--- /dev/null
+\ Add words supporting deferred execution
+
+: abort-defer
+ ." Tried to execute undefined deferred word." cr abort ;
+
+: defer
+ create ['] abort-defer ,
+does>
+ @ execute
+;
+
+hide abort-defer
+
+: defer! ( cfa cfaDef -- )
+ >body ! ;
+
+
+: is immediate
+ bl word find
+
+ 0= abort" Undefined deferred word."
+
+ state @ 0= if
+ defer!
+ else
+ ['] lit , , ['] defer! ,
+ then
+;
scheme definitions
include term-colours.4th
+include defer-is.4th
0 constant number-type
1 constant boolean-type
2 constant character-type
3 constant nil-type
+4 constant pair-type
: istype? ( obj -- obj b )
over = ;
+100 constant N
+create car-cells N allot
+create car-type-cells N allot
+create cdr-cells N allot
+create cdr-type-cells N allot
+
+variable nextfree
+0 nextfree !
+
+: cons ( car-obj cdr-obj -- pair-obj )
+ cdr-type-cells nextfree @ + !
+ cdr-cells nextfree @ + !
+ car-type-cells nextfree @ + !
+ car-cells nextfree @ + !
+
+ nextfree @ pair-type
+
+ 1 nextfree +!
+;
+
\ ---- Read ----
variable parse-idx
pop-parse-idx true
;
-: empty-list? ( -- bool )
- nextchar [char] ( <> if false exit then
- push-parse-idx
- inc-parse-idx
- eatspaces
- nextchar [char] ) <> if pop-parse-idx false exit then
- pop-parse-idx true ;
+: pair? ( -- bool )
+ nextchar [char] ( = ;
: readnum ( -- num-atom )
inc-parse-idx
;
-: readnil ( -- nil-atom )
+defer read
+
+: readpair ( -- obj )
inc-parse-idx
eatspaces
- inc-parse-idx
- nil-type
+ \ 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
+
+ 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
+
+ cons
;
\ Parse a scheme expression
-: read ( -- obj )
+: (read) ( -- obj )
eatspaces
exit
then
- empty-list? if
- readnil
+ pair? if
+ readpair
exit
then
abort
;
+' (read) is read
+
\ ---- Eval ----
: self-evaluating? ( obj -- obj bool )