In Forth you can write code generting words using by words like
POSTPONE COMPILE, and LITERAL. Standardized locals don't fit quite
in. While (LOCAL) has the superficial feel of a metaprogramming word,
it defines a named local and the only way to compile a read from or a
write to such a local is EVALUATE (with all the pitfalls one has to
work around). And you have to generate a unique name for the local
and then pass it to EVALUATE as a string.
So how could a metaprogramming interface for locals look like?
local-noname ( -- local-id ) ( generated code run-time: x -- )
defines a nameless local that is later referred to by the local-id
at run-time allocates space for the local an initializes it
flocal-noname ( -- local-id ) ( generated code run-time: r -- )
... possibly more words for defining locals
read-local ( local-id -- ) ( generated code run-time: -- x )
at run-time, push the value of the local on the stack
fread-local ( local-id -- ) ( generated code run-time: -- r )
...
write-local ( local-id -- ) ( generated code run-time: x -- )
at run-time, change the value of the local to x
fwrite-local ( local-id -- ) ( generated code run-time: r -- )
...
or maybe have READ-LOCAL work for all kinds of local
You may wonder what the use of such words is. Here are two possible
scenarios:
1) You may want to deal with values in metaprogramming without these
values getting in the way on the data stack or the return stack (the
latter requires a system that can mix return stack and locals
accesses). E.g., many object-oriented packages have a THIS or SELF
value, with implicit usage of THIS in field (aka instance variable)
words. One can put the THIS value in a local, then store the local-id
somewhere, and use it when compiling the field references. This is of
course only a good solution if your THIS is only valid within a
definition (as in most OO packages, but not Bernd Paysan's).
2) When using Forth as intermediate language for compiling a different
source language, you may want to map the source language's locals into
Forth locals, but possibly not using the same names (because of
different scoping rules, or to avoid name collisions). So you would
generate a Forth local for every source local, store the local-ids of
the Forth locals in the symbol table, and compile source local
references into the appropriate READ-LOCAL or WRITE-LOCAL calls.
- anton
--
M. Anton Ertl
http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs:
http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard:
http://www.forth200x.org/forth200x.html
EuroForth 2021:
https://euro.theforth.net/2021