4 include term-colours.4th
8 1 constant boolean-type
9 2 constant character-type
12 5 constant symbol-type
13 : istype? ( obj -- obj b )
17 create car-cells N allot
18 create car-type-cells N allot
19 create cdr-cells N allot
20 create cdr-type-cells N allot
25 : cons ( car-obj cdr-obj -- pair-obj )
26 cdr-type-cells nextfree @ + !
27 cdr-cells nextfree @ + !
28 car-type-cells nextfree @ + !
29 car-cells nextfree @ + !
36 : car ( pair-obj -- car-obj )
38 dup car-cells + @ swap
42 : cdr ( pair-obj -- car-obj )
44 dup cdr-cells + @ swap
52 variable stored-parse-idx
53 create parse-str 161 allot
54 variable parse-str-span
56 create parse-idx-stack 10 allot
58 parse-idx-stack parse-idx-sp !
61 parse-idx @ parse-idx-sp @ !
66 parse-idx-sp @ parse-idx-stack <= abort" Parse index stack underflow."
70 parse-idx-sp @ @ parse-idx ! ;
74 '\n' parse-str parse-str-span @ + !
82 parse-str 160 expect cr
83 span @ parse-str-span !
93 : charavailable? ( -- bool )
94 parse-str-span @ parse-idx @ > ;
96 : nextchar ( -- char )
97 charavailable? false = if getline then
98 parse-str parse-idx @ + @ ;
100 : whitespace? ( -- bool )
109 nextchar [char] ( = or
110 nextchar [char] ) = or
127 nextchar [char] - = ;
129 : number? ( -- bool )
130 digit? minus? or false = if
151 : boolean? ( -- bool )
152 nextchar [char] # <> if false exit then
159 and if pop-parse-idx false exit then
171 : str-equiv? ( str -- bool )
188 delim? false = if drop false then
193 : character? ( -- bool )
194 nextchar [char] # <> if false exit then
199 nextchar [char] \ <> if pop-parse-idx false exit then
203 S" newline" str-equiv? if pop-parse-idx true exit then
204 S" space" str-equiv? if pop-parse-idx true exit then
205 S" tab" str-equiv? if pop-parse-idx true exit then
207 charavailable? false = if pop-parse-idx false exit then
213 nextchar [char] ( = ;
216 : readnum ( -- num-atom )
224 10 * nextchar [char] 0 - +
233 : readbool ( -- bool-atom )
236 nextchar [char] f = if
247 : readchar ( -- char-atom )
251 S" newline" str-equiv? if 7 parse-idx +! '\n' character-type exit then
252 S" space" str-equiv? if 5 parse-idx +! bl character-type exit then
253 S" tab" str-equiv? if 3 parse-idx +! 9 character-type exit then
255 nextchar character-type
262 : readpair ( -- obj )
266 nextchar [char] ) = if
271 ." No delimiter following right paren. Aborting." cr
280 \ Read first pair element
285 nextchar [char] . = if
290 ." No delimiter following '.'. Aborting." cr
304 \ Parse a scheme expression
333 nextchar [char] ) <> if
334 bold red ." Missing closing paren." reset-term cr
344 bold fg blue ." Moriturus te saluto." reset-term ." ok" cr
348 bold fg red ." Error parsing string starting at character '"
350 ." '. Aborting." reset-term cr
357 : self-evaluating? ( obj -- obj bool )
358 number-type istype? if true exit then
359 boolean-type istype? if true exit then
360 character-type istype? if true exit then
361 nil-type istype? if true exit then
365 \ self-evaluating? if
370 bold fg red ." Error evaluating expression - unrecognized type. Aborting." reset-term cr
376 : printnum ( numobj -- ) drop 0 .R ;
378 : printbool ( numobj -- )
386 : printchar ( charobj -- )
390 bl of ." #\space" endof
391 '\n' of ." #\newline" endof
397 : printnil ( nilobj -- )
401 : printpair ( pairobj -- )
405 nil-type istype? if 2drop exit then
406 pair-type istype? if space recurse exit then
411 number-type istype? if printnum exit then
412 boolean-type istype? if printbool exit then
413 character-type istype? if printchar exit then
414 nil-type istype? if printnil exit then
415 pair-type istype? if ." (" printpair ." )" exit then
417 bold fg red ." Error printing expression - unrecognized type. Aborting" reset-term cr
424 cr ." Welcome to scheme.forth.jl!" cr
425 ." Use Ctrl-D to exit." cr
430 cr bold fg green ." > " reset-term
433 fg cyan ." ; " print reset-term