6.16.1 Literals

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 0.7, this computes 2 cells on every loop iteration. You can compute this value 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.25

You can also optimize the 2* cells into [ 2 cells ] literal * in this way.26

[ ( ) core “left-bracket”

Enter interpretation state. Immediate word.

] ( ) core “right-bracket”

Enter compilation state.

Literal ( compilation n – ; run-time – n  ) core

Compilation semantics: ( n – ) compile the run-time semantics.
Run-time Semantics: ( – n ).
Interpretation semantics: not defined in the standard.

lit, ( x –  ) gforth-1.0 “lit-comma”

This is a non-immediate variant of literal
Execution semantics: Compile the following semantis:
Compiled semantics: ( – x ).

ALiteral ( compilation addr – ; run-time – addr  ) gforth-0.2

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 “right-bracket-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”

Compilation semantics: ( w1 w2 – ) compile the run-time semantics.
Run-time Semantics: ( – w1 w2 ).
Interpretation semantics: not defined in the standard.

doc-2lit,

FLiteral ( compilation r – ; run-time – r  ) floating “f-literal”

Compilation semantics: ( r – ) compile the run-time semantics.
Run-time Semantics: ( – r ).
Interpretation semantics: not defined in the standard.

flit, ( r –  ) gforth-1.0 “flit-comma”

This is a non-immediate variant of fliteral
Execution semantics: Compile the following semantis:
Compiled semantics: ( – r ).

SLiteral ( Compilation c-addr1 u – ; run-time – c-addr2 u  ) string

Compilation semantics: ( c-addr1 u – ) Copy the string described by c-addr1 u to c-addr2 u and compile the run-time semantics.
Run-time Semantics: ( – c-addr2 u ).
Interpretation semantics: not defined in the standard.

slit, ( c-addr1 u –  ) gforth-1.0 “slit-comma”

This is a non-immediate variant of sliteral
Execution semantics: Copy the string described by c-addr1 u to c-addr2 u and Compile the following semantis:
Compiled semantics: ( – c-addr2 u ).

You might be tempted to pass data from outside a colon definition to the inside on the data stack. This does not work, because : pushes 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 the return stack:

5 >r : foo [ r> ] literal ;

The interpretive use of the return stack is Gforth-specific; the use of a variable also works on other Forth systems:

variable temp
5 temp !
: foo [ temp @ ] literal ;

Footnotes

(25)

In Gforth 1.0, the compiler performs constant folding, and see of the original .strings will show the same effect.

(26)

In Gforth 1.0, 2 cells * is sufficient.