Extending Smojo
Smojo is an extensible language, meaning you can (and are encouraged) to extend the language depending on the work at hand. For example, many of the important words in Smojo likeDO,
LOOP,
ELSE,
POSTPONEand all the multi-level conditional words have been defined as language extensions. The first step to extending Smojo is to understand the words
CREATE,
DOES>and
(CREATE)
Word | Action |
---|---|
CREATE |
Creates a new dictionary entry, with the name given at runtime. In other words, a name - XT binding is added to the dictionary.
|
DOES> |
Optionally assigns further functionality to the dictionary entry from CREATE. The functionality is ended by ; |
(CREATE) |
Similar to CREATEexcept that (CREATE)receives the name from the top of the stack as text. |
Using CREATE
We can create a wordTHREE, whose data section is initialized to 3:
create THREE 3 , ok THREE . com.terraweather.mini.XT@58a07808 ok THREE ? 3 okBe sure you understand this example thoroughly before proceeding. Note that:
CREATE
defined a new wordTHREE
on the dictionary; When it is run,THREE
puts its XT on the stack.- After
CREATE
defines the new word, the comma operator initializes its data section with a single element, whose value is 3.
The => Keyword
While many language have built-in "keywords" to do things, in Smojo, you can create your own. For example, consider the word=>below:
: => ( n -- ) CREATE , ;If you understand how
THREEworks, you should be able to understand
=>. It creates a new dictionary entry using
CREATEand initializes its data section using
,. In other languages, this would be known as a "variable". Some ways to use:
32 => HELLO ok HELLO ? 32 ok 41 HELLO ! ok HELLO ? 41 okIndeed, the example above is equivalent to another built-in word
VARIABLE, try using
VARIABLEin your own program.
Use DOES>
We can useDOES>to add functionalities to the words. For example, if we want the word
THREEto print the value out once it is called, we can modify it in the following way:
create three 3 , does> ? ; three 3 ok
Create Immediate Words
Similar to defining data sections, you can also mark the word being created immediate by using the wordIMMEDIATE
create aa immediate does> "Immediate?" . immediate? . ; ok aa Immediate? true okNote that
DOES>always puts the XT of the word being created onto the stack. Again, be sure you understand this example thoroughly before proceeding.
Quiz
Question 1
What is the difference between using:and using
CREATE?
A word declared using
CREATEwill push its XT to the stack as its first instruction.
Question 2
UseCREATEto write a word with a data section of multiple elements
create three 3 , 4 , 5 , does> ? ;
Question 3
Different from a variable as shown in the examples, a constant cannot be amended. Write a wordCONSTANTwhich declares a constant.
CONSTANTis also a built-in word, check your answer by using
SEE.
The decopilation of the built-in
CONSTANT:
see constant [0] CREATE [1] IMMEDIATE [2] , [3] DOES> [3.0] @ [3.1] COMPILATION? [3.2] CJump<4> [3.3] LITERALDefining
CONSTANTin the same way:
: constant create immediate , does> @ compilation? -> ` literal |. ;If you
see constantagain, the result should be the same.
Question 4
Write a word::for word redefinition such that the original definition is automatically saved in its data section.
: :: ( |name -- ) next-token dup xt-from-name swap (create) , ` does> ` drop \ drop the XT pushed automatically ; : hello "Hello" . cr ; :: hello "Bingoooo" . cr ; hello \ new definition => Bingoooo ' hello @ execute \ old definition => Hello