Lesson 14: Extending the Language

Toka provides a few tools that allow you to extend the language in new directions. The core of this is compiler macros, special words which are (under normal circumstances) always invoked.

Consider a fairly simple task, such as displaying a string. We know that this can be done by using type, and that parse can be used to create a string. A simple first try would be something like:

  [ char: " parse type ] is ."

Trying this at the interpreter works just fine:

  ." Hello, World"

But inside a definition, we run into a problem:

  [ ." Hello, World" ] is foo
  E0: 'Hello,' is not a word or a number.
  E0: 'World"' is not a word or a number.

To make this work inside a definition, we need to do a few things:

  • Parse the string at compile time
  • Compile in a reference to the string
  • Compile a call to type into the quote

To begin, we should be using is-macro to make this into a compiler macro. As a macro, it will also run in the interpreter, so we need to make it aware of the compiler state. This is provided by the compiler variable. So an initial expansion:

  [ char: " parse 
    compiler @ [ ( for compile time ) ] [ type ] ifTrueFalse 
  ] is-macro ."

A simplification is now in order. The first two challenges (parsing the string and compiling a reference to it) are already handled by the " word. We can reuse this and save some trouble:

  [ ` " invoke
    compiler @ [ ( for compile time ) ] [ type ] ifTrueFalse 
  ] is-macro ."

` returns a quote containing the requested function, in this case ". We can then invoke the quote. This is a fundamental aspect of extending the langauge.

To compile a call to a quote, Toka provides another word, compile. We can use this as follows:

  [ ` " invoke
    compiler @ [ ` type compile ] [ type ] ifTrueFalse 
  ] is-macro ."

And now we are done. Use of `, invoke, and compile allows for a fair amount of flexibility in extending the language with new features. Learn to use them, and your ability to adapt Toka to your programs needs will multiply drastically.

These functions can also be used with normal quotes to create defining words. As a nominal example, this is a defining word that creates a function that always returns a specific value. Basically a form of constant:

  [ >r ` [ invoke r> # ` ] invoke is ] is const

One final note. Considering the example above, many items have a form similar to this. Toka has an additional word +action that creates a new quote combining a specific action and data element. The word "const" above could be rewritten using it:

  [ [ ] +action ] is const

Or, with a slightly more complex example, try this:

  [ [ . ] +action ] is foo
  100 foo bar
  bar
changed September 16, 2007