@@ -1,28 +1,23 @@ | |||
# Dictionary | |||
List of words defined in Inner core (B390), Core words (B420) | |||
and Extra words (B150). | |||
List of words defined in arch-specific boot code (for example, | |||
B280 for Z80), Core words (B350) and Extra words (B150). | |||
# Glossary | |||
Stack notation: "<stack before> -- <stack after>". Rightmost is | |||
top of stack (TOS). For example, in "a b -- c d", b is TOS | |||
before, d is TOS after. "R:" means that the Return Stack is | |||
modified. "I:" prefix means "IMMEDIATE", that is, that this | |||
stack transformation is made at compile time. | |||
modified. | |||
Word references (wordref): When we say we have a "word | |||
reference", it's a pointer to a word's *code link*. For example, | |||
the address that "' DUP" puts on the stack is a wordref, that | |||
is, a reference to the code link of the word DUP. | |||
reference", it's a pointer to a word's *entry type field*. For | |||
example, the address that "' DUP" puts on the stack is a | |||
wordref, that is, a reference to the entry type field of the | |||
word DUP. See impl.txt for details. | |||
PF: Parameter field. The area following the code link of a | |||
word. For example, "' H@ 1+" points to the PF of the word H@. | |||
Atom: A word of the type compiledWord contains, in its PF, a | |||
list of what we call "atoms". Those atoms are most of the time | |||
word references, but they can also be references to NUMBER and | |||
LIT. | |||
PF: Parameter field. The area following the entry type field of | |||
a word. For example, "' H@ 1+" points to the PF of the word H@. | |||
Words between "()" are "support words" that aren't really meant | |||
to be used directly, but as part of another word. | |||
@@ -59,21 +54,22 @@ $ - Initialize | |||
ALLOT n -- Move HERE by n bytes | |||
C, b -- Write byte b in HERE and advance it. | |||
FIND w -- a f Like '?, but for w. | |||
EMPTY -- Rewind HERE and CURRENT where they were at | |||
EMPTY -- Rewind HERE and CURRENT where they were at | |||
system initialization. | |||
FORGET x -- Rewind the dictionary (both CURRENT and HERE) | |||
FORGET x -- Rewind the dictionary (both CURRENT and HERE) | |||
up to x's previous entry. | |||
PREV a -- a Return a wordref's previous entry. | |||
WORD( a -- a Get wordref's beginning addr. | |||
PREV a -- a Return a wordref's previous entry. | |||
WORD( a -- a Get wordref's beginning addr. | |||
# Defining words | |||
: x ... -- Define a new word | |||
; R:I -- Exit a colon definition | |||
CREATE x -- Create cell named x. Doesn't allocate a PF. | |||
[COMPILE] x -- Compile word x and write it to HERE. | |||
[COMPILE] x -- *I* Compile word x and write it to HERE. | |||
IMMEDIATE words are *not* executed. | |||
COMPILE x -- Meta compiles. See B6. | |||
COMPILE x -- *I* Meta compiles: write wordrefs that will | |||
compile x when executed. | |||
CONSTANT x n -- Creates cell x that when called pushes its | |||
value. | |||
DOES> -- See primer.txt | |||
@@ -105,7 +101,7 @@ have to consume it to avoid PSP leak. | |||
following bytes. Can be negative. | |||
(?br) f -- Branch if f is false. | |||
( -- *I* Comment. Ignore input until ")" is read. | |||
[ -- Begin interpretative mode. In a definition, | |||
[ -- *I* Begin interpretative mode. In a definition, | |||
execute words instead of compiling them. | |||
] -- End interpretative mode. | |||
ABORT -- Resets PS and RS and returns to interpreter. | |||
@@ -113,10 +109,9 @@ ABORT" x" -- *I* Compiles a ." followed by a ABORT. | |||
ERR a -- Prints a and ABORT. Defined early and used by | |||
drivers. | |||
EXECUTE a -- Execute wordref at addr a | |||
INTERPRET -- Get a line from stdin, compile it in tmp memory, | |||
then execute the compiled contents. | |||
INTERPRET -- Main interpret loop. | |||
LEAVE -- In a DO..LOOP, exit at the next LOOP call. | |||
QUIT -- Return to interpreter prompt immediately | |||
QUIT -- Return to interpreter prompt immediately. | |||
# Parameter Stack | |||
@@ -226,11 +221,10 @@ NOT f -- f Push the logical opposite of f | |||
# Strings | |||
LIT -- Write a LIT entry. You're expected to write | |||
actual string to HERE right afterwards. | |||
LIT< x -- Read following word and write to HERE as a | |||
string literal. | |||
S= a1 a2 -- f Returns whether string a1 == a2. | |||
LIT< x -- Read following word and write to HERE as a | |||
string literal. | |||
LIT" x" -- Same as LIT<, but can contain whitespaces. | |||
S= a1 a2 -- f Returns whether string a1 == a2. | |||
# I/O | |||
@@ -14,7 +14,7 @@ it. As a general rule, we go like this: | |||
# Executing a word | |||
At it's core, executing a word is pushing the wordref on PS and | |||
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 | |||
@@ -30,10 +30,16 @@ 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. | |||
# Stack management | |||
In all supported arches, The Parameter Stack and Return Stack | |||
tops are trackes by a registered assigned to this purpose. For | |||
tops are tracked by a registered assigned to this purpose. For | |||
example, in z80, it's SP and IX that do that. The value in those | |||
registers are referred to as PS Pointer (PSP) and RS Pointer | |||
(RSP). | |||
@@ -65,7 +71,7 @@ A dictionary entry has this structure: | |||
- Parameter field (PF) | |||
The prev offset is the number of bytes between the prev field | |||
and the previous word's code pointer. | |||
and the previous word's entry type. | |||
The size + flag indicate the size of the name field, with the | |||
7th bit being the IMMEDIATE flag. | |||
@@ -83,15 +89,15 @@ number is the word type and the word's behavior depends on it. | |||
0: native. This words PFA contains native binary code and is | |||
jumped to directly. | |||
1: compiled. This word's PFA contains an atom list and its | |||
1: compiled. This word's PFA contains a list of wordrefs and its | |||
execution is described in "Execution model" above. | |||
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. | |||
3: DOES>. This word is created by "DOES>" and is followed | |||
by a 2-byte value as well as the address where "DOES>" was | |||
compiled. At that address is an atom list exactly like in a | |||
by a 2-bytes value as well as the address where "DOES>" was | |||
compiled. At that address is an wordref list exactly like in a | |||
compiled word. Upon execution, after having pushed its cell | |||
addr to PSP, it executes its reference exactly like a | |||
compiled word. | |||
@@ -131,10 +137,6 @@ CURRENT points to the last dict entry. | |||
HERE points to current write offset. | |||
IP is the Interpreter Pointer | |||
PARSEPTR holds routine address called on (parse) | |||
C<* holds routine address called on C<. If the C<* override | |||
at 0x08 is nonzero, this routine is called instead. | |||
@@ -153,10 +155,10 @@ CRLF). | |||
BLK* see B416. | |||
FUTURE USES section is unused for now. | |||
DRIVERS section is reserved for recipe-specific drivers. | |||
FUTURE USES section is unused for now. | |||
# Initialization sequence | |||
(this describes the z80 boot sequence, but other arches have | |||
@@ -2,7 +2,7 @@ | |||
Collapse OS is a minimal operating system created to preserve | |||
the ability to program microcontrollers through civilizational | |||
collapse. Its author expect the collapse of the global supply | |||
collapse. Its author expects the collapse of the global supply | |||
chain means the loss of our computer production capability. Many | |||
microcontrollers require a computer to program them. | |||
@@ -18,7 +18,7 @@ the top of the stack, then prints the result. | |||
42 0x8000 C! 0x8000 C@ . | |||
This writes the byte "42" at address 0x8000, and then reads | |||
back that bytes from the same address and print it. | |||
back that byte from the same address and print it. | |||
# Interpreter loop | |||
@@ -37,7 +37,7 @@ Forth's main interpeter loop is very simple: | |||
A word is a string of non-whitepace characters. We consider that | |||
we're finished reading a word when we encounter a whitespace | |||
after having read at least one non-whitespace character | |||
after having read at least one non-whitespace character. | |||
# Character encoding | |||
@@ -244,7 +244,7 @@ compilation. | |||
Words like "IF", "DO", ";" are all regular Forth words, but | |||
their "power" come from the fact that they're immediate. | |||
Starting Forth by Leo Brodie explain all of this in details. | |||
Starting Forth by Leo Brodie explains all of this in detail. | |||
Read this if you can. If you can't, well, let this sink in for | |||
a while, browse the dictionary (dict.txt) and try to understand | |||
why this or that word is immediate. Good luck! |