albert@spenarnc.xs4all.nl wrote:
Lispification of Forth means that all parts of Forth are dynamically
allocated. This means that all parts can be changed independantly,
headers, names high and low level code, without affecting the whole.
Once this is accomplished you want to expand the header with a source field.
This contains a heavily commented source of this word.
Now you can edit the source, and compile it to replace the code,
lispy and risky.
Of course you cannot lengthen any data item without dynamic
allocation.
This leans heavily on the circular allocation
wordlist facility. Any free space can be configured as a heap.
Also this wordset has SIZE, such that a single address determines
a string.
You need sufficient heap space, reserve a 1 Gbyte file for this.
(However you could easily expand it later.)
Use memmap() to map this in a fixed location in Forth, not
conflicting with the memory map. Now this space can be
configured for a heap. For each step you must close
and consolidate those heap file. Then you can continue
where you left off, for next steps.
You have rather specific idea here. Note however, that for
Lisp style redefinition of words (functions) all you need
is extra indirection say via dictionary (as mentioned in
another post). So Forth word needs to access other words
via dictionary entry or some other fixed-address intermediate
thing. Of course, this gives behaviour incompatible with
traditional Forth.
Speaking about Lispification, Lisp does not allow you to
change name of a symbol. All you can do is to change
maeaning of symbol, that is change variable/function
that you obtain by accessing the symbol.
Also, dynamic allocation can be coupled with manual dealocation.
But if you want to go in Lisp direction, then it is preferable
to have garbage collection. Practically garbage collection
means that you need things like headers before various
objects to identify things to garbage collector. Usual
approach uses tagged integers (that is one or more bit in an
integer serves as tag to distinguish it from pointers).
There may be other tagged things. This means that usual
expectations of Forth programs are violated.
Anyway, real system combining features of Lisp and Forth
works as follows: dictionary is a fixed size hash table
at fixed location. Each position in the table points
to list of possible meanings, that is list of pairs
(word, meaning). Dictionary lookup works as follows:
string correspnding to a word is hashed giving position
in the table, then there is linear search trough list
of pairs looking for matching word. If matching word is
found lookup gives corresponding meaning. Meaning may be
a function which can be executed. Or a special object
representing variable. At given time a word has single
meaning, but it can be removed or changed.
As in Forth a function takes arguments from data stack
and puts results on the data stack, function takes as many
arguments as it wants and produces as many results as
iut wishes. A lot of little details is different than
in Forth, let me just say that return stack is entirely
managed by the implementation. There is garbage collector
which in principle can collect almost anything: words,
variables, functions, various pieces of data. In practice
there are system objects especially functions that are
allocated at fixed addresses and not subject to garbage
collection. Garbage collector itself is a system
function so will be never garbage collected. However
it seems that only dictionary is fundamental, the
rest is mostly for efficiency: on x86_64 system objects
are reachable via 32-bit addresses and are at fixed
locations which allows more efficient function calls.
User objects are moved around in memory needing extra
indirection and full 64-bit addreses.
Named functions are accessed via variable objects, calls
go via corresponding object, re-definition changes
pointer to actual procedure, so after redefiniton calls
end up execution new code.
To summarize: if you really want Lisp features, you are likely
to get rater different system than Forth.
BTW: I am not sure what 1 GB is supposed to mean? Do you need
that much to rebuild ciforth with your changes? FYI, the system
I outlined above is extremaly bloated by Forth standards, but
runs happily in few MB. Recompilation needs more memory, but
currently main "memory eater" is C compilation of few support
files.
-- Waldek Hebisch