The simplest and most frequent example is to compute a literal during compilation. E.g., the following definition prints an array of strings, one string per line:
: .strings ( addr u -- ) \ gforth 2* cells bounds U+DO cr i 2@ type 2 cells +LOOP ;
With a simple-minded compiler like Gforth’s, this computes 2
cells
on every loop iteration. You can compute this value once and for
all at compile time and compile it into the definition like this:
: .strings ( addr u -- ) \ gforth 2* cells bounds U+DO cr i 2@ type [ 2 cells ] literal +LOOP ;
[
switches the text interpreter to interpret state (you will get
an ok
prompt if you type this example interactively and insert a
newline between [
and ]
), so it performs the
interpretation semantics of 2 cells
; this computes a number.
]
switches the text interpreter back into compile state. It then
performs Literal
’s compilation semantics, which are to compile
this number into the current word. You can decompile the word with
see .strings
to see the effect on the compiled code.
You can also optimize the 2* cells
into [ 2 cells ] literal
*
in this way.
[
( – ) core “left-bracket”
Enter interpretation state. Immediate word.
]
( – ) core “right-bracket”
Enter compilation state.
Literal
( compilation n – ; run-time – n ) core “Literal”
Compilation semantics: compile the run-time semantics.
Run-time Semantics: push n.
Interpretation semantics: undefined.
ALiteral
( compilation addr – ; run-time – addr ) gforth-0.2 “ALiteral”
Works like literal
, but (when used in cross-compiled
code) tells the cross-compiler that the literal is an address.
]L
( compilation: n – ; run-time: – n ) gforth-0.5 “]L”
equivalent to ] literal
There are also words for compiling other data types than single cells as literals:
2Literal
( compilation w1 w2 – ; run-time – w1 w2 ) double “two-literal”
Compile appropriate code such that, at run-time, w1 w2 are placed on the stack. Interpretation semantics are undefined.
FLiteral
( compilation r – ; run-time – r ) floating “f-literal”
Compile appropriate code such that, at run-time, r is placed on the (floating-point) stack. Interpretation semantics are undefined.
SLiteral
( Compilation c-addr1 u ; run-time – c-addr2 u ) string “SLiteral”
Compilation: compile the string specified by c-addr1, u into the current definition. Run-time: return c-addr2 u describing the address and length of the string.
You might be tempted to pass data from outside a colon definition to the
inside on the data stack. This does not work, because :
puhes a
colon-sys, making stuff below unaccessible. E.g., this does not work:
5 : foo literal ; \ error: "unstructured"
Instead, you have to pass the value in some other way, e.g., through a variable:
variable temp 5 temp ! : foo [ temp @ ] literal ;