mes.c: refactor begin and closures. Fixes bugs/top.mes.
This commit is contained in:
parent
7662a0918d
commit
711a29f4f9
12
bugs/top.mes
12
bugs/top.mes
|
@ -1,12 +0,0 @@
|
||||||
(begin (define *test-begin-a* '*test-begin-a*))
|
|
||||||
|
|
||||||
(display "defined? *test-begin-a*: ")
|
|
||||||
(display (defined? '*test-begin-a*))
|
|
||||||
(newline)
|
|
||||||
(display *test-begin-a*)
|
|
||||||
(newline)
|
|
||||||
|
|
||||||
(let () (define *test-let-a* '*test-let-a*) #f)
|
|
||||||
(display "defined? *test-let-a*: ")
|
|
||||||
(display (defined? '*test-let-a*))
|
|
||||||
(newline)
|
|
75
mes.c
75
mes.c
|
@ -81,7 +81,7 @@ scm scm_t = {SYMBOL, "#t"};
|
||||||
scm scm_f = {SYMBOL, "#f"};
|
scm scm_f = {SYMBOL, "#f"};
|
||||||
scm scm_unspecified = {SYMBOL, "*unspecified*"};
|
scm scm_unspecified = {SYMBOL, "*unspecified*"};
|
||||||
|
|
||||||
scm symbol_closure = {SYMBOL, "*lambda*"};
|
scm symbol_closure = {SYMBOL, "*closure*"};
|
||||||
scm symbol_circ = {SYMBOL, "*circ*"};
|
scm symbol_circ = {SYMBOL, "*circ*"};
|
||||||
scm symbol_lambda = {SYMBOL, "lambda"};
|
scm symbol_lambda = {SYMBOL, "lambda"};
|
||||||
scm symbol_begin = {SYMBOL, "begin"};
|
scm symbol_begin = {SYMBOL, "begin"};
|
||||||
|
@ -277,13 +277,17 @@ apply_env (scm *fn, scm *x, scm *a)
|
||||||
if (builtin_p (fn) == &scm_t)
|
if (builtin_p (fn) == &scm_t)
|
||||||
return call (fn, x);
|
return call (fn, x);
|
||||||
}
|
}
|
||||||
else if (car (fn) == &symbol_lambda)
|
else if (car (fn) == &symbol_lambda) {
|
||||||
return eval (cons (&symbol_begin, cddr (fn)), pairlis (cadr (fn), x, a));
|
scm *p = pairlis (cadr (fn), x, a);
|
||||||
|
return eval (cons (&symbol_begin, cddr (fn)), cons (cons (&symbol_closure, p), p));
|
||||||
|
}
|
||||||
else if (car (fn) == &symbol_closure) {
|
else if (car (fn) == &symbol_closure) {
|
||||||
scm *args = caddr (fn);
|
scm *args = caddr (fn);
|
||||||
scm *body = cdddr (fn);
|
scm *body = cdddr (fn);
|
||||||
a = cdadr (fn);
|
a = cdadr (fn);
|
||||||
return eval (cons (&symbol_begin, body), pairlis (args, x, a));
|
a = cdr (a);
|
||||||
|
scm *p = pairlis (args, x, a);
|
||||||
|
return eval (cons (&symbol_begin, body), cons (cons (&symbol_closure, p), p));
|
||||||
}
|
}
|
||||||
else if ((macro = lookup_macro (car (fn), a)) != &scm_f) {
|
else if ((macro = lookup_macro (car (fn), a)) != &scm_f) {
|
||||||
scm *r = apply_env (eval (macro, a), cdr (fn), a);
|
scm *r = apply_env (eval (macro, a), cdr (fn), a);
|
||||||
|
@ -303,6 +307,8 @@ eval (scm *e, scm *a)
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
printf ("\neval e=");
|
printf ("\neval e=");
|
||||||
display (e);
|
display (e);
|
||||||
|
printf ("\na=");
|
||||||
|
display (a);
|
||||||
puts ("");
|
puts ("");
|
||||||
#endif
|
#endif
|
||||||
scm *macro;
|
scm *macro;
|
||||||
|
@ -324,37 +330,15 @@ eval (scm *e, scm *a)
|
||||||
if (car (e) == &symbol_begin)
|
if (car (e) == &symbol_begin)
|
||||||
{
|
{
|
||||||
scm *body = cdr (e);
|
scm *body = cdr (e);
|
||||||
scm *defines = &scm_nil;
|
if (body == &scm_nil) return &scm_unspecified;
|
||||||
while (body != &scm_nil) {
|
|
||||||
e = car (body);
|
e = car (body);
|
||||||
body = cdr (body);
|
body = cdr (body);
|
||||||
if (e->type == PAIR
|
scm *r = eval (e, a);
|
||||||
&& (eq_p (car (e), &symbol_define) == &scm_t
|
|
||||||
|| eq_p (car (e), &symbol_define_macro) == &scm_t)) {
|
|
||||||
defines = append2 (defines, cons (def (e), &scm_nil));
|
|
||||||
e = &scm_unspecified;
|
|
||||||
}
|
|
||||||
else break;
|
|
||||||
}
|
|
||||||
a = append2 (defines, a);
|
|
||||||
while (defines != &scm_nil) {
|
|
||||||
scm *name = caar (defines);
|
|
||||||
scm *entry = assq (name, a);
|
|
||||||
scm *x = cdar (defines);
|
|
||||||
set_cdr_x (entry, cdr (define (x, a)));
|
|
||||||
// if (eq_p (car (x), &symbol_define_macro) == &scm_t)
|
|
||||||
// set_cdr_x (last_pair (a), cons (cons (name, cdr (define (x, a))), &scm_nil));
|
|
||||||
defines = cdr (defines);
|
|
||||||
}
|
|
||||||
scm *fubar = cons (&scm_dot, &scm_dot);
|
|
||||||
scm *r = eval (e, cons (fubar, a));
|
|
||||||
if (r->type == PAIR && macro_p (cdr (r)))
|
|
||||||
a = cons (r, a); // macros defining macros...
|
|
||||||
if (body == &scm_nil) return r;
|
if (body == &scm_nil) return r;
|
||||||
return eval (cons (&symbol_begin, body), a);
|
return eval (cons (&symbol_begin, body), a);
|
||||||
}
|
}
|
||||||
if (car (e) == &symbol_lambda)
|
if (car (e) == &symbol_lambda)
|
||||||
return make_closure (cadr (e), cddr (e), a);
|
return make_closure (cadr (e), cddr (e), assq (&symbol_closure, a));
|
||||||
if (car (e) == &symbol_closure)
|
if (car (e) == &symbol_closure)
|
||||||
return e;
|
return e;
|
||||||
if (car (e) == &symbol_unquote)
|
if (car (e) == &symbol_unquote)
|
||||||
|
@ -363,8 +347,8 @@ eval (scm *e, scm *a)
|
||||||
return eval_quasiquote (cadr (e), add_unquoters (a));
|
return eval_quasiquote (cadr (e), add_unquoters (a));
|
||||||
if (car (e) == &symbol_cond)
|
if (car (e) == &symbol_cond)
|
||||||
return evcon (cdr (e), a);
|
return evcon (cdr (e), a);
|
||||||
// if (eq_p (car (e), &symbol_define) == &scm_t)
|
if (eq_p (car (e), &symbol_define) == &scm_t)
|
||||||
// return define (e, a);
|
return define (e, a);
|
||||||
if (eq_p (car (e), &symbol_define_macro) == &scm_t)
|
if (eq_p (car (e), &symbol_define_macro) == &scm_t)
|
||||||
return define (e, a);
|
return define (e, a);
|
||||||
if ((macro = lookup_macro (car (e), a)) != &scm_f)
|
if ((macro = lookup_macro (car (e), a)) != &scm_f)
|
||||||
|
@ -820,6 +804,10 @@ display_helper (scm *x, bool cont, char *sep, bool quote)
|
||||||
printf ("(*circ* . #-1#)");
|
printf ("(*circ* . #-1#)");
|
||||||
return &scm_unspecified;
|
return &scm_unspecified;
|
||||||
}
|
}
|
||||||
|
if (car (x) == &symbol_closure) {
|
||||||
|
printf ("(*closure* . #-1#)");
|
||||||
|
return &scm_unspecified;
|
||||||
|
}
|
||||||
if (car (x) == &scm_quote) {
|
if (car (x) == &scm_quote) {
|
||||||
printf ("'");
|
printf ("'");
|
||||||
return display_helper (car (cdr (x)), cont, "", true);
|
return display_helper (car (cdr (x)), cont, "", true);
|
||||||
|
@ -1129,8 +1117,13 @@ mes_environment ()
|
||||||
a = cons (cons (&symbol_begin, &symbol_begin), a);
|
a = cons (cons (&symbol_begin, &symbol_begin), a);
|
||||||
a = cons (cons (&symbol_quote, &scm_quote), a);
|
a = cons (cons (&symbol_quote, &scm_quote), a);
|
||||||
|
|
||||||
|
#if MES_FULL
|
||||||
#include "environment.i"
|
#include "environment.i"
|
||||||
|
#else
|
||||||
|
a = add_environment (a, "display", &scm_display);
|
||||||
|
a = add_environment (a, "newline", &scm_newline);
|
||||||
|
#endif
|
||||||
|
a = cons (cons (&symbol_closure, a), a);
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1143,15 +1136,7 @@ make_lambda (scm *args, scm *body)
|
||||||
scm *
|
scm *
|
||||||
make_closure (scm *args, scm *body, scm *a)
|
make_closure (scm *args, scm *body, scm *a)
|
||||||
{
|
{
|
||||||
return cons (&symbol_closure, cons (cons (&symbol_circ, cdr (a)), cons (args, body)));
|
return cons (&symbol_closure, cons (cons (&symbol_circ, a), cons (args, body)));
|
||||||
}
|
|
||||||
|
|
||||||
scm *
|
|
||||||
def (scm *x)
|
|
||||||
{
|
|
||||||
if (atom_p (cadr (x)) != &scm_f)
|
|
||||||
return cons (cadr (x), x);
|
|
||||||
return cons (caadr (x), x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
scm *
|
scm *
|
||||||
|
@ -1168,7 +1153,13 @@ define (scm *x, scm *a)
|
||||||
}
|
}
|
||||||
if (eq_p (car (x), &symbol_define_macro) == &scm_t)
|
if (eq_p (car (x), &symbol_define_macro) == &scm_t)
|
||||||
e = make_macro (e);
|
e = make_macro (e);
|
||||||
return cons (name, e);
|
scm *entry = cons (name, e);
|
||||||
|
scm *aa = cons (entry, &scm_nil);
|
||||||
|
set_cdr_x (aa, cdr (a));
|
||||||
|
set_cdr_x (a, aa);
|
||||||
|
scm *cl = assq (&symbol_closure, a);
|
||||||
|
set_cdr_x (cl, aa);
|
||||||
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
scm *
|
scm *
|
||||||
|
|
30
scm.mes
30
scm.mes
|
@ -21,6 +21,15 @@
|
||||||
;; The Maxwell Equations of Software -- John McCarthy page 13
|
;; The Maxwell Equations of Software -- John McCarthy page 13
|
||||||
;; http://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf
|
;; http://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf
|
||||||
|
|
||||||
|
(define-macro (if expr then . else)
|
||||||
|
`(cond
|
||||||
|
(,expr ,then)
|
||||||
|
(#t (cond (,(pair? else) ((lambda () ,@else)))))))
|
||||||
|
|
||||||
|
(define-macro (when expr . body)
|
||||||
|
`(if ,expr
|
||||||
|
((lambda () ,@body))))
|
||||||
|
|
||||||
(define (list . rest) rest)
|
(define (list . rest) rest)
|
||||||
|
|
||||||
(define (split-params bindings params)
|
(define (split-params bindings params)
|
||||||
|
@ -109,7 +118,7 @@
|
||||||
(define (procedure? p)
|
(define (procedure? p)
|
||||||
(cond ((builtin? p) #t)
|
(cond ((builtin? p) #t)
|
||||||
((and (pair? p) (eq? (car p) 'lambda)))
|
((and (pair? p) (eq? (car p) 'lambda)))
|
||||||
((and (pair? p) (eq? (car p) '*lambda*)))
|
((and (pair? p) (eq? (car p) '*closure*)))
|
||||||
(#t #f)))
|
(#t #f)))
|
||||||
|
|
||||||
(define (assq-set! alist key val)
|
(define (assq-set! alist key val)
|
||||||
|
@ -163,15 +172,6 @@
|
||||||
(or (null? x)
|
(or (null? x)
|
||||||
(and (pair? x) (list? (cdr x)))))
|
(and (pair? x) (list? (cdr x)))))
|
||||||
|
|
||||||
(define-macro (if expr then . else)
|
|
||||||
`(cond
|
|
||||||
(,expr ,then)
|
|
||||||
(#t (cond (,(pair? else) ((lambda () ,@else)))))))
|
|
||||||
|
|
||||||
(define-macro (when expr . body)
|
|
||||||
`(if ,expr
|
|
||||||
((lambda () ,@body))))
|
|
||||||
|
|
||||||
(define (unspecified-bindings bindings params)
|
(define (unspecified-bindings bindings params)
|
||||||
(cond ((null? bindings) params)
|
(cond ((null? bindings) params)
|
||||||
(#t (unspecified-bindings
|
(#t (unspecified-bindings
|
||||||
|
@ -189,16 +189,8 @@
|
||||||
,@(letrec-setters bindings '())
|
,@(letrec-setters bindings '())
|
||||||
,@body))
|
,@body))
|
||||||
|
|
||||||
;; TODO
|
(define gensym
|
||||||
;; (define gensym
|
|
||||||
;; (let ((counter 0))
|
|
||||||
;; (lambda (. rest)
|
|
||||||
;; (let ((value (number->string counter)))
|
|
||||||
;; (set! counter (+ counter 1))
|
|
||||||
;; (string->symbol (string-append "g" value))))))
|
|
||||||
(define gensym #f)
|
|
||||||
(let ((counter 0))
|
(let ((counter 0))
|
||||||
(set! gensym
|
|
||||||
(lambda (. rest)
|
(lambda (. rest)
|
||||||
(let ((value (number->string counter)))
|
(let ((value (number->string counter)))
|
||||||
(set! counter (+ counter 1))
|
(set! counter (+ counter 1))
|
||||||
|
|
15
test.mes
15
test.mes
|
@ -22,16 +22,23 @@
|
||||||
;; http://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf
|
;; http://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf
|
||||||
|
|
||||||
;; haha, broken...lat0r
|
;; haha, broken...lat0r
|
||||||
(define result #f)
|
;; (define result #f)
|
||||||
|
;; (let ((pass 0)
|
||||||
|
;; (fail 0))
|
||||||
|
;; (set! result
|
||||||
|
;; (lambda (. t)
|
||||||
|
;; (cond ((null? t) (list pass fail))
|
||||||
|
;; ((car t) (display ": pass") (newline) (set! pass (+ pass 1)))
|
||||||
|
;; (#t (display ": fail") (newline) (set! fail (+ fail 1)))))))
|
||||||
|
(define result
|
||||||
(let ((pass 0)
|
(let ((pass 0)
|
||||||
(fail 0)
|
(fail 0))
|
||||||
(xresult #f))
|
|
||||||
(set! result
|
|
||||||
(lambda (. t)
|
(lambda (. t)
|
||||||
(cond ((null? t) (list pass fail))
|
(cond ((null? t) (list pass fail))
|
||||||
((car t) (display ": pass") (newline) (set! pass (+ pass 1)))
|
((car t) (display ": pass") (newline) (set! pass (+ pass 1)))
|
||||||
(#t (display ": fail") (newline) (set! fail (+ fail 1)))))))
|
(#t (display ": fail") (newline) (set! fail (+ fail 1)))))))
|
||||||
|
|
||||||
|
|
||||||
(define guile? (defined? 'gc))
|
(define guile? (defined? 'gc))
|
||||||
(when guile?
|
(when guile?
|
||||||
(module-define! (current-module) 'builtin? (lambda (. x) #t))
|
(module-define! (current-module) 'builtin? (lambda (. x) #t))
|
||||||
|
|
Loading…
Reference in a new issue