4 include term-colours.4th
8 1 constant boolean-type
9 2 constant character-type
12 : istype? ( obj -- obj b )
16 create car-cells N allot
17 create car-type-cells N allot
18 create cdr-cells N allot
19 create cdr-type-cells N allot
24 : cons ( car-obj cdr-obj -- pair-obj )
25 cdr-type-cells nextfree @ + !
26 cdr-cells nextfree @ + !
27 car-type-cells nextfree @ + !
28 car-cells nextfree @ + !
38 variable stored-parse-idx
39 create parse-str 161 allot
40 variable parse-str-span
42 create parse-idx-stack 10 allot
44 parse-idx-stack parse-idx-sp !
47 parse-idx @ parse-idx-sp @ !
52 parse-idx-sp @ parse-idx-stack <= abort" Parse index stack underflow."
56 parse-idx-sp @ @ parse-idx ! ;
60 '\n' parse-str parse-str-span @ + !
68 parse-str 160 expect cr
69 span @ parse-str-span !
79 : charavailable? ( -- bool )
80 parse-str-span @ parse-idx @ > ;
82 : nextchar ( -- char )
83 charavailable? false = if getline then
84 parse-str parse-idx @ + @ ;
86 : whitespace? ( -- bool )
95 nextchar [char] ( = or
96 nextchar [char] ) = or
113 nextchar [char] - = ;
115 : number? ( -- bool )
116 digit? minus? or false = if
137 : boolean? ( -- bool )
138 nextchar [char] # <> if false exit then
145 and if pop-parse-idx false exit then
157 : str-equiv? ( str -- bool )
174 delim? false = if drop false then
179 : character? ( -- bool )
180 nextchar [char] # <> if false exit then
185 nextchar [char] \ <> if pop-parse-idx false exit then
189 S" newline" str-equiv? if pop-parse-idx true exit then
190 S" space" str-equiv? if pop-parse-idx true exit then
191 S" tab" str-equiv? if pop-parse-idx true exit then
193 charavailable? false = if pop-parse-idx false exit then
199 nextchar [char] ( = ;
202 : readnum ( -- num-atom )
210 10 * nextchar [char] 0 - +
219 : readbool ( -- bool-atom )
222 nextchar [char] f = if
233 : readchar ( -- char-atom )
237 S" newline" str-equiv? if 7 parse-idx +! '\n' character-type exit then
238 S" space" str-equiv? if 5 parse-idx +! bl character-type exit then
239 S" tab" str-equiv? if 3 parse-idx +! 9 character-type exit then
241 nextchar character-type
248 : readpair ( -- obj )
253 nextchar [char] ) = if
258 ." No delimiter following right paren. Aborting." cr
265 \ Read first pair element
270 nextchar [char] . = if
275 ." No delimiter following '.'. Aborting." cr
288 \ Parse a scheme expression
314 bold fg blue ." Moriturus te saluto." reset-term ." ok" cr
318 bold fg red ." Error parsing string starting at character '"
320 ." '. Aborting." reset-term cr
328 : self-evaluating? ( obj -- obj bool )
329 number-type istype? if true exit then
330 boolean-type istype? if true exit then
331 character-type istype? if true exit then
332 nil-type istype? if true exit then
340 bold fg red ." Error evaluating expression - unrecognized type. Aborting." reset-term cr
346 : printnum ( numobj -- ) drop . ;
348 : printbool ( numobj -- )
356 : printchar ( charobj -- )
360 bl of ." #\space" endof
361 '\n' of ." #\newline" endof
367 : printnil ( nilobj -- )
372 number-type istype? if printnum exit then
373 boolean-type istype? if printbool exit then
374 character-type istype? if printchar exit then
375 nil-type istype? if printnil exit then
381 cr ." Welcome to scheme.forth.jl!" cr
382 ." Use Ctrl-D to exit." cr
387 cr bold fg green ." > " reset-term
390 fg cyan print reset-term