Create and manage labels in metacompilation
published: 2 April 2021 / updated 2 April 2021
The labels
Labels are defined in assembler as the code unfolds. Here is a fragment of the code FlashForth source:
; EXIT -- Compile a return ; variable link .dw 0 EXIT_L: .db NFA|4,"exit",0 EXIT: m_pop_t0 pop t0 pop t0 ret fdw IFLUSH_L OPERATOR_L: .db NFA|8,"operator",0 OPERATOR: call DOCREATE fdw OPERATOR_AREA OPERATOR_AREA: .dw up0 .dw 0, ursize .dw ussize, utibsize
Here, each label is in red. Labels preceded by a colon are labels
not defined and created, example EXIT:
.
Labels, once defined, can be used as many times as needed. Example
call DOCREATE
.
Definition of labels in FORTH
Label definition code:
\ Coded labels without header in target : label ( -- ) forced >IN @ Xassembler definitions here-t constant \ create label in Xassembler vocabulary >IN ! ?resolves unforced ;
This definition is written to the file
meta.txt. The word label
is followed by the name of the label to create. This label is recorded in the vocabulary
Xassembler
. Example, for this code in assembler:
DOUSER: m_pop_zh pop zh pop zl rcall FETCHLIT add tosl, upl adc tosh, uph ret
Which is rewritten in FORTH assembler with a DOUSER
label:
label DOUSER m_pop_zh zh pop, zl pop, FETCHLIT rcall, tosl upl add, tosh uph adc, ret,
A label is a constant created in the Xassembler
vocabulary. This
constant contains the value of the dp-t
pointer in the target. This pointer
increments as the meta-compilation progresses:
The meta-compilation target is pointed to by ADR-T
. The pointer
dp-t
(Dictionnary Pointer in Target) is incremented each time
that code is assembled or compiled into the target.
The value of this pointer is retrieved by the word here-t
(HERE in Target).
Each label points to a relative address in the target. Running a label restores this relative address.
Use of labels
Once defined, any label can be used in FORTH or FORTH assembler code.
However, unlike pure assembly code, it is not possible to use a label before it is defined. Example:
label DOUSER ..... FETCHLIT rcall, ..... ret, label FETCHLIT ..... ret,
In our example, we try a subroutine call to FETCHLIT
before its definition in the Xassembler vocabulary.
This is one of the drawbacks of the FORTH language.
To be able to make a connection to FETCHLIT
, you must move the code:
label FETCHLIT ..... ret, label DOUSER ..... FETCHLIT rcall, ..... ret,
When rewriting the FlashForth assembly code, we will define a label for each CFA, example of assembly code:
fdw MPLUS_L MINUS_L: .db NFA|INLINE5|1, "-" MINUS: ld t0, Y+ ld t1, Y+ sub t0, tosl sbc t1, tosh movw tosl, t0 ret
And its rewrite in FORTH assembler:
label MINUS t0 Y+ ld, t1 Y+ ld, t0 tosl sub, t1 tosl sbc, tosl t0 movw, ret,
In this code:
- the label
MINUS
points to the CFA field of the definition of the word-
- the MINUS_L label in the original assembly code points to the NFA
of the word
-
. It is not necessary, for meta-compilation, to define this label, because the meta-compiler has mechanisms for managing dictionary links which automate word links in the target FORTH dictionary.
The NFA field of a FORTH definition is written, in the original FlashForth code, Under the form:
fdw MPLUS_L MINUS_L: .db NFA|INLINE5|1, "-"
In metacompilation, this hardware is useless, because simply replaced by this:
code -
And this is how -
is defined in the meta-compiled source code:
code - ( n1 n2 -- n1-n2) label MINUS t0 Y+ ld, t1 Y+ ld, t0 tosl sub, t1 tosl sbc, tosl t0 movw, ret, end-code
The explanations on these mechanisms are explained in the following article...