Frank Heckenbach wrote:
Peter N Lewis wrote:
In the Mac OS, we have a concept of a FourCharCode, which is essentially a UInt32 except that it often has values that are made up of four characters. In Mac OS compilers then, the UNSIGNEDLONG (Cardinal attribute( size = 32 ))is compatible as a special case with constant strings of four characters.
[...]
Changing FourCharCode = UInt32 is probably better since the concept behind it is as a fixed size low cost use, and it is essentially never used as a string as such.
I agree. It's probably the only way it can be used in `case' as well.
The problem then comes from the fact that you can't case the constants above to UInt32's, eg:
typeBoolean = UInt32('bool');
this doesn't work.
One possibility might be to extend BP's # character hack to work with quoted strings in reverse, so #'bool' would return an unsigned integer constant equal to ((((ord('b)*256)_+ord('o'))*256+ord('o'))*256+ord('l').
[...]
I'm certainly open to hear of any existing GPC solutions that we could use instead.
I thought of a macro encapsulating the code above.
{$define UInt32(s) ((((Ord (s[1]) * 256) + Ord (s[2])) * 256 + Ord (s[3])) * 256 + Ord (s[4]))}
I'm not sure if GPC supports it but Extended Pascal provides for using the substr required function in constant-expressions as long as none of the parameters are variable-access. In theory, a macro such as:
{$define UInt32(s) ((Ord (substr((s),1,1)) shl 24) or (Ord (substr((s),2,1)) shl 16) or (Ord (substr((s),3,1)) shl 8) or Ord (substr((s),4,1))}
should work for s as a constant-string-literal or as a constant-identifier declared as a string-literal (presuming, of course, the string has at least four characters).
However, when I tried the basic concept in a test program, I got a "internal compiler error: Bus error" result.
The test program was:
program FourCharCodeTest (input, output);
const ch1value = ord(substr('bool',1,1)); begin writeln('The value of ''b'' is: ', ch1value:1); end.
The command line used and the resulting output was:
[Gale-Paepers-Computer:~/programming/FourCharCodeTest] galepaep% gpc --automake -v -save-temps FourCharCodeTest.pas -o FourCharCodeTest Reading specs from /Developer/Pascal/gpc33d6/lib/gcc-lib/powerpc-apple-darwin/3.3/specs Configured with: ../gpc-3.3d6/configure --enable-languages=pascal,c --enable-threads=posix --prefix=/Developer/Pascal/gpc33d6 --target=powerpc-apple-darwin Thread model: posix gpc version 20030507, based on gcc-3.3 /Developer/Pascal/gpc33d6/lib/gcc-lib/powerpc-apple-darwin/3.3/gpcpp -D__BITS_BIG_ENDIAN__=1 -D__BYTES_BIG_ENDIAN__=1 -D__WORDS_BIG_ENDIAN__=1 -D__NEED_NO_ALIGNMENT__=1 -quiet -v -iprefix /usr/bin/../lib/gcc-lib/powerpc-apple-darwin/3.3/ -D__GNUC__=3 -D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=0 -D__DYNAMIC__ FourCharCodeTest.pas -fautomake -famtmpfile=/var/tmp//cc51gu9u.gpa FourCharCodeTest.i GNU Pascal Compiler PreProcessor version 20030507, based on gcc-3.3 (Darwin/PowerPC) /Developer/Pascal/gpc33d6/lib/gcc-lib/powerpc-apple-darwin/3.3/gpc1 FourCharCodeTest.i -fPIC -quiet -dumpbase FourCharCodeTest.pas -auxbase FourCharCodeTest -version -fautomake -famtmpfile=/var/tmp//cc51gu9u.gpa -o FourCharCodeTest.s GNU Pascal version is actually 20030507, based on gcc-3.3 GNU Pascal version 3.3 (powerpc-apple-darwin) compiled by GNU C version 3.3. GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096 FourCharCodeTest.pas:4: internal compiler error: Bus error Please submit a full bug report, with preprocessed source if appropriate. See URL:http://gcc.gnu.org/bugs.html for instructions.
Then you can do:
const c = 'abcd';
WriteLn (UInt32 (c));
Unfortunately, this doesn't work:
WriteLn (UInt32 ('abcd'));
because after macro expansion it will contain things like 'abcd'[1] which are syntactically invalid (in any Pascal dialect AFAIK).
If it actually worked, the substr function would work in both cases since the string parameter can be any string-type (or char-type) expression - e.g., a constant string-literal, a constant-identifier of string-type, etc.
I think for Mac OS X, a more typical useage for such a macro fix would be using the macro in the declaration of the constant instead of using the macro every place the constant identifier is used in the code, i.e., :
const c = UInt32 ('abcd');
The reason being that for interface declarations Apple added for PPC only useage, it was assumed that the FourCharCode type was the same base type as UInt32 so there a plenty of places where parameter types and record field types intended to take FourCharCode types are just declared as UInt32 types. Since there are quite a few FourCharCode constants declared, it would lessen the burden of applying the FourCharCode macro fix if the fix can be applied to the declaration of the constants instead of every where in the code the constants are used.
Gale Paeper gpaeper@empirenet.com