1 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2 ;; and now
for something completely different
...
3 ;; UrForth
/C Forth Engine
!
4 ;; Copyright
(C
) 2023 Ketmar Dark
// Invisible Vector
6 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12 ;; some compiler helpers
16 " LATEST-LFA" COMPILER
:(WFLAG
-PROTECTED
) COMPILER
:(CREATE
-WORD
-HEADER
)
17 COMPILER:(CFAIDX-DO-FORTH) , ]
18 CURRENT @ COMPILER
:(VOCOFS
-LATEST
) + @ FORTH
:(EXIT
)
19 [ ;; return to interpreter mode
(we don
't have a semicolon yet)
23 " NOOP" COMPILER:(WFLAG-PROTECTED) COMPILER:(CREATE-WORD-HEADER)
24 COMPILER:(CFAIDX-DO-FORTH) , ]
26 [ ;; return to interpreter mode (we don't have a semicolon yet
)
27 ;; we need it
's address
32 COMPILER FORTH:CONTEXT FORTH:@ FORTH:CURRENT FORTH:!
34 FORTH:" (CTLID-COLON)" COMPILER:(WFLAG-PROTECTED) COMPILER:(CREATE-WORD-HEADER)
35 COMPILER:(CFAIDX-DO-CONST) FORTH:, 0xdeadfeed FORTH:,
38 FORTH:DROP ;; drop "NOOP" CFA
41 ;; define in FORTH again
42 FORTH:FORTH FORTH:CONTEXT FORTH:@ FORTH:CURRENT FORTH:!
45 ;; define tick (we'll need it later
)
47 " '" COMPILER
:(WFLAG
-PROTECTED
) COMPILER
:(CREATE
-WORD
-HEADER
)
48 COMPILER:(CFAIDX-DO-FORTH) , ]
49 PARSE
-NAME
2DUP FIND
-WORD FORTH
:(TBRANCH
) [ HERE
0 , ]
51 ENDCR SPACE TYPE
" ? -- wut?\n" TYPE
" word not found" ERROR
55 [ ;; return to interpreter mode
(we don
't have a semicolon yet)
58 " :" COMPILER:(WFLAG-PROTECTED) COMPILER:(CREATE-WORD-HEADER)
59 COMPILER:(CFAIDX-DO-FORTH) , ]
60 COMPILER:?EXEC PARSE-NAME
61 ;; sanitise default word flags
62 FORTH:(NEW-WORD-FLAGS) @ COMPILER:(WFLAG-HIDDEN) COMPILER:(WFLAG-PROTECTED) OR AND
63 ;; create smudged words
64 COMPILER:(WFLAG-SMUDGE) OR COMPILER:(CREATE-WORD-HEADER)
66 COMPILER:(CFAIDX-DO-FORTH) FORTH:,
67 ;; push flag for semicolon
68 COMPILER:(CTLID-COLON)
69 ;; turn on the compiler
73 [ ;; return to interpreter mode
(we don
't have a semicolon yet)
76 " ;" COMPILER:(WFLAG-PROTECTED) COMPILER:(WFLAG-IMMEDIATE) OR COMPILER:(CREATE-WORD-HEADER)
77 COMPILER:(CFAIDX-DO-FORTH) , ]
78 COMPILER:?COMP COMPILER:(CTLID-COLON) <> " primary imbalance" ?ERROR
80 [ ' FORTH
:EXIT
, ] ;; because it is immediate
82 LATEST
-LFA LFA
->NFA DUP @ COMPILER
:(WFLAG
-SMUDGE
) BITNOT AND SWAP
!
83 ;; compile
"[" (it is immediate
)
87 [ ;; return to interpreter mode
(we don
't have a semicolon yet)
90 (NEW-WORD-FLAGS) @ COMPILER:(WFLAG-PROTECTED) OR (NEW-WORD-FLAGS) !
92 : ALIAS ( -- ) \ oldword newword
93 FORTH:' >R
;; we
'll need CFA later
96 R@ CFA->NFA @ 0xffff_00_00 AND ;; get word flags
97 COMPILER:(CREATE-WORD-HEADER)
99 COMPILER:(CFAIDX-DO-FORTH) FORTH:,
100 ;; execute original CFA, as tail-call
101 [ ' FORTH
:(LITCFA
) , ' FORTH:(LITCFA) , ] FORTH:, R> FORTH:,
102 [ ' FORTH
:(LITCFA
) , ' EXECUTE-TAIL , ] FORTH:,
105 \ : LATEST-LFA ( -- lfa ) CURRENT @ COMPILER:(VOCOFS-LATEST) + @ ;
106 : LATEST-CFA ( -- cfa ) LATEST-LFA LFA->CFA ;
107 : LATEST-PFA ( -- pfa ) LATEST-LFA LFA->PFA ;
108 : LATEST-NFA ( -- nfa ) LATEST-LFA LFA->NFA ;
110 : ~AND ( a b -- a&~b ) BITNOT AND ;
112 : SWAP! ( addr value -- ) SWAP ! ;
113 : OR! ( value addr -- ) DUP @ ROT OR SWAP! ;
114 : ~AND! ( value addr -- ) DUP @ ROT ~AND SWAP! ;
115 : XOR! ( value addr -- ) DUP @ ROT XOR SWAP! ;
117 : IMMEDIATE ( -- ) COMPILER:(WFLAG-IMMEDIATE) LATEST-NFA XOR! ;
118 : (HIDDEN) ( -- ) COMPILER:(WFLAG-HIDDEN) LATEST-NFA OR! ;
119 : (PUBLIC) ( -- ) COMPILER:(WFLAG-HIDDEN) LATEST-NFA ~AND! ;
121 ;; now we can define words with the usual mechanics
122 ALIAS ' -FIND
-REQUIRED
124 : PARSE
-SKIP
-COMMENTS
( -- ) TRUE
(PARSE
-SKIP
-COMMENTS
) ;
126 : PARSE
-SKIP
-LINE
-COMMENTS
( -- ) FALSE
(PARSE
-SKIP
-COMMENTS
) ;
129 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
133 : (SET
-DEF
-WORD
-FLAGS
) ( flg
-- ) (NEW
-WORD
-FLAGS
) @ OR
(NEW
-WORD
-FLAGS
) ! ; (HIDDEN
)
134 : (RESET
-DEF
-WORD
-FLAGS
) ( flg
-- ) (NEW
-WORD
-FLAGS
) @ SWAP BITNOT AND
(NEW
-WORD
-FLAGS
) ! ; (HIDDEN
)
136 : <PUBLIC
-WORDS
> ( -- ) COMPILER
:(WFLAG
-HIDDEN
) FORTH
:(RESET
-DEF
-WORD
-FLAGS
) ;
137 : <HIDDEN
-WORDS
> ( -- ) COMPILER
:(WFLAG
-HIDDEN
) FORTH
:(SET
-DEF
-WORD
-FLAGS
) ;
138 : <UNPROTECTED
-WORDS
> ( -- ) COMPILER
:(WFLAG
-PROTECTED
) FORTH
:(RESET
-DEF
-WORD
-FLAGS
) ;
139 : <PROTECTED
-WORDS
> ( -- ) COMPILER
:(WFLAG
-PROTECTED
) FORTH
:(SET
-DEF
-WORD
-FLAGS
) ;
141 : ONLY
( -- ) 0 (VSP
!) ;
142 : ALSO
( -- ) CONTEXT @
(VSP@
) (VSP
-AT
!) (VSP@
) 1 + (VSP
!) ;
143 : PREVIOUS
( -- ) (VSP@
) 1 - DUP
(VSP
!) (VSP
-AT@
) CONTEXT
! ;
144 : DEFINITIONS
( -- ) CONTEXT @ CURRENT
! <PUBLIC
-WORDS
> ;
147 ALSO DEBUG DEFINITIONS
149 : DECOMPILE
( -- ) \ wordname
150 -FIND
-REQUIRED
(DECOMPILE
-CFA
)
155 \ DEBUG
:DECOMPILE DEBUG
:DECOMPILE
158 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
159 ;; we need a way
to compile an immediate string literal
162 : IMM
-STRLITERAL STRLITERAL
; IMMEDIATE
165 : ID
-COUNT
( addr
-- addr count
) DUP C@ SWAP
4 + SWAP
;