+: readchar ( -- char-atom )
+ inc-parse-idx
+ inc-parse-idx
+
+ S" newline" str-equiv? if 7 parse-idx +! '\n' character-type exit then
+ S" space" str-equiv? if 5 parse-idx +! bl character-type exit then
+ S" tab" str-equiv? if 3 parse-idx +! 9 character-type exit then
+
+ nextchar character-type
+
+ inc-parse-idx
+;
+
+: readstring ( -- charlist )
+ nextchar [char] " = if
+ inc-parse-idx
+
+ delim? false = if
+ bold fg red
+ ." No delimiter following right double quote. Aborting." cr
+ reset-term abort
+ then
+
+ dec-parse-idx
+
+ 0 nil-type exit
+ then
+
+ nextchar [char] \ = if
+ inc-parse-idx
+ nextchar case
+ [char] n of '\n' endof
+ [char] " of [char] " endof
+ [char] \
+ endcase
+ else
+ nextchar
+ then
+ inc-parse-idx character-type
+
+ recurse
+
+ cons
+;
+
+: readsymbol ( -- charlist )
+ delim? if nil exit then
+
+ nextchar inc-parse-idx character-type
+
+ recurse
+
+ cons
+;
+
+: charlist-equiv ( charlist charlist -- bool )
+
+ 2over 2over
+
+ \ One or both nil
+ nil? -rot 2drop
+ if
+ nil? -rot 2drop
+ if
+ true exit
+ else
+ false exit
+ then
+ else
+ nil? -rot 2drop
+ if
+ false exit
+ then
+ then
+
+ 2over 2over
+
+ \ Neither nil
+ car 2swap car rot = -rot = and if
+ cdr 2swap cdr recurse
+ else
+ 2drop 2drop false
+ then
+;
+
+: (symbol-in-table?) ( charlist symbol-table -- charlist symbol-obj )
+
+ begin
+ nil? false =
+ while
+ 2over 2over
+ car
+ charlist-equiv if
+ repeat
+;
+
+: symbol-in-table? ( charlist -- charlist bool )
+ symbol-table (symbol-in-table?) ;
+
+defer read
+
+: readpair ( -- obj )
+ eatspaces
+
+ \ Empty lists
+ nextchar [char] ) = if
+ inc-parse-idx
+
+ delim? false = if
+ bold fg red
+ ." No delimiter following right paren. Aborting." cr
+ reset-term abort
+ then
+
+ dec-parse-idx
+
+ 0 nil-type exit
+ then
+
+ \ Read first pair element
+ read
+
+ \ Pairs
+ eatspaces
+ nextchar [char] . = if
+ inc-parse-idx
+
+ delim? false = if
+ bold fg red
+ ." No delimiter following '.'. Aborting." cr
+ reset-term abort
+ then
+
+ eatspaces read
+ else
+ recurse
+ then
+
+ eatspaces
+
+ cons
+;
+
+\ Parse a scheme expression
+:noname ( -- obj )