Merge pull request #327 from dcurrie/defect-cond
Fix cond to conform to R7RS 'If the selected ⟨clause⟩ contains only t…
This commit is contained in:
commit
5a5b5ee25c
|
@ -192,6 +192,10 @@ my $src = <<'EOL';
|
|||
(if (and (variable? (car clause))
|
||||
(variable=? (the 'else) (make-identifier (car clause) env)))
|
||||
(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))
|
||||
(variable=? (the '=>) (make-identifier (cadr clause) env)))
|
||||
(let ((tmp (make-identifier 'tmp here)))
|
||||
|
@ -201,7 +205,7 @@ my $src = <<'EOL';
|
|||
(cons (the 'cond) (cdr clauses)))))
|
||||
(list the-if (car clause)
|
||||
(cons the-begin (cdr clause))
|
||||
(cons (the 'cond) (cdr clauses))))))))))
|
||||
(cons (the 'cond) (cdr clauses)))))))))))
|
||||
|
||||
(define-macro quasiquote
|
||||
(lambda (form env)
|
||||
|
@ -788,220 +792,224 @@ const char pic_boot[][80] = {
|
|||
"\n (if (null? clauses)\n #undefined\n (let ((clause (car cla",
|
||||
"uses)))\n (if (and (variable? (car clause))\n (vari",
|
||||
"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 ",
|
||||
" (let ((tmp (make-identifier 'tmp here)))\n ",
|
||||
" (list (the 'let) (list (list tmp (car clause)))\n (li",
|
||||
"st the-if tmp\n (list (car (cddr clause)) tmp)\n ",
|
||||
" (cons (the 'cond) (cdr clauses)))))\n ",
|
||||
" (list the-if (car clause)\n (cons the-begin (cd",
|
||||
"r clause))\n (cons (the 'cond) (cdr clauses))))))))))\n\n(",
|
||||
"define-macro quasiquote\n (lambda (form env)\n\n (define (quasiquote? form)\n ",
|
||||
" (and (pair? form)\n (variable? (car form))\n (variable=? (t",
|
||||
"he 'quasiquote) (make-identifier (car form) env))))\n\n (define (unquote? form)",
|
||||
"\n (and (pair? form)\n (variable? (car form))\n (variable=",
|
||||
"? (the 'unquote) (make-identifier (car form) env))))\n\n (define (unquote-splic",
|
||||
"ing? form)\n (and (pair? form)\n (pair? (car form))\n (var",
|
||||
"iable? (caar form))\n (variable=? (the 'unquote-splicing) (make-identif",
|
||||
"ier (caar form) env))))\n\n (define (qq depth expr)\n (cond\n ;; unquo",
|
||||
"te\n ((unquote? expr)\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-spli",
|
||||
"cing\n ((unquote-splicing? expr)\n (if (= depth 1)\n (list ",
|
||||
"(the 'append)\n (car (cdr (car expr)))\n (qq dep",
|
||||
"th (cdr expr)))\n (list (the 'cons)\n (list (the 'list",
|
||||
")\n (list (the 'quote) (the 'unquote-splicing))\n ",
|
||||
" (qq (- depth 1) (car (cdr (car expr)))))\n (qq dep",
|
||||
"th (cdr expr)))))\n ;; quasiquote\n ((quasiquote? expr)\n (list ",
|
||||
"(the 'list)\n (list (the 'quote) (the 'quasiquote))\n (q",
|
||||
"q (+ depth 1) (car (cdr expr)))))\n ;; list\n ((pair? expr)\n (l",
|
||||
"ist (the 'cons)\n (qq depth (car expr))\n (qq depth (cdr",
|
||||
" expr))))\n ;; vector\n ((vector? expr)\n (list (the 'list->vect",
|
||||
"or) (qq depth (vector->list expr))))\n ;; simple datum\n (else\n ",
|
||||
" (list (the 'quote) expr))))\n\n (let ((x (cadr form)))\n (qq 1 x))))\n\n(def",
|
||||
"ine-macro let*\n (lambda (form env)\n (let ((bindings (car (cdr form)))\n ",
|
||||
" (body (cdr (cdr form))))\n (if (null? bindings)\n `(,(the 'l",
|
||||
"et) () ,@body)\n `(,(the 'let) ((,(car (car bindings)) ,@(cdr (car bindi",
|
||||
"ngs))))\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 bindings)))\n (initials (map (lambda (v) `(,(the ",
|
||||
"'set!) ,@v)) bindings)))\n `(,(the 'let) (,@variables)\n ,@initial",
|
||||
"s\n ,@body)))))\n\n(define-macro let-values\n (lambda (form env)\n `(,(t",
|
||||
"he 'let*-values) ,@(cdr form))))\n\n(define-macro let*-values\n (lambda (form env)",
|
||||
"\n (let ((formal (car (cdr form)))\n (body (cdr (cdr form))))\n ",
|
||||
"(if (null? formal)\n `(,(the 'let) () ,@body)\n `(,(the 'call-wi",
|
||||
"th-values) (,the-lambda () ,@(cdr (car formal)))\n (,(the 'lambda) (,@",
|
||||
"(car (car formal)))\n (,(the 'let*-values) (,@(cdr formal))\n ",
|
||||
" ,@body)))))))\n\n(define-macro define-values\n (lambda (form env)\n (let ((",
|
||||
"formal (car (cdr form)))\n (body (cdr (cdr form))))\n (let ((argum",
|
||||
"ents (make-identifier 'arguments here)))\n `(,the-begin\n ,@(let l",
|
||||
"oop ((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 () ,@b",
|
||||
"ody)\n (,the-lambda\n ,arguments\n ,@(let loop ((fo",
|
||||
"rmal formal) (args arguments))\n (if (pair? formal)\n ",
|
||||
" `((,the-set! ,(car formal) (,(the 'car) ,args)) ,@(loop (cdr formal) `(,(t",
|
||||
"he 'cdr) ,args)))\n (if (variable? formal)\n ",
|
||||
" `((,the-set! ,formal ,args))\n '()))))))))))\n\n(define",
|
||||
"-macro do\n (lambda (form env)\n (let ((bindings (car (cdr form)))\n (",
|
||||
"test (car (car (cdr (cdr form)))))\n (cleanup (cdr (car (cdr (cdr f",
|
||||
"orm)))))\n (body (cdr (cdr (cdr form)))))\n (let ((loop (make-id",
|
||||
"entifier 'loop here)))\n `(,(the 'let) ,loop ,(map (lambda (x) `(,(car x) ",
|
||||
",(cadr x))) bindings)\n (,the-if ,test\n (,the-begin\n ",
|
||||
" ,@cleanup)\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 (fo",
|
||||
"rm env)\n (let ((test (car (cdr form)))\n (body (cdr (cdr form))))\n ",
|
||||
" `(,the-if ,test\n (,the-begin ,@body)\n #undefine",
|
||||
"d))))\n\n(define-macro unless\n (lambda (form env)\n (let ((test (car (cdr form)",
|
||||
"))\n (body (cdr (cdr form))))\n `(,the-if ,test\n #und",
|
||||
"efined\n (,the-begin ,@body)))))\n\n(define-macro case\n (lambda (fo",
|
||||
"rm env)\n (let ((key (car (cdr form)))\n (clauses (cdr (cdr form))",
|
||||
"))\n (let ((the-key (make-identifier 'key here)))\n `(,(the 'let) ((,t",
|
||||
"he-key ,key))\n ,(let loop ((clauses clauses))\n (if (null? c",
|
||||
"lauses)\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 (lambda (x) `(,(the 'eqv?) ,the-key (,the-quote ,x))) (car cla",
|
||||
"use))))\n ,(if (and (variable? (cadr clause))\n ",
|
||||
" (variable=? (the '=>) (make-identifier (cadr cla",
|
||||
"use) env)))\n `(,(car (cdr (cdr clause))) ,the-k",
|
||||
"ey)\n `(,the-begin ,@(cdr clause)))\n ",
|
||||
" ,(loop (cdr clauses)))))))))))\n\n(define-macro parameterize\n (l",
|
||||
"ambda (form env)\n (let ((formal (car (cdr form)))\n (body (cdr (cdr",
|
||||
" form))))\n `(,(the 'with-parameter)\n (,(the 'lambda) ()\n ,@f",
|
||||
"ormal\n ,@body)))))\n\n(define-macro syntax-quote\n (lambda (form env)\n ",
|
||||
"(let ((renames '()))\n (letrec\n ((rename (lambda (var)\n ",
|
||||
" (let ((x (assq var renames)))\n (if x\n ",
|
||||
" (cadr x)\n (begin\n ",
|
||||
" (set! renames `((,var ,(make-identifier var env) (,(the 'make-identifier)",
|
||||
" ',var ',env)) . ,renames))\n (rename var))))))\n ",
|
||||
" (walk (lambda (f form)\n (cond\n ((vari",
|
||||
"able? form)\n (f form))\n ((pair? form)\n ",
|
||||
" `(,(the 'cons) (walk f (car form)) (walk f (cdr form))))\n ",
|
||||
" ((vector? form)\n `(,(the 'list->vector) (walk",
|
||||
" f (vector->list form))))\n (else\n `(,(the",
|
||||
" 'quote) ,form))))))\n (let ((form (walk rename (cadr form))))\n `",
|
||||
"(,(the 'let)\n ,(map cdr renames)\n ,form))))))\n\n(define-mac",
|
||||
"ro syntax-quasiquote\n (lambda (form env)\n (let ((renames '()))\n (letrec",
|
||||
"\n ((rename (lambda (var)\n (let ((x (assq var rename",
|
||||
"s)))\n (if x\n (cadr x)\n ",
|
||||
" (begin\n (set! renames `((,var ,(mak",
|
||||
"e-identifier var env) (,(the 'make-identifier) ',var ',env)) . ,renames))\n ",
|
||||
" (rename var)))))))\n\n (define (syntax-quasiquote? f",
|
||||
"orm)\n (and (pair? form)\n (variable? (car form))\n ",
|
||||
" (variable=? (the 'syntax-quasiquote) (make-identifier (car form) env))))\n\n",
|
||||
" (define (syntax-unquote? form)\n (and (pair? form)\n ",
|
||||
" (variable? (car form))\n (variable=? (the 'syntax-unquote) (make-",
|
||||
"identifier (car form) env))))\n\n (define (syntax-unquote-splicing? form)\n ",
|
||||
" (and (pair? form)\n (pair? (car form))\n (var",
|
||||
"iable? (caar form))\n (variable=? (the 'syntax-unquote-splicing) (m",
|
||||
"ake-identifier (caar form) env))))\n\n (define (qq depth expr)\n (c",
|
||||
"ond\n ;; syntax-unquote\n ((syntax-unquote? expr)\n ",
|
||||
"(if (= depth 1)\n (car (cdr expr))\n (list (the 'lis",
|
||||
"t)\n (list (the 'quote) (the 'syntax-unquote))\n ",
|
||||
" (qq (- depth 1) (car (cdr expr))))))\n ;; syntax-unquote-splic",
|
||||
"ing\n ((syntax-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 'quot",
|
||||
"e) (the 'syntax-unquote-splicing))\n (qq (- depth 1) (",
|
||||
"car (cdr (car expr)))))\n (qq depth (cdr expr)))))\n ",
|
||||
" ;; syntax-quasiquote\n ((syntax-quasiquote? expr)\n (list (",
|
||||
"the 'list)\n (list (the 'quote) (the 'quasiquote))\n ",
|
||||
" (qq (+ depth 1) (car (cdr expr)))))\n ;; list\n ((pair? e",
|
||||
"xpr)\n (list (the 'cons)\n (qq depth (car expr))\n ",
|
||||
" (qq depth (cdr expr))))\n ;; vector\n ((vector? e",
|
||||
"xpr)\n (list (the 'list->vector) (qq depth (vector->list expr))))\n ",
|
||||
" ;; variable\n ((variable? expr)\n (rename expr))\n ",
|
||||
" ;; simple datum\n (else\n (list (the 'quote) expr))))\n\n",
|
||||
" (let ((body (qq 1 (cadr form))))\n `(,(the 'let)\n ,(m",
|
||||
"ap cdr renames)\n ,body))))))\n\n(define (transformer f)\n (lambda (form",
|
||||
" env)\n (let ((register1 (make-register))\n (register2 (make-register)",
|
||||
"))\n (letrec\n ((wrap (lambda (var1)\n (let ((var2 ",
|
||||
"(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",
|
||||
" `(,(car (cdr (cdr clause))) ,the-key)\n ",
|
||||
" `(,the-begin ,@(cdr clause)))\n ,(loo",
|
||||
"p (cdr clauses)))))))))))\n\n(define-macro parameterize\n (lambda (form env)\n (",
|
||||
"let ((formal (car (cdr form)))\n (body (cdr (cdr form))))\n `(,(th",
|
||||
"e 'with-parameter)\n (,(the 'lambda) ()\n ,@formal\n ,@body)",
|
||||
"))))\n\n(define-macro syntax-quote\n (lambda (form env)\n (let ((renames '()))\n ",
|
||||
" (letrec\n ((rename (lambda (var)\n (let ((x (ass",
|
||||
"q var renames)))\n (if x\n (cadr x",
|
||||
")\n (begin\n (set! renames `",
|
||||
"((,var ,(make-identifier var env) (,(the 'make-identifier) ',var ',env)) . ,rena",
|
||||
"mes))\n (rename var))))))\n (walk (lambda (f",
|
||||
" form)\n (cond\n ((variable? form)\n ",
|
||||
" (f form))\n ((pair? form)\n `(,(",
|
||||
"the 'cons) (walk f (car form)) (walk f (cdr form))))\n ((vecto",
|
||||
"r? form)\n `(,(the 'list->vector) (walk f (vector->list form)",
|
||||
")))\n (else\n `(,(the 'quote) ,form))))))\n ",
|
||||
" (let ((form (walk rename (cadr form))))\n `(,(the 'let)\n ",
|
||||
" ,(map cdr renames)\n ,form))))))\n\n(define-macro syntax-quasiquote\n ",
|
||||
" (lambda (form env)\n (let ((renames '()))\n (letrec\n ((rename (l",
|
||||
"ambda (var)\n (let ((x (assq var renames)))\n ",
|
||||
" (if x\n (cadr x)\n (begi",
|
||||
"n\n (set! renames `((,var ,(make-identifier var env) ",
|
||||
"(,(the 'make-identifier) ',var ',env)) . ,renames))\n ",
|
||||
" (rename var)))))))\n\n (define (syntax-quasiquote? form)\n (and (p",
|
||||
"air? form)\n (variable? (car form))\n (variable=? (the",
|
||||
" 'syntax-quasiquote) (make-identifier (car form) env))))\n\n (define (synta",
|
||||
"x-unquote? form)\n (and (pair? form)\n (variable? (car form",
|
||||
"))\n (variable=? (the 'syntax-unquote) (make-identifier (car form) ",
|
||||
"env))))\n\n (define (syntax-unquote-splicing? form)\n (and (pair? f",
|
||||
"orm)\n (pair? (car form))\n (variable? (caar form))\n ",
|
||||
" (variable=? (the 'syntax-unquote-splicing) (make-identifier (caar f",
|
||||
"orm) env))))\n\n (define (qq depth expr)\n (cond\n ;; synt",
|
||||
"ax-unquote\n ((syntax-unquote? expr)\n (if (= depth 1)\n ",
|
||||
" (car (cdr expr))\n (list (the 'list)\n ",
|
||||
" (list (the 'quote) (the 'syntax-unquote))\n (qq (- depth ",
|
||||
"1) (car (cdr expr))))))\n ;; syntax-unquote-splicing\n ((synta",
|
||||
"x-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 (lis",
|
||||
"t (the 'list)\n (list (the 'quote) (the 'syntax-unquot",
|
||||
"e-splicing))\n (qq (- depth 1) (car (cdr (car expr))))",
|
||||
")\n (qq depth (cdr expr)))))\n ;; syntax-quasiquote",
|
||||
"\n ((syntax-quasiquote? expr)\n (list (the 'list)\n ",
|
||||
" (list (the 'quote) (the 'quasiquote))\n (qq (+ depth 1) (",
|
||||
"car (cdr expr)))))\n ;; list\n ((pair? expr)\n (list",
|
||||
" (the 'cons)\n (qq depth (car expr))\n (qq depth",
|
||||
" (cdr expr))))\n ;; vector\n ((vector? expr)\n (list",
|
||||
" (the 'list->vector) (qq depth (vector->list expr))))\n ;; variable\n ",
|
||||
" ((variable? expr)\n (rename expr))\n ;; simple datum\n",
|
||||
" (else\n (list (the 'quote) expr))))\n\n (let ((body (q",
|
||||
"q 1 (cadr form))))\n `(,(the 'let)\n ,(map cdr renames)\n ",
|
||||
" ,body))))))\n\n(define (transformer f)\n (lambda (form env)\n (let ((regis",
|
||||
"ter1 (make-register))\n (register2 (make-register)))\n (letrec\n ",
|
||||
" ((wrap (lambda (var1)\n (let ((var2 (register1 var1)))\n ",
|
||||
" (if var2\n (cdr var2)\n ",
|
||||
" (let ((var2 (make-identifier var1 env)))\n (reg",
|
||||
"ister1 var1 var2)\n (register2 var2 var1)\n ",
|
||||
" var2)))))\n (unwrap (lambda (var2)\n (",
|
||||
"let ((var1 (register2 var2)))\n (if var1\n ",
|
||||
" (cdr var1)\n var2))))\n (walk (lambda",
|
||||
" (f form)\n (cond\n ((variable? form)\n ",
|
||||
" (f form))\n ((pair? form)\n (",
|
||||
"cons (walk f (car form)) (walk f (cdr form))))\n ((vector? for",
|
||||
"m)\n (list->vector (walk f (vector->list form))))\n ",
|
||||
" (else\n form)))))\n (let ((form (cdr form)))\n ",
|
||||
" (walk unwrap (apply f (walk wrap form))))))))\n\n(define-macro define-syn",
|
||||
"tax\n (lambda (form env)\n (let ((formal (car (cdr form)))\n (body (",
|
||||
"cdr (cdr form))))\n (if (pair? formal)\n `(,(the 'define-syntax) ,(c",
|
||||
"ar formal) (,the-lambda ,(cdr formal) ,@body))\n `(,the-define-macro ,fo",
|
||||
"rmal (,(the 'transformer) (,the-begin ,@body)))))))\n\n(define-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 formal)\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 define-library\n (lambda",
|
||||
" (form _)\n (let ((name (cadr form))\n (body (cddr form)))\n (let ",
|
||||
"((old-library (current-library))\n (new-library (or (find-library name",
|
||||
") (make-library name))))\n (let ((env (library-environment new-library)))\n",
|
||||
" (current-library new-library)\n (for-each (lambda (expr) (eval",
|
||||
" expr env)) body)\n (current-library old-library))))))\n\n(define-macro co",
|
||||
"nd-expand\n (lambda (form _)\n (letrec\n ((test (lambda (form)\n ",
|
||||
" (or\n (eq? form 'else)\n (and (symbol? f",
|
||||
"orm)\n (memq form (features)))\n (and (pair",
|
||||
"? form)\n (case (car form)\n ((libra",
|
||||
"ry) (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) (le",
|
||||
"t 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 c",
|
||||
"lauses))\n `(,the-begin ,@(cdar clauses))\n (loop (c",
|
||||
"dr clauses))))))))\n\n(define-macro import\n (lambda (form _)\n (let ((caddr\n ",
|
||||
" (lambda (x) (car (cdr (cdr x)))))\n (prefix\n (lambda (",
|
||||
"prefix symbol)\n (string->symbol\n (string-append\n ",
|
||||
" (symbol->string prefix)\n (symbol->string symbol))))))\n ",
|
||||
" (letrec\n ((extract\n (lambda (spec)\n (case (ca",
|
||||
"r spec)\n ((only rename prefix except)\n (extract (",
|
||||
"cadr spec)))\n (else\n (or (find-library spec) (err",
|
||||
"or \"library not found\" spec))))))\n (collect\n (lambda (spec)",
|
||||
"\n (case (car spec)\n ((only)\n (let ((",
|
||||
"alist (collect (cadr spec))))\n (map (lambda (var) (assq var al",
|
||||
"ist)) (cddr spec))))\n ((rename)\n (let ((alist (co",
|
||||
"llect (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 (le",
|
||||
"t ((alist (collect (cadr spec))))\n (let loop ((alist alist))\n ",
|
||||
" (if (null? alist)\n '()\n ",
|
||||
" (if (memq (caar alist) (cddr spec))\n (lo",
|
||||
"op (cdr alist))\n (cons (car alist) (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-each\n ",
|
||||
" (lambda (slot)\n (library-import lib (cdr slot) (car slot)",
|
||||
"))\n alist)))))\n (for-each import (cdr form)))))))\n\n(",
|
||||
"define-macro export\n (lambda (form _)\n (letrec\n ((collect\n (",
|
||||
"lambda (spec)\n (cond\n ((symbol? spec)\n `(,sp",
|
||||
"ec . ,spec))\n ((and (list? spec) (= (length spec) 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 (librar",
|
||||
"y-export (car slot) (cdr slot))))))\n (for-each export (cdr form)))))\n\n(expo",
|
||||
"rt define lambda quote set! if begin define-macro\n let let* letrec letrec",
|
||||
"*\n let-values let*-values define-values\n quasiquote unquote unquot",
|
||||
"e-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-syntax letrec-syntax\n ",
|
||||
" syntax-error)\n\n\n",
|
||||
"",
|
||||
""
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue