[View]  [Edit]  [Lock]  [References]  [Attachments]  [History]  [Home]  [Changes]  [Search]  [Help] 

[scripting] Primitives

We do NOT need primitives in S8, but if you are still using primitives in your code, it would be nice to connect your lowlevel primitive code (code in native language code, e.g. javascript or lua code) to the ScriptParser.
The ScriptParser has a basic but extensible implementation for directives in general.
Primitives are considered a custom case of directive syntax in S8.

Basic primitive implementation

As an example we will implement here a directive tagged with "basic:" token. It will act as a simple primitive that will return a string embedded in the directive literal and will never fail.
An example of use:
    < basic: #hello >
We want this basic directive to force return of #hello literal, and never reach the point returning #ok

To register the support for basic: primitive we evaluate:
ScriptParser primitiveHandlers at: #basic: put: [:parser :context :type|
    | literal |
    literal := parser nextStringConstant: context.
    literal isNil ifTrue: [ literal := parser nextSymbolConstant: context. ].
    literal isNil
    ifTrue: [ parser expected: 'String constant' ]
    ifFalse: [ PrimitiveNode doing: [:ctx :node | node exitWith: (literal evaluateIn: ctx) ] ]

Note that...

  1. The handler returns a PrimitiveNode in case of success parsing the directive
  2. The primitive node will exit the method (see #exitWith:) at runtime
  3. A simulator will evaluate the primitive as a single step of execution
  4. in case of a primitive failure, it is good to do nothing and implement a message accessing the failure as #primitiveFailed