Added defer/is to support mutual recursion.
authorTim Vaughan <tgvaughan@gmail.com>
Tue, 5 Jul 2016 23:13:31 +0000 (01:13 +0200)
committerTim Vaughan <tgvaughan@gmail.com>
Tue, 5 Jul 2016 23:13:31 +0000 (01:13 +0200)
defer-is.4th [new file with mode: 0644]
scheme.4th

diff --git a/defer-is.4th b/defer-is.4th
new file mode 100644 (file)
index 0000000..bf3225a
--- /dev/null
@@ -0,0 +1,28 @@
+\ 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
+;
index 9a49053..915edba 100644 (file)
@@ -2,14 +2,36 @@ vocabulary scheme
 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
@@ -173,13 +195,8 @@ parse-idx-stack parse-idx-sp !
     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 )
@@ -226,16 +243,50 @@ parse-idx-stack parse-idx-sp !
     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
 
@@ -254,8 +305,8 @@ parse-idx-stack parse-idx-sp !
         exit
     then
 
-    empty-list? if
-        readnil
+    pair? if
+        readpair
         exit
     then
 
@@ -270,6 +321,8 @@ parse-idx-stack parse-idx-sp !
     abort
 ;
 
+' (read) is read
+
 \ ---- Eval ----
 
 : self-evaluating? ( obj -- obj bool )