From: Tim Vaughan Date: Tue, 27 Jun 2017 20:19:37 +0000 (+1200) Subject: Merged macro quasiquote into analyze. X-Git-Url: https://thelambdalab.xyz/gitweb/index.cgi?p=scheme.forth.jl.git;a=commitdiff_plain;h=632cf90c6a97b1ee01a13ab424051f0a99c4a150;hp=346e7741d328a4521e8673f1c0418d05d59a4439 Merged macro quasiquote into analyze. --- diff --git a/src/scheme-library.scm b/src/scheme-library.scm index ec5c08e..8740e15 100644 --- a/src/scheme-library.scm +++ b/src/scheme-library.scm @@ -2,15 +2,78 @@ ;; Standard Library Procedures and Macros ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; MISC ESSENTIAL PROCEDURES + +(define list + (lambda args args)) + +(define map + (lambda (proc l) + (if (null? l) + '() + (cons (proc (car l)) (map proc (cdr l)))))) + +(define join-lists + (lambda (l1 l2) + (if (null? l1) + l2 + (cons (car l1) (join-lists (cdr l1) l2))))) + +; Append an arbitrary number of lists together +(define append + (lambda lists + (if (null? lists) + () + (if (null? (cdr lists)) + (car lists) + (join-lists (car lists) (apply append (cdr lists))))))) + + ;; DERIVED FORMS -;; define (procedural syntax) +;; define (define-macro (define args . body) (if (pair? args) - `(define ,(car args) (lambda ,(cdr args) ,@body)) + (list 'define (car args) (join-lists (list 'lambda (cdr args)) body)) 'no-match)) +;; not + +(define-macro (not x) + (list 'if x #f #t)) + +;; let + +(define-macro (let args . body) + (join-lists + (list (join-lists (list 'lambda (map (lambda (x) (car x)) args)) body)) + (map (lambda (x) (car (cdr x))) args))) + +;; quasiquote/unquote (one nesting level only) + +((lambda () + (define (qqhelper l) + (if (null? l) + l + (let ((head (car l)) + (tail (cdr l))) + + (if (pair? head) + (if (eq? (car head) 'unquote) + (list 'cons (car (cdr head)) (qqhelper tail)) + (if (eq? (car head) 'unquote-splicing) + (list 'join-lists (car (cdr head)) (qqhelper tail)) + (list 'cons (list 'quasiquote head) (qqhelper tail)))) + (if (symbol? head) + (list 'cons (list 'quote head) (qqhelper tail)) + (list 'cons head (qqhelper tail))))))) + + (define-macro (quasiquote arg) + (if (not (pair? arg)) + (list 'quote arg) + (qqhelper arg))))) + ;; begin (define-macro (begin . sequence) @@ -32,20 +95,6 @@ (define-macro (cdddr l) `(cdr (cdr (cdr ,l)))) (define-macro (cadddr l) `(car (cdr (cdr (cdr ,l))))) - -;; Methods used in remaining macro definitions: - -(define (map proc l) - (if (null? l) - '() - (cons (proc (car l)) (map proc (cdr l))))) - -;; let - -(define-macro (let args . body) - `((lambda ,(map (lambda (x) (car x)) args) - ,@body) ,@(map (lambda (x) (cadr x)) args))) - ;; let* (define-macro (let* args . body) @@ -105,31 +154,24 @@ (define-macro (and . expressions) (if (null? expressions) #t - (expand-and-expressions expressions))) - )) + (expand-and-expressions expressions))))) ;; or ((lambda () (define (expand-or-expressions expressions) - (if (null? expressions) - #f - (let ((first (car expressions)) - (rest (cdr expressions)) - (val (gensym))) - `(let ((,val ,first)) - (if ,val - ,val - ,(expand-or-expressions rest)))))) + (let ((first (car expressions)) + (rest (cdr expressions))) + (if (null? rest) + first + `(if ,first + #t + ,(expand-or-expressions rest))))) (define-macro (or . expressions) - (expand-or-expressions expressions)) - )) - -;; not - -(define-macro (not x) - `(if ,x #f #t)) + (if (null? expressions) + #f + (expand-or-expressions expressions))))) ;; FUNCTIONAL PROGRAMMING @@ -322,9 +364,6 @@ ;; LISTS -; List creation -(define (list . args) args) - ; Return number of items in list (define (length l) (define (iter a count) @@ -333,20 +372,6 @@ (iter (cdr a) (fix:+ count 1)))) (iter l 0)) -; Join two lists together -(define (join l1 l2) - (if (null? l1) - l2 - (cons (car l1) (join (cdr l1) l2)))) - -; Append an arbitrary number of lists together -(define (append . lists) - (if (null? lists) - () - (if (null? (cdr lists)) - (car lists) - (join (car lists) (apply append (cdr lists)))))) - ; Reverse the contents of a list (define (reverse l) (if (null? l) @@ -382,7 +407,6 @@ (fix:+ n (sum-recurse (fix:- n 1))))) - ;; MISC (define (license) diff --git a/src/scheme.4th b/src/scheme.4th index 4d5e33b..e5ac9cd 100644 --- a/src/scheme.4th +++ b/src/scheme.4th @@ -1315,95 +1315,6 @@ parse-idx-stack parse-idx-sp ! : quote-body ( quote-obj -- quote-body-obj ) cdr car ; -: quasiquote? ( obj -- obj bool ) - quasiquote-symbol tagged-list? ; - -: unquote? ( obj -- obj bool ) - unquote-symbol tagged-list? ; - -: unquote-splicing? ( obj -- obj bool ) - unquote-splicing-symbol tagged-list? ; - -: eval-unquote ( env obj -- res ) - cdr ( env args ) - - nil? if - except-message: ." no arguments to unquote." recoverable-exception throw - then - - 2dup cdr - nil? false = if - except-message: ." too many arguments to unquote." recoverable-exception throw - then - - 2drop car 2swap eval -; - -( Create a new list from elements of l1 consed on to l2 ) -: join-lists ( l2 l1 -- l3 ) - nil? if 2drop exit then - - 2dup car - -2rot cdr - recurse cons -; - -defer eval-quasiquote-item -: eval-quasiquote-pair ( env obj -- res ) - 2over 2over ( env obj env obj ) - - cdr eval-quasiquote-item - - -2rot car ( cdritem env objcar ) - - unquote-splicing? if - eval-unquote ( cdritems caritem ) - - 2swap nil? if - 2drop - else - 2swap join-lists - then - else - eval-quasiquote-item ( cdritems caritem ) - 2swap cons - then - -; - -:noname ( env obj ) - nil? if - 2swap 2drop exit - then - - unquote? if - eval-unquote exit - then - - pair-type istype? if - eval-quasiquote-pair exit - then - - 2swap 2drop -; is eval-quasiquote-item - -: eval-quasiquote ( obj env -- res ) - 2swap cdr ( env args ) - - nil? if - except-message: ." no arguments to quasiquote." recoverable-exception throw - then - - 2dup cdr ( env args args-cdr ) - nil? false = if - except-message: ." too many arguments to quasiquote." recoverable-exception throw - then - - 2drop car ( env arg ) - - eval-quasiquote-item -; - : variable? ( obj -- obj bool ) symbol-type istype? ; @@ -1665,11 +1576,6 @@ hide env exit then - quasiquote? if - 2swap eval-quasiquote - exit - then - variable? if 2swap lookup-var exit @@ -2030,33 +1936,6 @@ hide env R> drop ['] expand goto-deferred ; -: expand-quasiquote-item ( exp -- result ) - nil? if exit then - - unquote? if - unquote-symbol 2swap cdr car expand nil cons cons - exit - then - - unquote-splicing? if - unquote-splicing-symbol 2swap cdr car expand nil cons cons - exit - then - - pair-type istype? if - 2dup car recurse - 2swap cdr recurse - cons - then -; - -: expand-quasiquote ( exp -- result ) - quasiquote-symbol 2swap cdr - - expand-quasiquote-item - - cons ; - : expand-definition ( exp -- result ) define-symbol 2swap @@ -2126,8 +2005,6 @@ hide env quote? if exit then - quasiquote? if expand-quasiquote exit then - definition? if expand-definition exit then assignment? if expand-assignment exit then