Fix cond to conform to R7RS 'If the selected ⟨clause⟩ contains only the ⟨test⟩ and no ⟨expression⟩s, then the value of the ⟨test⟩ is returned as the result.'

This commit is contained in:
Doug Currie 2016-01-23 16:14:11 -05:00
parent 7019f81aaf
commit 0f3ef76fcb
1 changed files with 230 additions and 222 deletions

View File

@ -192,6 +192,10 @@ my $src = <<'EOL';
(if (and (variable? (car clause)) (if (and (variable? (car clause))
(variable=? (the 'else) (make-identifier (car clause) env))) (variable=? (the 'else) (make-identifier (car clause) env)))
(cons the-begin (cdr clause)) (cons the-begin (cdr clause))
(if (null? (cdr clause))
(let ((tmp (make-identifier 'tmp here)))
(list (the 'let) (list (list tmp (car clause)))
(list the-if tmp tmp (cons (the 'cond) (cdr clauses)))))
(if (and (variable? (cadr clause)) (if (and (variable? (cadr clause))
(variable=? (the '=>) (make-identifier (cadr clause) env))) (variable=? (the '=>) (make-identifier (cadr clause) env)))
(let ((tmp (make-identifier 'tmp here))) (let ((tmp (make-identifier 'tmp here)))
@ -201,7 +205,7 @@ my $src = <<'EOL';
(cons (the 'cond) (cdr clauses))))) (cons (the 'cond) (cdr clauses)))))
(list the-if (car clause) (list the-if (car clause)
(cons the-begin (cdr clause)) (cons the-begin (cdr clause))
(cons (the 'cond) (cdr clauses)))))))))) (cons (the 'cond) (cdr clauses)))))))))))
(define-macro quasiquote (define-macro quasiquote
(lambda (form env) (lambda (form env)
@ -788,220 +792,224 @@ const char pic_boot[][80] = {
"\n (if (null? clauses)\n #undefined\n (let ((clause (car cla", "\n (if (null? clauses)\n #undefined\n (let ((clause (car cla",
"uses)))\n (if (and (variable? (car clause))\n (vari", "uses)))\n (if (and (variable? (car clause))\n (vari",
"able=? (the 'else) (make-identifier (car clause) env)))\n (cons th", "able=? (the 'else) (make-identifier (car clause) env)))\n (cons th",
"e-begin (cdr clause))\n (if (and (variable? (cadr clause))\n ", "e-begin (cdr clause))\n (if (null? (cdr clause))\n ",
" (let ((tmp (make-identifier 'tmp here)))\n (list (the 'le",
"t) (list (list tmp (car clause)))\n (list the-if tmp t",
"mp (cons (the 'cond) (cdr clauses)))))\n (if (and (variable? (",
"cadr clause))\n (variable=? (the '=>) (make-identifie",
"r (cadr clause) env)))\n (let ((tmp (make-identifier 'tmp ",
"here)))\n (list (the 'let) (list (list tmp (car clause))",
")\n (list the-if tmp\n ",
" (list (car (cddr clause)) tmp)\n (c",
"ons (the 'cond) (cdr clauses)))))\n (list the-if (car clau",
"se)\n (cons the-begin (cdr clause))\n ",
" (cons (the 'cond) (cdr clauses)))))))))))\n\n(define-macro quasiquot",
"e\n (lambda (form env)\n\n (define (quasiquote? form)\n (and (pair? form)\n ",
" (variable? (car form))\n (variable=? (the 'quasiquote) (make-",
"identifier (car form) env))))\n\n (define (unquote? form)\n (and (pair? for",
"m)\n (variable? (car form))\n (variable=? (the 'unquote) (make",
"-identifier (car form) env))))\n\n (define (unquote-splicing? form)\n (and ",
"(pair? form)\n (pair? (car form))\n (variable? (caar form))\n ",
" (variable=? (the 'unquote-splicing) (make-identifier (caar form) env)))",
")\n\n (define (qq depth expr)\n (cond\n ;; unquote\n ((unquote? e",
"xpr)\n (if (= depth 1)\n (car (cdr expr))\n (list (the",
" 'list)\n (list (the 'quote) (the 'unquote))\n (",
"qq (- depth 1) (car (cdr expr))))))\n ;; unquote-splicing\n ((unquote-",
"splicing? expr)\n (if (= depth 1)\n (list (the 'append)\n ",
" (car (cdr (car expr)))\n (qq depth (cdr expr)))\n ",
" (list (the 'cons)\n (list (the 'list)\n ",
" (list (the 'quote) (the 'unquote-splicing))\n (qq (- d",
"epth 1) (car (cdr (car expr)))))\n (qq depth (cdr expr)))))\n ",
" ;; quasiquote\n ((quasiquote? expr)\n (list (the 'list)\n ",
" (list (the 'quote) (the 'quasiquote))\n (qq (+ depth 1) (car (cd",
"r expr)))))\n ;; list\n ((pair? expr)\n (list (the 'cons)\n ",
" (qq depth (car expr))\n (qq depth (cdr expr))))\n ;; ve",
"ctor\n ((vector? expr)\n (list (the 'list->vector) (qq depth (vector-",
">list expr))))\n ;; simple datum\n (else\n (list (the 'quote) ex",
"pr))))\n\n (let ((x (cadr form)))\n (qq 1 x))))\n\n(define-macro let*\n (lamb",
"da (form env)\n (let ((bindings (car (cdr form)))\n (body (cdr (cd",
"r form))))\n (if (null? bindings)\n `(,(the 'let) () ,@body)\n ",
" `(,(the 'let) ((,(car (car bindings)) ,@(cdr (car bindings))))\n (,",
"(the 'let*) (,@(cdr bindings))\n ,@body))))))\n\n(define-macro letrec\n ",
" (lambda (form env)\n `(,(the 'letrec*) ,@(cdr form))))\n\n(define-macro letrec*",
"\n (lambda (form env)\n (let ((bindings (car (cdr form)))\n (body ",
"(cdr (cdr form))))\n (let ((variables (map (lambda (v) `(,v #f)) (map car bi",
"ndings)))\n (initials (map (lambda (v) `(,(the 'set!) ,@v)) bindings)",
"))\n `(,(the 'let) (,@variables)\n ,@initials\n ,@body))))",
")\n\n(define-macro let-values\n (lambda (form env)\n `(,(the 'let*-values) ,@(cd",
"r form))))\n\n(define-macro let*-values\n (lambda (form env)\n (let ((formal (ca",
"r (cdr form)))\n (body (cdr (cdr form))))\n (if (null? formal)\n ",
" `(,(the 'let) () ,@body)\n `(,(the 'call-with-values) (,the-lambd",
"a () ,@(cdr (car formal)))\n (,(the 'lambda) (,@(car (car formal)))\n ",
" (,(the 'let*-values) (,@(cdr formal))\n ,@body)))))))\n\n(d",
"efine-macro define-values\n (lambda (form env)\n (let ((formal (car (cdr form)",
"))\n (body (cdr (cdr form))))\n (let ((arguments (make-identifier ",
"'arguments here)))\n `(,the-begin\n ,@(let loop ((formal formal))\n",
" (if (pair? formal)\n `((,the-define ,(car formal) ",
"#undefined) ,@(loop (cdr formal)))\n (if (variable? formal)\n ",
" `((,the-define ,formal #undefined))\n '())",
"))\n (,(the 'call-with-values) (,the-lambda () ,@body)\n (,the-",
"lambda\n ,arguments\n ,@(let loop ((formal formal) (args arg",
"uments))\n (if (pair? formal)\n `((,the-set! ,(c",
"ar formal) (,(the 'car) ,args)) ,@(loop (cdr formal) `(,(the 'cdr) ,args)))\n ",
" (if (variable? formal)\n `((,the-set! ,for",
"mal ,args))\n '()))))))))))\n\n(define-macro do\n (lambda (f",
"orm env)\n (let ((bindings (car (cdr form)))\n (test (car (car (cd",
"r (cdr form)))))\n (cleanup (cdr (car (cdr (cdr form)))))\n (bo",
"dy (cdr (cdr (cdr form)))))\n (let ((loop (make-identifier 'loop here)))",
"\n `(,(the 'let) ,loop ,(map (lambda (x) `(,(car x) ,(cadr x))) bindings)\n",
" (,the-if ,test\n (,the-begin\n ,@cl",
"eanup)\n (,the-begin\n ,@body\n ",
" (,loop ,@(map (lambda (x) (if (null? (cdr (cdr x))) (car x) (car (cdr (cdr ",
"x))))) bindings)))))))))\n\n(define-macro when\n (lambda (form env)\n (let ((tes",
"t (car (cdr form)))\n (body (cdr (cdr form))))\n `(,the-if ,test\n ",
" (,the-begin ,@body)\n #undefined))))\n\n(define-macro u",
"nless\n (lambda (form env)\n (let ((test (car (cdr form)))\n (body (cd",
"r (cdr form))))\n `(,the-if ,test\n #undefined\n ",
" (,the-begin ,@body)))))\n\n(define-macro case\n (lambda (form env)\n (let ((key",
" (car (cdr form)))\n (clauses (cdr (cdr form))))\n (let ((the-ke",
"y (make-identifier 'key here)))\n `(,(the 'let) ((,the-key ,key))\n ",
" ,(let loop ((clauses clauses))\n (if (null? clauses)\n ",
" #undefined\n (let ((clause (car clauses)))\n ",
"`(,the-if ,(if (and (variable? (car clause))\n ",
" (variable=? (the 'else) (make-identifier (car clause) env)))\n ",
" #t\n `(,(the 'or) ,@(map (lam",
"bda (x) `(,(the 'eqv?) ,the-key (,the-quote ,x))) (car clause))))\n ",
" ,(if (and (variable? (cadr clause))\n ",
" (variable=? (the '=>) (make-identifier (cadr clause) env)))\n ", " (variable=? (the '=>) (make-identifier (cadr clause) env)))\n ",
" (let ((tmp (make-identifier 'tmp here)))\n ", " `(,(car (cdr (cdr clause))) ,the-key)\n ",
" (list (the 'let) (list (list tmp (car clause)))\n (li", " `(,the-begin ,@(cdr clause)))\n ,(loo",
"st the-if tmp\n (list (car (cddr clause)) tmp)\n ", "p (cdr clauses)))))))))))\n\n(define-macro parameterize\n (lambda (form env)\n (",
" (cons (the 'cond) (cdr clauses)))))\n ", "let ((formal (car (cdr form)))\n (body (cdr (cdr form))))\n `(,(th",
" (list the-if (car clause)\n (cons the-begin (cd", "e 'with-parameter)\n (,(the 'lambda) ()\n ,@formal\n ,@body)",
"r clause))\n (cons (the 'cond) (cdr clauses))))))))))\n\n(", "))))\n\n(define-macro syntax-quote\n (lambda (form env)\n (let ((renames '()))\n ",
"define-macro quasiquote\n (lambda (form env)\n\n (define (quasiquote? form)\n ", " (letrec\n ((rename (lambda (var)\n (let ((x (ass",
" (and (pair? form)\n (variable? (car form))\n (variable=? (t", "q var renames)))\n (if x\n (cadr x",
"he 'quasiquote) (make-identifier (car form) env))))\n\n (define (unquote? form)", ")\n (begin\n (set! renames `",
"\n (and (pair? form)\n (variable? (car form))\n (variable=", "((,var ,(make-identifier var env) (,(the 'make-identifier) ',var ',env)) . ,rena",
"? (the 'unquote) (make-identifier (car form) env))))\n\n (define (unquote-splic", "mes))\n (rename var))))))\n (walk (lambda (f",
"ing? form)\n (and (pair? form)\n (pair? (car form))\n (var", " form)\n (cond\n ((variable? form)\n ",
"iable? (caar form))\n (variable=? (the 'unquote-splicing) (make-identif", " (f form))\n ((pair? form)\n `(,(",
"ier (caar form) env))))\n\n (define (qq depth expr)\n (cond\n ;; unquo", "the 'cons) (walk f (car form)) (walk f (cdr form))))\n ((vecto",
"te\n ((unquote? expr)\n (if (= depth 1)\n (car (cdr expr))\n", "r? form)\n `(,(the 'list->vector) (walk f (vector->list form)",
" (list (the 'list)\n (list (the 'quote) (the 'unquote", ")))\n (else\n `(,(the 'quote) ,form))))))\n ",
"))\n (qq (- depth 1) (car (cdr expr))))))\n ;; unquote-spli", " (let ((form (walk rename (cadr form))))\n `(,(the 'let)\n ",
"cing\n ((unquote-splicing? expr)\n (if (= depth 1)\n (list ", " ,(map cdr renames)\n ,form))))))\n\n(define-macro syntax-quasiquote\n ",
"(the 'append)\n (car (cdr (car expr)))\n (qq dep", " (lambda (form env)\n (let ((renames '()))\n (letrec\n ((rename (l",
"th (cdr expr)))\n (list (the 'cons)\n (list (the 'list", "ambda (var)\n (let ((x (assq var renames)))\n ",
")\n (list (the 'quote) (the 'unquote-splicing))\n ", " (if x\n (cadr x)\n (begi",
" (qq (- depth 1) (car (cdr (car expr)))))\n (qq dep", "n\n (set! renames `((,var ,(make-identifier var env) ",
"th (cdr expr)))))\n ;; quasiquote\n ((quasiquote? expr)\n (list ", "(,(the 'make-identifier) ',var ',env)) . ,renames))\n ",
"(the 'list)\n (list (the 'quote) (the 'quasiquote))\n (q", " (rename var)))))))\n\n (define (syntax-quasiquote? form)\n (and (p",
"q (+ depth 1) (car (cdr expr)))))\n ;; list\n ((pair? expr)\n (l", "air? form)\n (variable? (car form))\n (variable=? (the",
"ist (the 'cons)\n (qq depth (car expr))\n (qq depth (cdr", " 'syntax-quasiquote) (make-identifier (car form) env))))\n\n (define (synta",
" expr))))\n ;; vector\n ((vector? expr)\n (list (the 'list->vect", "x-unquote? form)\n (and (pair? form)\n (variable? (car form",
"or) (qq depth (vector->list expr))))\n ;; simple datum\n (else\n ", "))\n (variable=? (the 'syntax-unquote) (make-identifier (car form) ",
" (list (the 'quote) expr))))\n\n (let ((x (cadr form)))\n (qq 1 x))))\n\n(def", "env))))\n\n (define (syntax-unquote-splicing? form)\n (and (pair? f",
"ine-macro let*\n (lambda (form env)\n (let ((bindings (car (cdr form)))\n ", "orm)\n (pair? (car form))\n (variable? (caar form))\n ",
" (body (cdr (cdr form))))\n (if (null? bindings)\n `(,(the 'l", " (variable=? (the 'syntax-unquote-splicing) (make-identifier (caar f",
"et) () ,@body)\n `(,(the 'let) ((,(car (car bindings)) ,@(cdr (car bindi", "orm) env))))\n\n (define (qq depth expr)\n (cond\n ;; synt",
"ngs))))\n (,(the 'let*) (,@(cdr bindings))\n ,@body))))))\n\n", "ax-unquote\n ((syntax-unquote? expr)\n (if (= depth 1)\n ",
"(define-macro letrec\n (lambda (form env)\n `(,(the 'letrec*) ,@(cdr form))))\n", " (car (cdr expr))\n (list (the 'list)\n ",
"\n(define-macro letrec*\n (lambda (form env)\n (let ((bindings (car (cdr form))", " (list (the 'quote) (the 'syntax-unquote))\n (qq (- depth ",
")\n (body (cdr (cdr form))))\n (let ((variables (map (lambda (v)", "1) (car (cdr expr))))))\n ;; syntax-unquote-splicing\n ((synta",
" `(,v #f)) (map car bindings)))\n (initials (map (lambda (v) `(,(the ", "x-unquote-splicing? expr)\n (if (= depth 1)\n (list (the",
"'set!) ,@v)) bindings)))\n `(,(the 'let) (,@variables)\n ,@initial", " 'append)\n (car (cdr (car expr)))\n (qq",
"s\n ,@body)))))\n\n(define-macro let-values\n (lambda (form env)\n `(,(t", " depth (cdr expr)))\n (list (the 'cons)\n (lis",
"he 'let*-values) ,@(cdr form))))\n\n(define-macro let*-values\n (lambda (form env)", "t (the 'list)\n (list (the 'quote) (the 'syntax-unquot",
"\n (let ((formal (car (cdr form)))\n (body (cdr (cdr form))))\n ", "e-splicing))\n (qq (- depth 1) (car (cdr (car expr))))",
"(if (null? formal)\n `(,(the 'let) () ,@body)\n `(,(the 'call-wi", ")\n (qq depth (cdr expr)))))\n ;; syntax-quasiquote",
"th-values) (,the-lambda () ,@(cdr (car formal)))\n (,(the 'lambda) (,@", "\n ((syntax-quasiquote? expr)\n (list (the 'list)\n ",
"(car (car formal)))\n (,(the 'let*-values) (,@(cdr formal))\n ", " (list (the 'quote) (the 'quasiquote))\n (qq (+ depth 1) (",
" ,@body)))))))\n\n(define-macro define-values\n (lambda (form env)\n (let ((", "car (cdr expr)))))\n ;; list\n ((pair? expr)\n (list",
"formal (car (cdr form)))\n (body (cdr (cdr form))))\n (let ((argum", " (the 'cons)\n (qq depth (car expr))\n (qq depth",
"ents (make-identifier 'arguments here)))\n `(,the-begin\n ,@(let l", " (cdr expr))))\n ;; vector\n ((vector? expr)\n (list",
"oop ((formal formal))\n (if (pair? formal)\n `((,the", " (the 'list->vector) (qq depth (vector->list expr))))\n ;; variable\n ",
"-define ,(car formal) #undefined) ,@(loop (cdr formal)))\n (if (", " ((variable? expr)\n (rename expr))\n ;; simple datum\n",
"variable? formal)\n `((,the-define ,formal #undefined))\n ", " (else\n (list (the 'quote) expr))))\n\n (let ((body (q",
" '())))\n (,(the 'call-with-values) (,the-lambda () ,@b", "q 1 (cadr form))))\n `(,(the 'let)\n ,(map cdr renames)\n ",
"ody)\n (,the-lambda\n ,arguments\n ,@(let loop ((fo", " ,body))))))\n\n(define (transformer f)\n (lambda (form env)\n (let ((regis",
"rmal formal) (args arguments))\n (if (pair? formal)\n ", "ter1 (make-register))\n (register2 (make-register)))\n (letrec\n ",
" `((,the-set! ,(car formal) (,(the 'car) ,args)) ,@(loop (cdr formal) `(,(t", " ((wrap (lambda (var1)\n (let ((var2 (register1 var1)))\n ",
"he 'cdr) ,args)))\n (if (variable? formal)\n ", " (if var2\n (cdr var2)\n ",
" `((,the-set! ,formal ,args))\n '()))))))))))\n\n(define", " (let ((var2 (make-identifier var1 env)))\n (reg",
"-macro do\n (lambda (form env)\n (let ((bindings (car (cdr form)))\n (", "ister1 var1 var2)\n (register2 var2 var1)\n ",
"test (car (car (cdr (cdr form)))))\n (cleanup (cdr (car (cdr (cdr f", " var2)))))\n (unwrap (lambda (var2)\n (",
"orm)))))\n (body (cdr (cdr (cdr form)))))\n (let ((loop (make-id", "let ((var1 (register2 var2)))\n (if var1\n ",
"entifier 'loop here)))\n `(,(the 'let) ,loop ,(map (lambda (x) `(,(car x) ", " (cdr var1)\n var2))))\n (walk (lambda",
",(cadr x))) bindings)\n (,the-if ,test\n (,the-begin\n ", " (f form)\n (cond\n ((variable? form)\n ",
" ,@cleanup)\n (,the-begin\n ", " (f form))\n ((pair? form)\n (",
",@body\n (,loop ,@(map (lambda (x) (if (null? (cdr (cdr x))) (", "cons (walk f (car form)) (walk f (cdr form))))\n ((vector? for",
"car x) (car (cdr (cdr x))))) bindings)))))))))\n\n(define-macro when\n (lambda (fo", "m)\n (list->vector (walk f (vector->list form))))\n ",
"rm env)\n (let ((test (car (cdr form)))\n (body (cdr (cdr form))))\n ", " (else\n form)))))\n (let ((form (cdr form)))\n ",
" `(,the-if ,test\n (,the-begin ,@body)\n #undefine", " (walk unwrap (apply f (walk wrap form))))))))\n\n(define-macro define-syn",
"d))))\n\n(define-macro unless\n (lambda (form env)\n (let ((test (car (cdr form)", "tax\n (lambda (form env)\n (let ((formal (car (cdr form)))\n (body (",
"))\n (body (cdr (cdr form))))\n `(,the-if ,test\n #und", "cdr (cdr form))))\n (if (pair? formal)\n `(,(the 'define-syntax) ,(c",
"efined\n (,the-begin ,@body)))))\n\n(define-macro case\n (lambda (fo", "ar formal) (,the-lambda ,(cdr formal) ,@body))\n `(,the-define-macro ,fo",
"rm env)\n (let ((key (car (cdr form)))\n (clauses (cdr (cdr form))", "rmal (,(the 'transformer) (,the-begin ,@body)))))))\n\n(define-macro letrec-syntax",
"))\n (let ((the-key (make-identifier 'key here)))\n `(,(the 'let) ((,t", "\n (lambda (form env)\n (let ((formal (car (cdr form)))\n (body (cdr",
"he-key ,key))\n ,(let loop ((clauses clauses))\n (if (null? c", " (cdr form))))\n `(let ()\n ,@(map (lambda (x)\n `(,(",
"lauses)\n #undefined\n (let ((clause (car clauses)", "the 'define-syntax) ,(car x) ,(cadr x)))\n formal)\n ,@body",
"))\n `(,the-if ,(if (and (variable? (car clause))\n ", "))))\n\n(define-macro let-syntax\n (lambda (form env)\n `(,(the 'letrec-syntax) ",
" (variable=? (the 'else) (make-identifier (car clause) ", ",@(cdr form))))\n\n\n;;; library primitives\n\n(define-macro define-library\n (lambda",
"env)))\n #t\n `(", " (form _)\n (let ((name (cadr form))\n (body (cddr form)))\n (let ",
",(the 'or) ,@(map (lambda (x) `(,(the 'eqv?) ,the-key (,the-quote ,x))) (car cla", "((old-library (current-library))\n (new-library (or (find-library name",
"use))))\n ,(if (and (variable? (cadr clause))\n ", ") (make-library name))))\n (let ((env (library-environment new-library)))\n",
" (variable=? (the '=>) (make-identifier (cadr cla", " (current-library new-library)\n (for-each (lambda (expr) (eval",
"use) env)))\n `(,(car (cdr (cdr clause))) ,the-k", " expr env)) body)\n (current-library old-library))))))\n\n(define-macro co",
"ey)\n `(,the-begin ,@(cdr clause)))\n ", "nd-expand\n (lambda (form _)\n (letrec\n ((test (lambda (form)\n ",
" ,(loop (cdr clauses)))))))))))\n\n(define-macro parameterize\n (l", " (or\n (eq? form 'else)\n (and (symbol? f",
"ambda (form env)\n (let ((formal (car (cdr form)))\n (body (cdr (cdr", "orm)\n (memq form (features)))\n (and (pair",
" form))))\n `(,(the 'with-parameter)\n (,(the 'lambda) ()\n ,@f", "? form)\n (case (car form)\n ((libra",
"ormal\n ,@body)))))\n\n(define-macro syntax-quote\n (lambda (form env)\n ", "ry) (find-library (cadr form)))\n ((not) (not (test (cadr",
"(let ((renames '()))\n (letrec\n ((rename (lambda (var)\n ", " form))))\n ((and) (let loop ((form (cdr form)))\n ",
" (let ((x (assq var renames)))\n (if x\n ", " (or (null? form)\n ",
" (cadr x)\n (begin\n ", " (and (test (car form)) (loop (cdr form))))))\n ((or) (le",
" (set! renames `((,var ,(make-identifier var env) (,(the 'make-identifier)", "t loop ((form (cdr form)))\n (and (pair? form)\n ",
" ',var ',env)) . ,renames))\n (rename var))))))\n ", " (or (test (car form)) (loop (cdr form))))))\n",
" (walk (lambda (f form)\n (cond\n ((vari", " (else #f)))))))\n (let loop ((clauses (cdr form)))\n",
"able? form)\n (f form))\n ((pair? form)\n ", " (if (null? clauses)\n #undefined\n (if (test (caar c",
" `(,(the 'cons) (walk f (car form)) (walk f (cdr form))))\n ", "lauses))\n `(,the-begin ,@(cdar clauses))\n (loop (c",
" ((vector? form)\n `(,(the 'list->vector) (walk", "dr clauses))))))))\n\n(define-macro import\n (lambda (form _)\n (let ((caddr\n ",
" f (vector->list form))))\n (else\n `(,(the", " (lambda (x) (car (cdr (cdr x)))))\n (prefix\n (lambda (",
" 'quote) ,form))))))\n (let ((form (walk rename (cadr form))))\n `", "prefix symbol)\n (string->symbol\n (string-append\n ",
"(,(the 'let)\n ,(map cdr renames)\n ,form))))))\n\n(define-mac", " (symbol->string prefix)\n (symbol->string symbol))))))\n ",
"ro syntax-quasiquote\n (lambda (form env)\n (let ((renames '()))\n (letrec", " (letrec\n ((extract\n (lambda (spec)\n (case (ca",
"\n ((rename (lambda (var)\n (let ((x (assq var rename", "r spec)\n ((only rename prefix except)\n (extract (",
"s)))\n (if x\n (cadr x)\n ", "cadr spec)))\n (else\n (or (find-library spec) (err",
" (begin\n (set! renames `((,var ,(mak", "or \"library not found\" spec))))))\n (collect\n (lambda (spec)",
"e-identifier var env) (,(the 'make-identifier) ',var ',env)) . ,renames))\n ", "\n (case (car spec)\n ((only)\n (let ((",
" (rename var)))))))\n\n (define (syntax-quasiquote? f", "alist (collect (cadr spec))))\n (map (lambda (var) (assq var al",
"orm)\n (and (pair? form)\n (variable? (car form))\n ", "ist)) (cddr spec))))\n ((rename)\n (let ((alist (co",
" (variable=? (the 'syntax-quasiquote) (make-identifier (car form) env))))\n\n", "llect (cadr spec)))\n (renames (map (lambda (x) `((car x) .",
" (define (syntax-unquote? form)\n (and (pair? form)\n ", " (cadr x))) (cddr spec))))\n (map (lambda (s) (or (assq (car s)",
" (variable? (car form))\n (variable=? (the 'syntax-unquote) (make-", " renames) s)) alist)))\n ((prefix)\n (let ((alist (",
"identifier (car form) env))))\n\n (define (syntax-unquote-splicing? form)\n ", "collect (cadr spec))))\n (map (lambda (s) (cons (prefix (caddr ",
" (and (pair? form)\n (pair? (car form))\n (var", "spec) (car s)) (cdr s))) alist)))\n ((except)\n (le",
"iable? (caar form))\n (variable=? (the 'syntax-unquote-splicing) (m", "t ((alist (collect (cadr spec))))\n (let loop ((alist alist))\n ",
"ake-identifier (caar form) env))))\n\n (define (qq depth expr)\n (c", " (if (null? alist)\n '()\n ",
"ond\n ;; syntax-unquote\n ((syntax-unquote? expr)\n ", " (if (memq (caar alist) (cddr spec))\n (lo",
"(if (= depth 1)\n (car (cdr expr))\n (list (the 'lis", "op (cdr alist))\n (cons (car alist) (loop (cdr alist)",
"t)\n (list (the 'quote) (the 'syntax-unquote))\n ", ")))))))\n (else\n (let ((lib (or (find-library spec",
" (qq (- depth 1) (car (cdr expr))))))\n ;; syntax-unquote-splic", ") (error \"library not found\" spec))))\n (map (lambda (x) (cons ",
"ing\n ((syntax-unquote-splicing? expr)\n (if (= depth 1)\n ", "x x)) (library-exports lib))))))))\n (letrec\n ((import\n ",
" (list (the 'append)\n (car (cdr (car expr)))\n ", " (lambda (spec)\n (let ((lib (extract spec))\n ",
" (qq depth (cdr expr)))\n (list (the 'cons)\n ", " (alist (collect spec)))\n (for-each\n ",
" (list (the 'list)\n (list (the 'quot", " (lambda (slot)\n (library-import lib (cdr slot) (car slot)",
"e) (the 'syntax-unquote-splicing))\n (qq (- depth 1) (", "))\n alist)))))\n (for-each import (cdr form)))))))\n\n(",
"car (cdr (car expr)))))\n (qq depth (cdr expr)))))\n ", "define-macro export\n (lambda (form _)\n (letrec\n ((collect\n (",
" ;; syntax-quasiquote\n ((syntax-quasiquote? expr)\n (list (", "lambda (spec)\n (cond\n ((symbol? spec)\n `(,sp",
"the 'list)\n (list (the 'quote) (the 'quasiquote))\n ", "ec . ,spec))\n ((and (list? spec) (= (length spec) 3) (eq? (car spec)",
" (qq (+ depth 1) (car (cdr expr)))))\n ;; list\n ((pair? e", " 'rename))\n `(,(list-ref spec 1) . ,(list-ref spec 2)))\n ",
"xpr)\n (list (the 'cons)\n (qq depth (car expr))\n ", " (else\n (error \"malformed export\")))))\n (export\n ",
" (qq depth (cdr expr))))\n ;; vector\n ((vector? e", " (lambda (spec)\n (let ((slot (collect spec)))\n (librar",
"xpr)\n (list (the 'list->vector) (qq depth (vector->list expr))))\n ", "y-export (car slot) (cdr slot))))))\n (for-each export (cdr form)))))\n\n(expo",
" ;; variable\n ((variable? expr)\n (rename expr))\n ", "rt define lambda quote set! if begin define-macro\n let let* letrec letrec",
" ;; simple datum\n (else\n (list (the 'quote) expr))))\n\n", "*\n let-values let*-values define-values\n quasiquote unquote unquot",
" (let ((body (qq 1 (cadr form))))\n `(,(the 'let)\n ,(m", "e-splicing\n and or\n cond case else =>\n do when unless\n ",
"ap cdr renames)\n ,body))))))\n\n(define (transformer f)\n (lambda (form", " parameterize\n define-syntax\n syntax-quote syntax-unquote\n ",
" env)\n (let ((register1 (make-register))\n (register2 (make-register)", " syntax-quasiquote syntax-unquote-splicing\n let-syntax letrec-syntax\n ",
"))\n (letrec\n ((wrap (lambda (var1)\n (let ((var2 ", " syntax-error)\n\n\n",
"(register1 var1)))\n (if var2\n (cdr v",
"ar2)\n (let ((var2 (make-identifier var1 env)))\n ",
" (register1 var1 var2)\n (register2 va",
"r2 var1)\n var2)))))\n (unwrap (lambda (var2)\n",
" (let ((var1 (register2 var2)))\n (if v",
"ar1\n (cdr var1)\n var2))))\n ",
" (walk (lambda (f form)\n (cond\n ((v",
"ariable? form)\n (f form))\n ((pair? form)\n",
" (cons (walk f (car form)) (walk f (cdr form))))\n ",
" ((vector? form)\n (list->vector (walk f (vector->lis",
"t form))))\n (else\n form)))))\n (let",
" ((form (cdr form)))\n (walk unwrap (apply f (walk wrap form))))))))\n\n(d",
"efine-macro define-syntax\n (lambda (form env)\n (let ((formal (car (cdr form)",
"))\n (body (cdr (cdr form))))\n (if (pair? formal)\n `(,(t",
"he 'define-syntax) ,(car formal) (,the-lambda ,(cdr formal) ,@body))\n `",
"(,the-define-macro ,formal (,(the 'transformer) (,the-begin ,@body)))))))\n\n(defi",
"ne-macro letrec-syntax\n (lambda (form env)\n (let ((formal (car (cdr form)))\n",
" (body (cdr (cdr form))))\n `(let ()\n ,@(map (lambda (x)\n",
" `(,(the 'define-syntax) ,(car x) ,(cadr x)))\n f",
"ormal)\n ,@body))))\n\n(define-macro let-syntax\n (lambda (form env)\n `(",
",(the 'letrec-syntax) ,@(cdr form))))\n\n\n;;; library primitives\n\n(define-macro de",
"fine-library\n (lambda (form _)\n (let ((name (cadr form))\n (body (cd",
"dr form)))\n (let ((old-library (current-library))\n (new-library ",
"(or (find-library name) (make-library name))))\n (let ((env (library-envir",
"onment new-library)))\n (current-library new-library)\n (for-eac",
"h (lambda (expr) (eval expr env)) body)\n (current-library old-library))",
"))))\n\n(define-macro cond-expand\n (lambda (form _)\n (letrec\n ((test (l",
"ambda (form)\n (or\n (eq? form 'else)\n ",
" (and (symbol? form)\n (memq form (features)))\n ",
" (and (pair? form)\n (case (car form)\n ",
" ((library) (find-library (cadr form)))\n (",
"(not) (not (test (cadr form))))\n ((and) (let loop ((form",
" (cdr form)))\n (or (null? form)\n ",
" (and (test (car form)) (loop (cdr form))))))\n ",
" ((or) (let loop ((form (cdr form)))\n ",
" (and (pair? form)\n (or (test (car form)) ",
"(loop (cdr form))))))\n (else #f)))))))\n (let loop (",
"(clauses (cdr form)))\n (if (null? clauses)\n #undefined\n ",
" (if (test (caar clauses))\n `(,the-begin ,@(cdar clauses))\n ",
" (loop (cdr clauses))))))))\n\n(define-macro import\n (lambda (form _",
")\n (let ((caddr\n (lambda (x) (car (cdr (cdr x)))))\n (prefi",
"x\n (lambda (prefix symbol)\n (string->symbol\n ",
"(string-append\n (symbol->string prefix)\n (symbol->st",
"ring symbol))))))\n (letrec\n ((extract\n (lambda (spec)\n ",
" (case (car spec)\n ((only rename prefix except)\n ",
" (extract (cadr spec)))\n (else\n (or (f",
"ind-library spec) (error \"library not found\" spec))))))\n (collect\n ",
" (lambda (spec)\n (case (car spec)\n ((only)\n ",
" (let ((alist (collect (cadr spec))))\n (map (lam",
"bda (var) (assq var alist)) (cddr spec))))\n ((rename)\n ",
" (let ((alist (collect (cadr spec)))\n (renames (map (",
"lambda (x) `((car x) . (cadr x))) (cddr spec))))\n (map (lambda",
" (s) (or (assq (car s) renames) s)) alist)))\n ((prefix)\n ",
" (let ((alist (collect (cadr spec))))\n (map (lambda (s)",
" (cons (prefix (caddr spec) (car s)) (cdr s))) alist)))\n ((except",
")\n (let ((alist (collect (cadr spec))))\n (let ",
"loop ((alist alist))\n (if (null? alist)\n ",
" '()\n (if (memq (caar alist) (cddr spec))\n ",
" (loop (cdr alist))\n (cons (car al",
"ist) (loop (cdr alist))))))))\n (else\n (let ((lib ",
"(or (find-library spec) (error \"library not found\" spec))))\n (",
"map (lambda (x) (cons x x)) (library-exports lib))))))))\n (letrec\n ",
" ((import\n (lambda (spec)\n (let ((lib (extract",
" spec))\n (alist (collect spec)))\n (for-e",
"ach\n (lambda (slot)\n (library-import lib",
" (cdr slot) (car slot)))\n alist)))))\n (for-each impo",
"rt (cdr form)))))))\n\n(define-macro export\n (lambda (form _)\n (letrec\n ",
" ((collect\n (lambda (spec)\n (cond\n ((symbol? spe",
"c)\n `(,spec . ,spec))\n ((and (list? spec) (= (length sp",
"ec) 3) (eq? (car spec) 'rename))\n `(,(list-ref spec 1) . ,(list-ref",
" spec 2)))\n (else\n (error \"malformed export\")))))\n ",
" (export\n (lambda (spec)\n (let ((slot (collect spec)))\n",
" (library-export (car slot) (cdr slot))))))\n (for-each export",
" (cdr form)))))\n\n(export define lambda quote set! if begin define-macro\n ",
"let let* letrec letrec*\n let-values let*-values define-values\n qua",
"siquote unquote unquote-splicing\n and or\n cond case else =>\n ",
" do when unless\n parameterize\n define-syntax\n syntax-quote",
" syntax-unquote\n syntax-quasiquote syntax-unquote-splicing\n let-sy",
"ntax letrec-syntax\n syntax-error)\n\n\n",
"", "",
"" ""
}; };