This change set adds support for the C preprocessor to SLANG.
Two new methods are supported: Object>>cppDirective Object>>cppIfDef:inSmalltalk:comment:ifTrue:ifFalse:
Examples:
The Smalltalk expression: self cppDirective: 'ifdef HAS_FOO'. self doFooStuff. self cppDirective: 'endif'. is translated to: # ifdef HAS_FOO doFooStuff(); # endif
The Smalltalk expression: self cppIfDef: 'HAVE_FOO' inSmalltalk: [if self haveFoo] comment: 'some platforms do not support foo properly' ifTrue: [self doThingsThatWorkIfFooIsPresent] ifFalse: [self doSomethingElseInstead]. is translated to: # ifdef SOMETHING // system supports foo doThingsThatWorkIfFooIsPresent(); # else doSomethingElseInstead(); # endif // SOMETHING
Here is an example of a method that uses the C preprocessor:
primitiveUnsetEnv "Unset an environment variable." | cStringPtr keyString | self export: true. self var: 'cStringPtr' declareC: 'char *cStringPtr'. keyString _ interpreterProxy stackObjectValue: 0. cStringPtr _ self transientCStringFromString: keyString. self cppIfDef: 'HAVE_UNSETENV' inSmalltalk: [true] comment: 'unsetenv() is not portable' ifTrue: [self unsetenv: cStringPtr] ifFalse: [interpreterProxy primitiveFail]. interpreterProxy pop: 1
The generated C code in the plugin is:
EXPORT(int) primitiveUnsetEnv(void) { int keyString; char *cStringPtr;
keyString = interpreterProxy->stackObjectValue(0); cStringPtr = transientCStringFromString(keyString); # ifdef HAVE_UNSETENV // unsetenv() is not portable unsetenv(cStringPtr); # else interpreterProxy->primitiveFail(); # endif // HAVE_UNSETENV
interpreterProxy->pop(1); }
Dave
vm-dev@lists.squeakfoundation.org