First tentative macro expansion working.
authorTim Vaughan <tgvaughan@gmail.com>
Mon, 12 Jun 2017 09:57:51 +0000 (21:57 +1200)
committerTim Vaughan <tgvaughan@gmail.com>
Mon, 12 Jun 2017 10:08:54 +0000 (22:08 +1200)
Tested by adding macro definition of procedural form of define.
Actually works for defining higher order functions too! For free!

src/scheme-derived-forms.scm [new file with mode: 0644]
src/scheme.4th

diff --git a/src/scheme-derived-forms.scm b/src/scheme-derived-forms.scm
new file mode 100644 (file)
index 0000000..1edd186
--- /dev/null
@@ -0,0 +1,9 @@
+;; define (procedural syntax)
+
+; Due to recursive macro expansion, this definition also allows
+; for curried function definitions.
+
+(define-macro (define args . body)
+              (if (pair? args)
+                `(define ,(car args) (lambda ,(cdr args) ,@body))
+                'no-match))
index 3931dad..8d361fc 100644 (file)
@@ -263,6 +263,7 @@ create-symbol lambda            lambda-symbol
 create-symbol λ                 λ-symbol
 create-symbol begin             begin-symbol
 create-symbol eof               eof-symbol
+create-symbol no-match          no-match-symbol
 
 \ Symbol to be bound to welcome message procedure by library
 create-symbol welcome           welcome-symbol
@@ -1403,34 +1404,21 @@ defer eval-quasiquote-item
 : definition? ( obj -- obj bool )
     define-symbol tagged-list? ;
 
-: make-lambda ( params body -- lambda-exp )
-    lambda-symbol -2rot cons cons ;
-
-( Handles iterative expansion of defines in
-  terms of nested lambdas. Most Schemes only
-  handle one iteration of expansion! )
-: definition-var-val ( obj -- var val )
-
-    cdr 2dup cdr 2swap car ( val var )
-
-    begin
-        symbol-type istype? false =
-    while
-        2dup cdr 2swap car ( val formals var' )
-        -2rot 2swap ( var' formals val )
-        make-lambda nil cons ( var' val' )
-        2swap ( val' var' )
-    repeat
+: definition-var ( obj -- var )
+    cdr car ;
 
-    2swap car
-;
+: definition-val ( obj -- val )
+    cdr cdr car ;
 
 : eval-definition ( obj env -- res )
-    2dup 2rot ( env env obj )
-    definition-var-val ( env env var val )
-    2rot eval  ( env var val )
+    2swap
+    2over 2over
+    definition-val 2swap
+    eval
 
-    2rot ( var val env )
+    2swap definition-var 2swap
+
+    2rot
     define-var
 
     ok-symbol
@@ -1766,6 +1754,8 @@ hide env
     extend-env eval-sequence eval
 ;
 
+defer expand
+
 : expand-quasiquote ;
 : expand-definition ;
 : expand-assignment ;
@@ -1775,8 +1765,28 @@ hide env
 : expand-begin ;
 : expand-application ;
 
+: expand-macro ( exp -- result )
+    pair-type istype? invert if exit then
+    2dup car symbol-type istype? invert if 2drop exit then
+    
+    lookup-macro nil? if
+        2drop exit then
+
+    2over cdr macro-eval
+
+    2dup no-match-symbol objeq? if
+        2drop exit
+    else
+        2swap 2drop
+    then
+
+    R> drop ['] expand goto-deferred
+;
+
 :noname ( exp -- result )
 
+    expand-macro
+
     quasiquote? if expand-quasiquote exit then
 
     definition? if expand-definition exit then
@@ -1789,9 +1799,9 @@ hide env
 
     lambda? if expand-lambda exit then
 
-    begin? if expand-sequence exit then
+    begin? if expand-begin exit then
 
-    application? if expand-apply exit then
+    application? if expand-application exit then
 
 ; is expand
 
@@ -2033,6 +2043,8 @@ variable gc-stack-depth
 
     include scheme-primitives.4th
 
+    s" scheme-derived-forms.scm" load 2drop
+
 \    s" scheme-library.scm" load 2drop
     
 \ }}}