mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-23 12:58:06 +11:00
Improve impl's word execution documentation
Add an example, which I think helps a lot to grasp the idea. Also, improve comments in Z80 boot code.
This commit is contained in:
parent
038ca61ea5
commit
e8cc3040d1
11
blk.fs
11
blk.fs
@ -1130,16 +1130,17 @@ lblexec BSET L1 FSET ( B284 ) L2 FSET ( B286 )
|
||||
HL INCd, HL INCd, LDDE(HL), EXDEHL, ( does )
|
||||
THEN, ( continue to compiledWord )
|
||||
( ----- 289 )
|
||||
( compiled word
|
||||
( compiled word. HL points to its first wordref, which we'll
|
||||
execute now.
|
||||
1. Push current IP to RS
|
||||
2. Set new IP to the second atom of the list
|
||||
3. Execute the first atom of the list. )
|
||||
2. Set new IP to PFA+2
|
||||
3. Execute wordref )
|
||||
IX INCd, IX INCd,
|
||||
0 IX+ C LDIXYr,
|
||||
1 IX+ B LDIXYr,
|
||||
( While we inc, dereference into DE for execute call later. )
|
||||
LDDE(HL),
|
||||
HL INCd,
|
||||
LDDE(HL), ( DE is new wordref )
|
||||
HL INCd, ( HL is new PFA+2 )
|
||||
B H LDrr, C L LDrr, ( --> IP )
|
||||
JR, lblexec BWR ( execute-B287 )
|
||||
( ----- 290 )
|
||||
|
78
doc/impl.txt
78
doc/impl.txt
@ -12,29 +12,12 @@ it. As a general rule, we go like this:
|
||||
5. If yes, push that number to PS, goto 1
|
||||
6. Error: undefined word.
|
||||
|
||||
# Executing a word
|
||||
# What is a word?
|
||||
|
||||
At its core, executing a word is pushing the wordref on PS and
|
||||
calling EXECUTE. Then, we let the word do its things. Some
|
||||
words are special, but most of them are of the "compiled"
|
||||
type (regular nonnative word), and that's their execution that
|
||||
we describe here.
|
||||
|
||||
First of all, at all time during execution, the Interpreter
|
||||
Pointer (IP) points to the wordref we're executing next.
|
||||
|
||||
When we execute a compiled word, the first thing we do is push
|
||||
IP to the Return Stack (RS). Therefore, RS' top of stack will
|
||||
contain a wordref to execute next, after we EXIT.
|
||||
|
||||
At the end of every compiled word is an EXIT. This pops RS, sets
|
||||
IP to it, and continues.
|
||||
|
||||
A compiled word is simply a list of wordrefs, but not all those
|
||||
wordrefs are 2 bytes in length. Some wordrefs are special. For
|
||||
example, a reference to (n) will be followed by an extra 2 bytes
|
||||
number. It's the responsibility of the (n) word to advance IP
|
||||
by 2 extra bytes.
|
||||
A word is a place in memory having a particular structure. Its
|
||||
first byte is a "word type" byte (see below), followed by a
|
||||
structure that depends on the word type. This structure is
|
||||
generally refered to as the Parameter Field (PF).
|
||||
|
||||
# Stack management
|
||||
|
||||
@ -84,6 +67,10 @@ The entry type is simply a number corresponding to a type which
|
||||
will determine how the word will be executed. See "Word types"
|
||||
below.
|
||||
|
||||
The vast majority of the time, a dictionary entry refers to a
|
||||
word. However, sometimes, it refers to something else. A "hook
|
||||
word" (see bootstrap.txt) is such an example.
|
||||
|
||||
# Word types
|
||||
|
||||
There are 6 word types in Collapse OS. Whenever you have a
|
||||
@ -94,7 +81,7 @@ number is the word type and the word's behavior depends on it.
|
||||
jumped to directly.
|
||||
|
||||
1: compiled. This word's PFA contains a list of wordrefs and its
|
||||
execution is described in "Execution model" above.
|
||||
execution is described in "Executing a compiled word" below.
|
||||
|
||||
2: cell. This word is usually followed by a 2-byte value in its
|
||||
PFA. Upon execution, the address of the PFA is pushed to PS.
|
||||
@ -111,6 +98,51 @@ pushing it to PS, we execute it.
|
||||
|
||||
5: ialias. Same as alias, but with an added indirection.
|
||||
|
||||
# Executing a compiled word
|
||||
|
||||
At its core, executing a word is pushing the wordref on PS and
|
||||
calling EXECUTE. Then, we let the word do its things. Some
|
||||
words are special, but most of them are of the "compiled"
|
||||
type, and that's their execution that we describe here.
|
||||
|
||||
First of all, at all time during execution, the Interpreter
|
||||
Pointer (IP) points to the wordref we're executing next.
|
||||
|
||||
When we execute a compiled word, the first thing we do is push
|
||||
IP to the Return Stack (RS). Therefore, RS' top of stack will
|
||||
contain a wordref to execute next, after we EXIT.
|
||||
|
||||
At the end of every compiled word is an EXIT. This pops RS, sets
|
||||
IP to it, and continues.
|
||||
|
||||
A compiled word is simply a list of wordrefs, but not all those
|
||||
wordrefs are 2 bytes in length. Some wordrefs are special. For
|
||||
example, a reference to (n) will be followed by an extra 2 bytes
|
||||
number. It's the responsibility of the (n) word to advance IP
|
||||
by 2 extra bytes.
|
||||
|
||||
To be clear: It's not (n)'s word type that is special, it's a
|
||||
regular "native" word. It's the compilation of the (n) type,
|
||||
done in LITN, that is special. We manually compile a number
|
||||
constant at compilation time, which is what is expected in (n)'s
|
||||
implementation. Similar special things happen in (s), (br),
|
||||
(?br) and (loop).
|
||||
|
||||
For example, the word defined by ": FOO 42 EMIT ;" would have
|
||||
an 8 bytes PF: a 2b ref to (n), 2b with 0x002a, a 2b ref to EMIT
|
||||
and then a 2b ref to EXIT.
|
||||
|
||||
When executing this word, we first set IP to PF+2, then exec
|
||||
PF+0, that is, the (n) reference. (n), when executing, reads IP,
|
||||
pushes that value to PS, then advances IP by 2. This means that
|
||||
when we return to the "next" routine, IP points to PF+4, which
|
||||
next will execute. Before executing, IP is increased by 2, but
|
||||
it's the "not-increased" value (PF+4) that is executed, that is,
|
||||
EMIT. EMIT does its thing, doesn't touch IP, then returns to
|
||||
"next". We're still at PF+6, which then points to EXIT. EXIT
|
||||
pops RS into IP, which is the value that IP had before FOO was
|
||||
called. The "next" dance continues...
|
||||
|
||||
# System variables
|
||||
|
||||
There are some core variables in the core system that are
|
||||
|
Loading…
Reference in New Issue
Block a user