1 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2 ;; and now
for something completely different
...
3 ;; UrForth
/C Forth Engine
!
4 ;; Copyright
(C
) 2023 Ketmar Dark
// Invisible Vector
6 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11 PARSE
-NAME DUP
" define name expected" ?NOT
-ERROR
12 PARSE
-SKIP
-LINE
-COMMENTS
13 TIB
-PEEKCH
" $DEFINE doesn't accept extra args yet" ?ERROR
19 PARSE
-NAME DUP
" define name expected" ?NOT
-ERROR
20 PARSE
-SKIP
-LINE
-COMMENTS
21 TIB
-PEEKCH
" $DEFINE doesn't accept extra args yet" ?ERROR
26 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
27 ;; simple expression evaluator
31 ALSO
($CC
-EVAL
) DEFINITIONS
33 0 VALUE CURR
-WORD
-ADDR
36 0 VALUE ALLOW
-CONTINUATIONS
41 DEFER $CC
-EXPR
( doeval?
-- value
)
44 : CURR
-WORD
( -- addr count
) CURR
-WORD
-ADDR CURR
-WORD
-LEN
;
46 : ONE
-CHAR
-WORD
( -- )
47 (TIB
-IN
) TO CURR
-WORD
-ADDR
1 TO CURR
-WORD
-LEN TIB
-SKIPCH
50 ;; one or two same chars
51 : ONE
-TWO
-CHAR
-WORD
( -- )
52 (TIB
-IN
) TO CURR
-WORD
-ADDR
53 TIB
-GETCH TIB
-PEEKCH
= IF TIB
-SKIPCH
2 TO CURR
-WORD
-LEN
54 ELSE 1 TO CURR
-WORD
-LEN
58 : IS
-SPECIAL
-CHAR
( ch
-- bool
)
60 [CHAR
] ! OF TRUE ENDOF
61 [CHAR
] ( OF TRUE ENDOF
62 [CHAR
] \ OF TRUE ENDOF
63 [CHAR
] ) OF TRUE ENDOF
64 [CHAR
] ~ OF TRUE ENDOF
65 [CHAR
] & OF TRUE ENDOF
66 [CHAR
] | OF TRUE ENDOF
67 [CHAR
] ; OF TRUE ENDOF
72 : CC
-PARSE
-SPECIAL
( -- )
73 TIB
-PEEKCH DUP
[CHAR
] & = SWAP
[CHAR
] |
= OR
74 IF ONE
-TWO
-CHAR
-WORD
ELSE ONE
-CHAR
-WORD
ENDIF
78 (TIB
-IN
) TO CURR
-WORD
-ADDR
80 TIB
-PEEKCH DUP BL
> SWAP IS
-SPECIAL
-CHAR NOT AND
84 (TIB
-IN
) CURR
-WORD
-ADDR
- TO CURR
-WORD
-LEN
90 0 OF
(TIB
-IN
) TO CURR
-WORD
-ADDR
0 TO CURR
-WORD
-LEN TRUE ENDOF
91 [CHAR
] ; OF ONE
-CHAR
-WORD PARSE
-SKIP
-LINE
0 TO CURR
-WORD
-LEN TRUE ENDOF
92 [CHAR
] \ OF
;; possible continuation
93 ALLOW
-CONTINUATIONS
IF
94 TIB
-SKIPCH PARSE
-SKIP
-BLANKS
95 TIB
-PEEKCH
" invalid continuation" ?ERROR
96 REFILL
-NOCROSS
" unexpected end of file" ?NOT
-ERROR
98 ELSE ONE
-CHAR
-WORD TRUE
101 BL
<=OF TIB
-SKIPCH FALSE ENDOF
103 IS
-SPECIAL
-CHAR
IF CC
-PARSE
-SPECIAL
ELSE CC
-PARSE
-ID
ENDIF
107 \
." |" CURR
-WORD XTYPE
." | -- " TIB
-PEEKCH XEMIT CR
110 ;; parse required argument in parens
111 : NEXT
-WORD
-ARG
( -- )
112 NEXT
-WORD CURR
-WORD
" (" STRING
:= " '(' expected" ?NOT
-ERROR
115 TIB
-PEEKCH DUP
34 = OVER
96 = OR SWAP
39 = OR
IF
116 TIB
-GETCH PARSE
" argument expected" ?NOT
-ERROR
117 TO CURR
-WORD
-LEN
TO CURR
-WORD
-ADDR
119 ;; parse up
to blank or
")"
121 (TIB
-IN
) TO CURR
-WORD
-ADDR
0 TO CURR
-WORD
-LEN
123 TIB
-PEEKCH DUP BL
<= SWAP
41 = OR
126 CURR
-WORD
-LEN
1+ TO CURR
-WORD
-LEN
129 \
." |" CURR
-WORD XTYPE
." | -- " TIB
-PEEKCH XEMIT CR
130 CURR
-WORD
-LEN
1 = CURR
-WORD
-ADDR C@ IS
-SPECIAL
-CHAR AND
" identifier required" ?ERROR
131 CURR
-WORD
;; save address
133 NEXT
-WORD CURR
-WORD
" )" STRING
:= " ')' expected" ?NOT
-ERROR
135 TO CURR
-WORD
-LEN
TO CURR
-WORD
-ADDR
136 \
." ||" CURR
-WORD XTYPE
." | -- " TIB
-PEEKCH XEMIT CR
140 VOCABULARY
($CC
-EVAL
-TERMS
)
141 ALSO
($CC
-EVAL
-TERMS
) DEFINITIONS
144 NEXT
-WORD
-ARG CURR
-WORD FORTH
:($DEFINED?
)
145 ?DUP IFNOT
;; try without a leading dollar
146 CURR
-WORD
-LEN
2 > CURR
-WORD
-ADDR C@
[CHAR
] $
= AND
IF
147 CURR
-WORD
-ADDR
1+ CURR
-WORD
-LEN
1- FORTH
:($DEFINED?
)
152 : UNDEFINED
( -- val
) DEFINED NOT
;
153 : HAS
-WORD
( -- val
) NEXT
-WORD
-ARG CURR
-WORD FIND
-WORD
IF DROP TRUE
ELSE FALSE
ENDIF ;
154 : NO
-WORD
( -- val
) HAS
-WORD NOT
;
155 ALIAS UNDEFINED NOT
-DEFINED
160 : $CC
-TERM
( -- value
)
161 \
." $TERM: " CURR
-WORD XTYPE CR
162 CURR
-WORD VOCID
: ($CC
-EVAL
-TERMS
) FIND
-WORD
-IN
-VOC
( cfa TRUE
/ FALSE
)
164 \
." $TERM: RES: " DUP
. CR
166 ;; special syntax
: $DEFVARNAME
167 CURR
-WORD
-LEN
2 > CURR
-WORD
-ADDR C@
36 = AND
IF
168 CURR
-WORD
-ADDR
1+ CURR
-WORD
-LEN
1- FORTH
:($DEFINED?
)
170 CURR
-WORD TRUE BASE @ FORTH
:(BASED
-NUMBER
) ( num TRUE
/ FALSE
)
171 IFNOT ENDCR SPACE CURR
-WORD XTYPE
." ? -- wut?!\n" " unknown term" ERROR
ENDIF
177 : $CC
-UNARY
( -- value
)
178 CURR
-WORD
" (" STRING
:= IF
180 CURR
-WORD
" )" STRING
:= " unbalanced parens" ?NOT
-ERROR
183 CURR
-WORD
" NOT" STRING
:=CI
184 CURR
-WORD
" !" STRING
:= OR
185 CURR
-WORD
" ~" STRING
:= OR
186 IF NEXT
-WORD RECURSE NOT
192 : $IS
-LOGAND
( -- bool
)
193 CURR
-WORD
" AND" STRING
:=CI
194 CURR
-WORD
" &&" STRING
:= OR
195 CURR
-WORD
" &" STRING
:= OR
198 : $IS
-LOGOR
( -- bool
)
199 CURR
-WORD
" OR" STRING
:=CI
200 CURR
-WORD
" ||" STRING
:= OR
201 CURR
-WORD
" |" STRING
:= OR
204 : ($CC
-LOG
-CREATE
) ( cfacheck cfalogop cfanext
-- value
)
206 ;; PFA
: cfanext cfacheck cfaop
207 -FIND
-REQUIRED
, ;; cfanext
208 -FIND
-REQUIRED
, ;; cfacheck
209 -FIND
-REQUIRED
, ;; cfaop
210 DOES
> ( pfa
-- value
)
215 NEXT
-WORD R@ @ EXECUTE
216 R@
2 +CELLS @ EXECUTE
221 ($CC
-LOG
-CREATE
) $CC
-AND $CC
-UNARY $IS
-LOGAND LOGAND
222 ($CC
-LOG
-CREATE
) $CC
-OR $CC
-AND $IS
-LOGOR LOGOR
225 ALLOW
-CONTINUATIONS
>R
226 1 TO ALLOW
-CONTINUATIONS $CC
-OR
227 R
> TO ALLOW
-CONTINUATIONS
230 ' ($CC-EXPR) TO $CC-EXPR
236 [CHAR] ; <> " invalid expression" ?ERROR
242 NEXT-WORD $CC-EXPR ENSURE-EOL
243 IF $IF-COUNT 1+ TO $IF-COUNT
244 ELSE TRUE $SKIP-CONDS
248 \ 0 VALUE ($SKIP-FROM-LINE)
250 : ($SKIP-CONDS) ( toelse -- )
252 ." SKIP: LINE=" 0 (INCLUDE-FILE-LINE) .
253 ." FILE: " 0 (INCLUDE-FILE-NAME) XTYPE CR
255 0 >R ( toelse | level )
257 REFILL-NOCROSS " unexpected end of file" ?NOT-ERROR
259 FALSE ( toelse done? | level )
260 CURR-WORD " $IF" STRING:=CI IF DROP R> 1+ >R FALSE ENDIF
261 CURR-WORD " $ENDIF" STRING:=CI IF DROP
262 ;; in nested ifs, look only for $ENDIF
265 ;; it doesn't matter which part we
're skipping, it ends here anyway
269 CURR-WORD " $ELSE" STRING:=CI IF DROP
270 ;; if we're skipping
"true" part
, go on
272 $
IF-COUNT
1+ TO $
IF-COUNT
275 ;; we
're skipping "false" part, there should be no else
276 " unexpected $ELSE" ERROR
281 CURR-WORD " $ELIF" STRING:=CI IF DROP
282 ;; if we're skipping
"true" part
, go on
284 ;; process the conditional
286 ;; either resume normal execution
, or keep searching
for $
ELSE
288 $
IF-COUNT
1+ TO $
IF-COUNT TRUE
292 ;; we
're skipping "false" part, there should be no else
293 " unexpected $ELIF" ERROR
298 DROP ;; drop `toelse`
299 R> 0<> " oops?" ?ERROR
300 \ REFILL " unexpected end of file" ?NOT-ERROR
304 ' ($SKIP
-CONDS
) TO $SKIP
-CONDS
310 ($CC
-EVAL
):$PROCESS
-COND
314 ($CC
-EVAL
):$
IF-COUNT
" unexpected $ELSE" ?NOT
-ERROR
315 ($CC
-EVAL
):ENSURE
-EOL
316 FALSE
($CC
-EVAL
):$SKIP
-CONDS
320 ($CC
-EVAL
):$
IF-COUNT
" unexpected $ELIF" ?NOT
-ERROR
321 ($CC
-EVAL
):$
IF-COUNT
1- TO ($CC
-EVAL
):$
IF-COUNT
322 FALSE
($CC
-EVAL
):$SKIP
-CONDS
326 ($CC
-EVAL
):$
IF-COUNT
" unexpected $ENDIF" ?NOT
-ERROR
327 ($CC
-EVAL
):ENSURE
-EOL
328 ($CC
-EVAL
):$
IF-COUNT
1- TO ($CC
-EVAL
):$
IF-COUNT
332 ALSO
($CC
-EVAL
):($CC
-EVAL
-TERMS
) DEFINITIONS
335 $
IF HAS
-WORD
(URASM
:HAS
-LABEL?
)
336 : HAS
-LABEL
( -- val
) NEXT
-WORD
-ARG CURR
-WORD URASM
:HAS
-LABEL?
;
337 : NO
-LABEL
( -- val
) HAS
-LABEL NOT
;
340 $
IF HAS
-WORD
(URASM
:PASS@
)
341 : PASS0
( -- val
) URASM
:PASS@
0= ;
342 : PASS1
( -- val
) URASM
:PASS@
0<> ;
347 PREVIOUS PREVIOUS DEFINITIONS