4 include term-colours.4th
8 1 constant boolean-type
9 2 constant character-type
10 3 constant string-type
13 6 constant symbol-type
14 : istype? ( obj -- obj b )
18 create car-cells N allot
19 create car-type-cells N allot
20 create cdr-cells N allot
21 create cdr-type-cells N allot
26 : cons ( car-obj cdr-obj -- pair-obj )
27 cdr-type-cells nextfree @ + !
28 cdr-cells nextfree @ + !
29 car-type-cells nextfree @ + !
30 car-cells nextfree @ + !
37 : car ( pair-obj -- car-obj )
39 dup car-cells + @ swap
43 : cdr ( pair-obj -- car-obj )
45 dup cdr-cells + @ swap
53 variable stored-parse-idx
54 create parse-str 161 allot
55 variable parse-str-span
57 create parse-idx-stack 10 allot
59 parse-idx-stack parse-idx-sp !
62 parse-idx @ parse-idx-sp @ !
67 parse-idx-sp @ parse-idx-stack <= abort" Parse index stack underflow."
71 parse-idx-sp @ @ parse-idx ! ;
75 '\n' parse-str parse-str-span @ + !
83 parse-str 160 expect cr
84 span @ parse-str-span !
94 : charavailable? ( -- bool )
95 parse-str-span @ parse-idx @ > ;
97 : nextchar ( -- char )
98 charavailable? false = if getline then
99 parse-str parse-idx @ + @ ;
101 : whitespace? ( -- bool )
110 nextchar [char] ( = or
111 nextchar [char] ) = or
128 nextchar [char] - = ;
130 : number? ( -- bool )
131 digit? minus? or false = if
152 : boolean? ( -- bool )
153 nextchar [char] # <> if false exit then
160 and if pop-parse-idx false exit then
172 : str-equiv? ( str -- bool )
189 delim? false = if drop false then
194 : character? ( -- bool )
195 nextchar [char] # <> if false exit then
200 nextchar [char] \ <> if pop-parse-idx false exit then
204 S" newline" str-equiv? if pop-parse-idx true exit then
205 S" space" str-equiv? if pop-parse-idx true exit then
206 S" tab" str-equiv? if pop-parse-idx true exit then
208 charavailable? false = if pop-parse-idx false exit then
214 nextchar [char] ( = ;
216 : string? ( -- bool )
217 nextchar [char] " = ;
219 : readnum ( -- num-atom )
227 10 * nextchar [char] 0 - +
236 : readbool ( -- bool-atom )
239 nextchar [char] f = if
250 : readchar ( -- char-atom )
254 S" newline" str-equiv? if 7 parse-idx +! '\n' character-type exit then
255 S" space" str-equiv? if 5 parse-idx +! bl character-type exit then
256 S" tab" str-equiv? if 3 parse-idx +! 9 character-type exit then
258 nextchar character-type
263 : readstring ( -- str-obj )
264 nextchar [char] " = if
269 ." No delimiter following right double quote. Aborting." cr
278 nextchar [char] \ = if
281 [char] n of '\n' endof
282 [char] " of [char] " endof
288 inc-parse-idx character-type
297 : readpair ( -- obj )
301 nextchar [char] ) = if
306 ." No delimiter following right paren. Aborting." cr
315 \ Read first pair element
320 nextchar [char] . = if
325 ." No delimiter following '.'. Aborting." cr
339 \ Parse a scheme expression
364 nextchar [char] " <> if
365 bold red ." Missing closing double-quote." reset-term cr
382 nextchar [char] ) <> if
383 bold red ." Missing closing paren." reset-term cr
393 bold fg blue ." Moriturus te saluto." reset-term ." ok" cr
397 bold fg red ." Error parsing string starting at character '"
399 ." '. Aborting." reset-term cr
406 : self-evaluating? ( obj -- obj bool )
407 number-type istype? if true exit then
408 boolean-type istype? if true exit then
409 character-type istype? if true exit then
410 string-type istype? if true exit then
411 nil-type istype? if true exit then
415 \ self-evaluating? if
420 bold fg red ." Error evaluating expression - unrecognized type. Aborting." reset-term cr
426 : printnum ( numobj -- ) drop 0 .R ;
428 : printbool ( numobj -- )
436 : printchar ( charobj -- )
440 bl of ." #\space" endof
441 '\n' of ." #\newline" endof
447 : (printstring) ( stringobj -- )
448 nil-type istype? if 2drop exit then
452 '\n' of ." \n" drop endof
453 [char] \ of ." \\" drop endof
454 [char] " of [char] \ emit [char] " emit drop endof
460 : printstring ( stringobj -- )
465 : printnil ( nilobj -- )
469 : printpair ( pairobj -- )
473 nil-type istype? if 2drop exit then
474 pair-type istype? if space recurse exit then
479 number-type istype? if printnum exit then
480 boolean-type istype? if printbool exit then
481 character-type istype? if printchar exit then
482 string-type istype? if printstring exit then
483 nil-type istype? if printnil exit then
484 pair-type istype? if ." (" printpair ." )" exit then
486 bold fg red ." Error printing expression - unrecognized type. Aborting" reset-term cr
493 cr ." Welcome to scheme.forth.jl!" cr
494 ." Use Ctrl-D to exit." cr
499 cr bold fg green ." > " reset-term
502 fg cyan ." ; " print reset-term