mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-02 10:20:55 +11:00
Compare commits
No commits in common. "a3c3a2f44a33710ad0b6d49f278d9723a9e5cbab" and "d3dbeb450fe36ee754ff0555bc155c8aa8031cc7" have entirely different histories.
a3c3a2f44a
...
d3dbeb450f
16
blk/003
16
blk/003
@ -2,15 +2,15 @@ Collapse OS usage guide
|
|||||||
|
|
||||||
This document is not meant to be an introduction to Forth, but
|
This document is not meant to be an introduction to Forth, but
|
||||||
to instruct the user about the peculiarities of this Forth
|
to instruct the user about the peculiarities of this Forth
|
||||||
implementation. The recommended introductory book is Starting
|
implemenation. Be sure to refer to dictionary for a word
|
||||||
Forth by Leo Brodie. This is the reference that was used to
|
reference.
|
||||||
build this implementation and many of the conventions described
|
|
||||||
in this book are followed in Collapse OS. Be sure to refer to
|
|
||||||
the dictionary (B30) for a word reference.
|
|
||||||
|
|
||||||
Contents
|
Contents
|
||||||
|
|
||||||
4 Number literals 6 Compilation vs meta-comp.
|
4 DOES> 6 Compilation vs meta-comp.
|
||||||
8 Interpreter I/O 11 Signed-ness
|
8 I/O 14 Addressed devices
|
||||||
14 Addressed devices 17 DOES>
|
18 Signed-ness
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
23
blk/004
23
blk/004
@ -1,11 +1,16 @@
|
|||||||
Number literals
|
DOES>
|
||||||
|
|
||||||
Traditional Forth often use HEX/DEC switches to go from decimal
|
Used inside a colon definition that itself uses CREATE, DOES>
|
||||||
to hexadecimal parsing. Collapse OS parses literals in a way
|
transforms that newly created word into a "does cell", that is,
|
||||||
that is closer to C.
|
a regular cell ( when called, puts the cell's addr on PS), but
|
||||||
|
right after that, it executes words that appear after the
|
||||||
|
DOES>.
|
||||||
|
|
||||||
|
"does cells" always allocate 4 bytes (2 for the cell, 2 for the
|
||||||
|
DOES> link) and there is no need for ALLOT in colon definition.
|
||||||
|
|
||||||
|
At compile time, colon definition stops processing words when
|
||||||
|
reaching the DOES>.
|
||||||
|
|
||||||
|
Example: ": CONSTANT CREATE HERE @ ! DOES> @ ;"
|
||||||
|
|
||||||
Straight numbers are decimals, numbers starting with "0x"
|
|
||||||
are hexadecimals (example "0x12ef"), "0b" prefixes indicate
|
|
||||||
binary (example "0b1010"), char literals are single characters
|
|
||||||
surrounded by ' (example 'X'). Char literals can't be used for
|
|
||||||
whitespaces.
|
|
||||||
|
26
blk/008
26
blk/008
@ -1,16 +1,16 @@
|
|||||||
Interpreter I/O
|
I/O
|
||||||
|
|
||||||
The INTERPRET loop, the heart of Collapse OS, feeds itself
|
A little word about inputs. There are two kind of inputs:
|
||||||
from the C< word, which yields a character every time it is
|
direct and buffered. As a general rule, we read line in a
|
||||||
called. If no character is available to interpret, it blocks.
|
buffer, then feed words in it to the interpreter. That's what
|
||||||
|
"WORD" does. If it's at the End Of Line, it blocks and wait
|
||||||
|
until another line is entered.
|
||||||
|
|
||||||
During normal operations, C< is simply a buffered layer over
|
KEY input, however, is direct. Regardless of the input buffer's
|
||||||
KEY, which has the same behavior (but unbuffered). Before
|
state, KEY will return the next typed key.
|
||||||
yielding any character, the C< routine fetches a whole line
|
|
||||||
from KEY, puts it in a buffer, then yields the buffered line,
|
|
||||||
one character at once.
|
|
||||||
|
|
||||||
Both C< and KEY can be overridden by setting an alternate
|
PARSING AND BOOTSTRAP: Parsing number literal is a very "core"
|
||||||
routine at the proper RAM offset (see B80). For example, C<
|
activity of Forth, and therefore generally seen as having to be
|
||||||
overrides are used during LOAD so that input comes from
|
implemented in native code. However, Collapse OS' Forth
|
||||||
disk blocks instead of keyboard. (cont.)
|
supports many kinds of literals: decimal, hex, char, binary.
|
||||||
|
This incurs a significant complexity penalty. (cont.)
|
||||||
|
20
blk/009
20
blk/009
@ -1,6 +1,16 @@
|
|||||||
KEY overrides can be used to, for example, temporarily give
|
(cont.) What if we could implement those parsing routines in
|
||||||
prompt control to a RS-232 device instead of the keyboard.
|
Forth? "But it's a core routine!" you say. Yes, but here's the
|
||||||
|
deal: at its native core, only decimal parsing is supported. It
|
||||||
|
lives in the "(parsed)" word. The interpreter's main loop is
|
||||||
|
initially set to simply call that word.
|
||||||
|
|
||||||
|
However, in core.fs, "(parsex)", "(parsec)" and "(parseb)" are
|
||||||
|
implemented, in Forth, then "(parse)", which goes through them
|
||||||
|
all is defined. Then, "(parsef)", which is the variable in
|
||||||
|
which the interpreter's word pointer is set, is updated to that
|
||||||
|
new "(parse)" word.
|
||||||
|
|
||||||
|
This way, we have a full-featured (and extensible) parsing with
|
||||||
|
a tiny native core.
|
||||||
|
|
||||||
|
|
||||||
Interpreter output is unbuffered and only has EMIT. This
|
|
||||||
word can also be overriden, mostly as a companion to the
|
|
||||||
raison d'etre of your KEY override.
|
|
||||||
|
16
blk/017
16
blk/017
@ -1,16 +0,0 @@
|
|||||||
DOES>
|
|
||||||
|
|
||||||
Used inside a colon definition that itself uses CREATE, DOES>
|
|
||||||
transforms that newly created word into a "does cell", that is,
|
|
||||||
a regular cell ( when called, puts the cell's addr on PS), but
|
|
||||||
right after that, it executes words that appear after the
|
|
||||||
DOES>.
|
|
||||||
|
|
||||||
"does cells" always allocate 4 bytes (2 for the cell, 2 for the
|
|
||||||
DOES> link) and there is no need for ALLOT in colon definition.
|
|
||||||
|
|
||||||
At compile time, colon definition stops processing words when
|
|
||||||
reaching the DOES>.
|
|
||||||
|
|
||||||
Example: ": CONSTANT CREATE HERE @ ! DOES> @ ;"
|
|
||||||
|
|
12
blk/031
12
blk/031
@ -7,10 +7,10 @@ modified. "I:" prefix means "IMMEDIATE", that is, that this
|
|||||||
stack transformation is made at compile time.
|
stack transformation is made at compile time.
|
||||||
|
|
||||||
Word references (wordref): When we say we have a "word
|
Word references (wordref): When we say we have a "word
|
||||||
reference", it's a pointer to a word's *code link*. For
|
reference", it's a pointer to a words *code link*. For example,
|
||||||
example, the address that "' DUP" is a wordref, that is, a
|
the label "PLUS:" in this unit is a word reference. Why not
|
||||||
reference to the code link of the word DUP.
|
refer to the beginning of the word struct? Because we actually
|
||||||
|
seldom refer to the name and prev link, except during
|
||||||
PF: Parameter field. The area following the code link of a
|
compilation, so defining "word reference" this way makes the
|
||||||
word. For example, "' H@ 1+" points to the PF of the word H@.
|
code easier to understand.
|
||||||
(cont.)
|
(cont.)
|
||||||
|
1
blk/032
1
blk/032
@ -1,3 +1,4 @@
|
|||||||
|
(cont.)
|
||||||
Atom: A word of the type compiledWord contains, in its PF, a
|
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
|
list of what we call "atoms". Those atoms are most of the time
|
||||||
word references, but they can also be references to NUMBER and
|
word references, but they can also be references to NUMBER and
|
||||||
|
6
blk/037
6
blk/037
@ -10,7 +10,7 @@ Entry management
|
|||||||
, n -- Write n in HERE and advance it.
|
, n -- Write n in HERE and advance it.
|
||||||
ALLOT n -- Move HERE by n bytes
|
ALLOT n -- Move HERE by n bytes
|
||||||
C, b -- Write byte b in HERE and advance it.
|
C, b -- Write byte b in HERE and advance it.
|
||||||
|
DELW a -- Delete wordref at a. If it shadows another
|
||||||
|
definition, that definition is unshadowed.
|
||||||
EMPTY -- Rewind HERE and CURRENT where they were at
|
EMPTY -- Rewind HERE and CURRENT where they were at
|
||||||
system initialization.
|
system initialization. (cont.)
|
||||||
|
|
||||||
(cont.)
|
|
||||||
|
2
blk/040
2
blk/040
@ -8,7 +8,7 @@ CREATE x -- Create cell named x. Doesn't allocate a PF.
|
|||||||
COMPILE x -- Meta compiles. See B6.
|
COMPILE x -- Meta compiles. See B6.
|
||||||
CONSTANT x n -- Creates cell x that when called pushes its
|
CONSTANT x n -- Creates cell x that when called pushes its
|
||||||
value.
|
value.
|
||||||
DOES> -- See B17.
|
DOES> -- See B4.
|
||||||
IMMED? a -- f Checks whether wordref at a is immediate.
|
IMMED? a -- f Checks whether wordref at a is immediate.
|
||||||
IMMEDIATE -- Flag the latest defined word as immediate.
|
IMMEDIATE -- Flag the latest defined word as immediate.
|
||||||
LITA n -- Write address n as a literal.
|
LITA n -- Write address n as a literal.
|
||||||
|
16
blk/129
16
blk/129
@ -1,16 +0,0 @@
|
|||||||
( Note that the last word is always skipped because it's not
|
|
||||||
possible to reliably detect its end. If you need that last
|
|
||||||
word, define a dummy word before calling RLDICT.
|
|
||||||
|
|
||||||
We first start by copying the affected area to H@+4. This is
|
|
||||||
where the relinking will take place.
|
|
||||||
|
|
||||||
Then we iterate the new dict from the top, keeping track of
|
|
||||||
wr, the current wordref and we, wr's end offset.
|
|
||||||
|
|
||||||
Initially, we get our wr and we, withH@ and CURRENT, which we
|
|
||||||
offset by u+4. +4 before, remember, we're using 4 bytes
|
|
||||||
as variable space.
|
|
||||||
|
|
||||||
At each iteration, we becomes wr-header and wr is fetched from
|
|
||||||
PREV field. )
|
|
32
blk/130
32
blk/130
@ -1,16 +1,16 @@
|
|||||||
: RLDICT ( target offset -- )
|
( Note that the last word is always skipped because it's not
|
||||||
H@ 2+ ! H@ ! ( H@+2 == offset, H@ == target )
|
possible to reliably detect its end. If you need that last
|
||||||
H@ @ WORD( DUP H@ -^ ( src u )
|
word, define a dummy word before calling RLDICT.
|
||||||
DUP ROT SWAP H@ 4 + ( u src u dst )
|
|
||||||
SWAP MOVE ( u )
|
We first start by copying the affected area to H@+4. This is
|
||||||
4 + DUP CURRENT @ WORD( + ( u we )
|
where the relinking will take place.
|
||||||
DUP .X CRLF
|
|
||||||
SWAP CURRENT @ PREV + DUP .X CRLF ( we wr )
|
Then we iterate the new dict from the top, keeping track of
|
||||||
BEGIN ( we wr )
|
wr, the current wordref and we, wr's end offset.
|
||||||
DUP ROT ( wr wr we )
|
|
||||||
H@ @ H@ 2+ @ ( wr wr we ol o )
|
Initially, we get our wr and we, withH@ and CURRENT, which we
|
||||||
2SWAP RLWORD ( wr )
|
offset by u+4. +4 before, remember, we're using 4 bytes
|
||||||
DUP PREV SWAP ( wr oldwr )
|
as variable space.
|
||||||
WORD( SWAP ( we wr )
|
|
||||||
DUP 4 - H@ <= ( are we finished? )
|
At each iteration, we becomes wr-header and wr is fetched from
|
||||||
UNTIL H@ 4 + .X CRLF ;
|
PREV field. )
|
||||||
|
25
blk/131
25
blk/131
@ -1,9 +1,16 @@
|
|||||||
( Relink a regular Forth full interpreter. )
|
: RLDICT ( target offset -- )
|
||||||
: RLCORE
|
H@ 2+ ! H@ ! ( H@+2 == offset, H@ == target )
|
||||||
LIT< H@ (find) DROP ( target )
|
H@ @ WORD( DUP H@ -^ ( src u )
|
||||||
DUP 3 - @ ( t prevoff )
|
DUP ROT SWAP H@ 4 + ( u src u dst )
|
||||||
( subtract H@ name length )
|
SWAP MOVE ( u )
|
||||||
2- ( t o )
|
4 + DUP CURRENT @ WORD( + ( u we )
|
||||||
RLDICT
|
DUP .X CRLF
|
||||||
;
|
SWAP CURRENT @ PREV + DUP .X CRLF ( we wr )
|
||||||
|
BEGIN ( we wr )
|
||||||
|
DUP ROT ( wr wr we )
|
||||||
|
H@ @ H@ 2+ @ ( wr wr we ol o )
|
||||||
|
2SWAP RLWORD ( wr )
|
||||||
|
DUP PREV SWAP ( wr oldwr )
|
||||||
|
WORD( SWAP ( we wr )
|
||||||
|
DUP 4 - H@ <= ( are we finished? )
|
||||||
|
UNTIL H@ 4 + .X CRLF ;
|
||||||
|
9
blk/132
Normal file
9
blk/132
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
( Relink a regular Forth full interpreter. )
|
||||||
|
: RLCORE
|
||||||
|
LIT< H@ (find) DROP ( target )
|
||||||
|
DUP 3 - @ ( t prevoff )
|
||||||
|
( subtract H@ name length )
|
||||||
|
2- ( t o )
|
||||||
|
RLDICT
|
||||||
|
;
|
||||||
|
|
1
blk/434
1
blk/434
@ -6,4 +6,5 @@
|
|||||||
LOOP
|
LOOP
|
||||||
2DROP
|
2DROP
|
||||||
;
|
;
|
||||||
|
: DELW 1- 0 SWAP C! ;
|
||||||
: PREV 3 - DUP @ - ;
|
: PREV 3 - DUP @ - ;
|
||||||
|
BIN
emul/forth.bin
BIN
emul/forth.bin
Binary file not shown.
Loading…
Reference in New Issue
Block a user