1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-26 20:48:08 +11:00

Compare commits

..

No commits in common. "a3c3a2f44a33710ad0b6d49f278d9723a9e5cbab" and "d3dbeb450fe36ee754ff0555bc155c8aa8031cc7" have entirely different histories.

17 changed files with 104 additions and 103 deletions

16
blk/003
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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> @ ;"

View File

12
blk/031
View File

@ -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.)

View File

@ -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

View File

@ -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.)

View File

@ -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.

View File

@ -1 +1 @@
123 131 LOADR 123 132 LOADR

16
blk/129
View File

@ -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
View File

@ -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
View File

@ -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
View 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
;

View File

@ -6,4 +6,5 @@
LOOP LOOP
2DROP 2DROP
; ;
: DELW 1- 0 SWAP C! ;
: PREV 3 - DUP @ - ; : PREV 3 - DUP @ - ;

Binary file not shown.