[bugfix] make-parameter is broken

This commit is contained in:
Yuichi Nishiwaki 2016-02-23 20:50:26 +09:00
parent 4c6fe54d34
commit 34331dad6f
12 changed files with 207 additions and 221 deletions

View File

@ -26,8 +26,6 @@ struct fullcont {
struct code *ip;
pic_value ptable;
struct object **arena;
size_t arena_size, arena_idx;
@ -89,9 +87,6 @@ cont_mark(pic_state *pic, void *data, void (*mark)(pic_state *, pic_value))
for (i = 0; i < cont->arena_idx; ++i) {
mark(pic, pic_obj_value(cont->arena[i]));
}
/* parameter table */
mark(pic, cont->ptable);
}
static const pic_data_type cont_type = { "continuation", cont_dtor, cont_mark };
@ -151,8 +146,6 @@ save_cont(pic_state *pic, struct fullcont **c)
cont->ip = pic->ip;
cont->ptable = pic->ptable;
cont->arena_idx = pic->arena_idx;
cont->arena_size = pic->arena_size;
cont->arena = pic_malloc(pic, sizeof(struct object *) * pic->arena_size);
@ -204,8 +197,6 @@ restore_cont(pic_state *pic, struct fullcont *cont)
pic->ip = cont->ip;
pic->ptable = cont->ptable;
assert(pic->arena_size >= cont->arena_size);
memcpy(pic->arena, cont->arena, sizeof(struct object *) * cont->arena_size);
pic->arena_size = cont->arena_size;

View File

@ -382,10 +382,11 @@ my $src = <<'EOL';
(lambda (form env)
(let ((formal (car (cdr form)))
(body (cdr (cdr form))))
`(,(the 'with-parameter)
(,(the 'lambda) ()
,@formal
,@body)))))
(if (null? formal)
`(,the-begin ,@body)
(let ((bind (car formal)))
`(,(the 'dynamic-bind) ,(car bind) ,(cadr bind)
(,the-lambda () (,(the 'parameterize) ,(cdr formal) ,@body))))))))
(define-macro syntax-quote
(lambda (form env)
@ -894,138 +895,140 @@ const char pic_boot[][80] = {
" (cdr clause))) ,the-key)\n `(,the-begin ,@(cdr ",
"clause)))\n ,(loop (cdr clauses)))))))))))\n\n(define-m",
"acro parameterize\n (lambda (form env)\n (let ((formal (car (cdr form)))\n ",
" (body (cdr (cdr form))))\n `(,(the 'with-parameter)\n (,(the 'l",
"ambda) ()\n ,@formal\n ,@body)))))\n\n(define-macro syntax-quote\n (",
"lambda (form env)\n (let ((renames '()))\n (letrec\n ((rename (lam",
"bda (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 ",
" ((identifier? form)\n (f form))\n ",
" ((pair? form)\n `(,(the 'cons) (walk f (car form)) (wa",
"lk 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 (c",
"adr form))))\n `(,(the 'let)\n ,(map cdr renames)\n ",
",form))))))\n\n(define-macro syntax-quasiquote\n (lambda (form env)\n (let ((ren",
"ames '()))\n (letrec\n ((rename (lambda (var)\n (",
"let ((x (assq var renames)))\n (if x\n ",
" (cadr x)\n (begin\n (se",
"t! renames `((,var ,(make-identifier var env) (,(the 'make-identifier) ',var ',e",
"nv)) . ,renames))\n (rename var)))))))\n\n (defi",
"ne (syntax-quasiquote? form)\n (and (pair? form)\n (identif",
"ier? (car form))\n (identifier=? (the 'syntax-quasiquote) (make-ide",
"ntifier (car form) env))))\n\n (define (syntax-unquote? form)\n (an",
"d (pair? form)\n (identifier? (car form))\n (identifie",
"r=? (the 'syntax-unquote) (make-identifier (car form) env))))\n\n (define (",
"syntax-unquote-splicing? form)\n (and (pair? form)\n (pair?",
" (car form))\n (identifier? (caar form))\n (identifier",
"=? (the 'syntax-unquote-splicing) (make-identifier (caar form) env))))\n\n ",
"(define (qq depth expr)\n (cond\n ;; syntax-unquote\n ",
"((syntax-unquote? expr)\n (if (= depth 1)\n (car (cdr ex",
"pr))\n (list (the 'list)\n (list (the 'quote) ",
"(the 'syntax-unquote))\n (qq (- depth 1) (car (cdr expr)))))",
")\n ;; syntax-unquote-splicing\n ((syntax-unquote-splicing? ex",
"pr)\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 'syntax-unquote-splicing))\n ",
" (qq (- depth 1) (car (cdr (car expr)))))\n ",
" (qq depth (cdr expr)))))\n ;; syntax-quasiquote\n ((syntax-q",
"uasiquote? expr)\n (list (the 'list)\n (list (the 'quo",
"te) (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 ;; identifier\n ((identifier",
"? 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 ,(map cdr renames)\n ,body))))))\n",
"\n(define (transformer f)\n (lambda (form env)\n (let ((ephemeron1 (make-epheme",
"ron))\n (ephemeron2 (make-ephemeron)))\n (letrec\n ((wrap (l",
"ambda (var1)\n (let ((var2 (ephemeron1 var1)))\n ",
" (if var2\n (cdr var2)\n (let ",
"((var2 (make-identifier var1 env)))\n (ephemeron1 var1 ",
"var2)\n (ephemeron2 var2 var1)\n ",
" var2)))))\n (unwrap (lambda (var2)\n (let ((var1 ",
"(ephemeron2 var2)))\n (if var1\n (",
"cdr var1)\n var2))))\n (walk (lambda (f form)\n",
" (cond\n ((identifier? form)\n ",
" (f form))\n ((pair? form)\n (cons (wa",
"lk f (car form)) (walk f (cdr form))))\n ((vector? form)\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-syntax\n (l",
"ambda (form env)\n (let ((formal (car (cdr form)))\n (body (cdr (cdr",
" form))))\n (if (pair? formal)\n `(,(the 'define-syntax) ,(car forma",
"l) (,the-lambda ,(cdr formal) ,@body))\n `(,the-define-macro ,formal (,(",
"the 'transformer) (,the-begin ,@body)))))))\n\n(define-macro letrec-syntax\n (lamb",
"da (form env)\n (let ((formal (car (cdr form)))\n (body (cdr (cdr fo",
"rm))))\n `(let ()\n ,@(map (lambda (x)\n `(,(the 'def",
"ine-syntax) ,(car x) ,(cadr x)))\n formal)\n ,@body))))\n\n(d",
"efine-macro let-syntax\n (lambda (form env)\n `(,(the 'letrec-syntax) ,@(cdr f",
"orm))))\n\n\n;;; library primitives\n\n(define (mangle name)\n (define (->string n)\n ",
" (if (symbol? n)\n (symbol->string n)\n (number->string n)))\n (de",
"fine (join strs delim)\n (let loop ((res (car strs)) (strs (cdr strs)))\n ",
"(if (null? strs)\n res\n (loop (string-append res delim (car str",
"s)) (cdr strs)))))\n (join (map ->string name) \".\"))\n\n(define-macro define-libra",
"ry\n (lambda (form _)\n (let ((lib (mangle (cadr form)))\n (body (cddr",
" form)))\n (or (find-library lib) (make-library lib))\n (for-each (lambd",
"a (expr) (eval expr lib)) body))))\n\n(define-macro cond-expand\n (lambda (form _)",
"\n (letrec\n ((test (lambda (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 (mangle (c",
"adr form))))\n ((not) (not (test (cadr form))))\n ",
" ((and) (let loop ((form (cdr form)))\n ",
" (or (null? form)\n (and (test (car fo",
"rm)) (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 (prefix\n (lambda (prefix symbol)\n ",
" (string->symbol\n (string-append\n (symbol->st",
"ring prefix)\n (symbol->string symbol)))))\n (getlib\n ",
" (lambda (name)\n (let ((lib (mangle name)))\n (if (",
"find-library lib)\n lib\n (error \"library not ",
"found\" name))))))\n (letrec\n ((extract\n (lambda (spec)\n ",
" (case (car spec)\n ((only rename prefix except)\n ",
" (extract (cadr spec)))\n (else\n (getli",
"b spec)))))\n (collect\n (lambda (spec)\n (case (",
"car spec)\n ((only)\n (let ((alist (collect (cadr s",
"pec))))\n (map (lambda (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 (ca",
"dr spec))))\n (let loop ((alist alist))\n (i",
"f (null? alist)\n '()\n (if (memq ",
"(caar alist) (cddr spec))\n (loop (cdr alist))\n ",
" (cons (car alist) (loop (cdr alist))))))))\n ",
" (else\n (map (lambda (x) (cons x x)) (library-exports (getlib s",
"pec))))))))\n (letrec\n ((import\n (lambda (spec)\n ",
" (let ((lib (extract spec))\n (alist (collec",
"t 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 `(,spec . ,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 (library-export (car slot) (cd",
"r 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 le",
"t*-values define-values\n quasiquote 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 syn",
"tax-unquote-splicing\n let-syntax letrec-syntax\n syntax-error)\n\n\n",
" (body (cdr (cdr form))))\n (if (null? formal)\n `(,the-begin ",
",@body)\n (let ((bind (car formal)))\n `(,(the 'dynamic-bind) ",
",(car bind) ,(cadr bind)\n (,the-lambda () (,(the 'parameterize) ,(c",
"dr formal) ,@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 ((ident",
"ifier? 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) (wal",
"k f (vector->list form))))\n (else\n `(,(th",
"e 'quote) ,form))))))\n (let ((form (walk rename (cadr form))))\n ",
"`(,(the 'let)\n ,(map cdr renames)\n ,form))))))\n\n(define-ma",
"cro syntax-quasiquote\n (lambda (form env)\n (let ((renames '()))\n (letre",
"c\n ((rename (lambda (var)\n (let ((x (assq var renam",
"es)))\n (if x\n (cadr x)\n ",
" (begin\n (set! renames `((,var ,(ma",
"ke-identifier var env) (,(the 'make-identifier) ',var ',env)) . ,renames))\n ",
" (rename var)))))))\n\n (define (syntax-quasiquote? ",
"form)\n (and (pair? form)\n (identifier? (car form))\n ",
" (identifier=? (the 'syntax-quasiquote) (make-identifier (car form) env)",
")))\n\n (define (syntax-unquote? form)\n (and (pair? form)\n ",
" (identifier? (car form))\n (identifier=? (the 'syntax-unquot",
"e) (make-identifier (car form) env))))\n\n (define (syntax-unquote-splicing",
"? form)\n (and (pair? form)\n (pair? (car form))\n ",
" (identifier? (caar form))\n (identifier=? (the 'syntax-unquote",
"-splicing) (make-identifier (caar form) env))))\n\n (define (qq depth expr)",
"\n (cond\n ;; syntax-unquote\n ((syntax-unquote? expr)",
"\n (if (= depth 1)\n (car (cdr expr))\n (l",
"ist (the 'list)\n (list (the 'quote) (the 'syntax-unquote))\n",
" (qq (- depth 1) (car (cdr expr))))))\n ;; syntax-",
"unquote-splicing\n ((syntax-unquote-splicing? expr)\n (if (= ",
"depth 1)\n (list (the 'append)\n (car (cdr (ca",
"r expr)))\n (qq depth (cdr expr)))\n (list (th",
"e 'cons)\n (list (the 'list)\n (li",
"st (the 'quote) (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? 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 ;; identifier\n ((identifier? expr)\n (re",
"name expr))\n ;; simple datum\n (else\n (list (the '",
"quote) expr))))\n\n (let ((body (qq 1 (cadr form))))\n `(,(the 'let",
")\n ,(map cdr renames)\n ,body))))))\n\n(define (transformer f",
")\n (lambda (form env)\n (let ((ephemeron1 (make-ephemeron))\n (epheme",
"ron2 (make-ephemeron)))\n (letrec\n ((wrap (lambda (var1)\n ",
" (let ((var2 (ephemeron1 var1)))\n (if var2\n ",
" (cdr var2)\n (let ((var2 (make-identifier",
" var1 env)))\n (ephemeron1 var1 var2)\n ",
" (ephemeron2 var2 var1)\n var2)))))\n ",
" (unwrap (lambda (var2)\n (let ((var1 (ephemeron2 var2)))\n ",
" (if var1\n (cdr var1)\n ",
" var2))))\n (walk (lambda (f form)\n (con",
"d\n ((identifier? 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->list form))))\n (else\n ",
" form)))))\n (let ((form (cdr form)))\n (walk unwrap (apply f ",
"(walk wrap form))))))))\n\n(define-macro define-syntax\n (lambda (form env)\n (l",
"et ((formal (car (cdr form)))\n (body (cdr (cdr form))))\n (if (pa",
"ir? formal)\n `(,(the 'define-syntax) ,(car formal) (,the-lambda ,(cdr f",
"ormal) ,@body))\n `(,the-define-macro ,formal (,(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 p",
"rimitives\n\n(define (mangle name)\n (define (->string n)\n (if (symbol? n)\n ",
" (symbol->string n)\n (number->string n)))\n (define (join strs delim)\n",
" (let loop ((res (car strs)) (strs (cdr strs)))\n (if (null? strs)\n ",
" res\n (loop (string-append res delim (car strs)) (cdr strs)))))\n (j",
"oin (map ->string name) \".\"))\n\n(define-macro define-library\n (lambda (form _)\n ",
" (let ((lib (mangle (cadr form)))\n (body (cddr form)))\n (or (fin",
"d-library lib) (make-library lib))\n (for-each (lambda (expr) (eval expr lib",
")) body))))\n\n(define-macro cond-expand\n (lambda (form _)\n (letrec\n ((",
"test (lambda (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 (mangle (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 (t",
"est (car form)) (loop (cdr form))))))\n (else #f)))))))\n ",
" (let loop ((clauses (cdr form)))\n (if (null? clauses)\n #u",
"ndefined\n (if (test (caar clauses))\n `(,the-begin ,@(c",
"dar clauses))\n (loop (cdr 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->symbo",
"l\n (string-append\n (symbol->string prefix)\n ",
" (symbol->string symbol)))))\n (getlib\n (lambda (name)\n ",
" (let ((lib (mangle name)))\n (if (find-library lib)\n ",
" lib\n (error \"library not found\" name))))))\n ",
" (letrec\n ((extract\n (lambda (spec)\n (case (car",
" spec)\n ((only rename prefix except)\n (extract (c",
"adr spec)))\n (else\n (getlib spec)))))\n ",
"(collect\n (lambda (spec)\n (case (car spec)\n ",
" ((only)\n (let ((alist (collect (cadr spec))))\n ",
" (map (lambda (var) (assq var alist)) (cddr spec))))\n ((rename",
")\n (let ((alist (collect (cadr spec)))\n (r",
"enames (map (lambda (x) `((car x) . (cadr x))) (cddr spec))))\n ",
" (map (lambda (s) (or (assq (car s) renames) s)) alist)))\n ((pref",
"ix)\n (let ((alist (collect (cadr spec))))\n (ma",
"p (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 alist) (loop (cdr alist))))))))\n (else\n ",
" (map (lambda (x) (cons x x)) (library-exports (getlib spec))))))))\n (le",
"trec\n ((import\n (lambda (spec)\n (let ((",
"lib (extract spec))\n (alist (collect spec)))\n ",
" (for-each\n (lambda (slot)\n (librar",
"y-import lib (cdr slot) (car slot)))\n alist)))))\n (f",
"or-each import (cdr form)))))))\n\n(define-macro export\n (lambda (form _)\n (le",
"trec\n ((collect\n (lambda (spec)\n (cond\n (",
"(symbol? spec)\n `(,spec . ,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 (coll",
"ect spec)))\n (library-export (car slot) (cdr slot))))))\n (for",
"-each export (cdr form)))))\n\n(export define lambda quote set! if begin define-ma",
"cro\n let let* letrec letrec*\n let-values let*-values define-values",
"\n quasiquote unquote unquote-splicing\n and or\n cond case el",
"se =>\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",
"",
""
};

View File

@ -16,7 +16,6 @@ struct pic_cont {
ptrdiff_t ci_offset;
ptrdiff_t xp_offset;
size_t arena_idx;
pic_value ptable;
struct code *ip;
int retc;
@ -39,7 +38,6 @@ pic_save_point(pic_state *pic, struct pic_cont *cont, PIC_JMPBUF *jmp)
cont->xp_offset = pic->xp - pic->xpbase;
cont->arena_idx = pic->arena_idx;
cont->ip = pic->ip;
cont->ptable = pic->ptable;
cont->prev = pic->cc;
cont->retc = 0;
cont->retv = NULL;
@ -60,7 +58,6 @@ pic_load_point(pic_state *pic, struct pic_cont *cont)
pic->xp = pic->xpbase + cont->xp_offset;
pic->arena_idx = cont->arena_idx;
pic->ip = cont->ip;
pic->ptable = cont->ptable;
pic->cc = cont->prev;
}
@ -86,12 +83,14 @@ pic_wind(pic_state *pic, struct checkpoint *here, struct checkpoint *there)
}
}
static pic_value
pic_value
pic_dynamic_wind(pic_state *pic, pic_value in, pic_value thunk, pic_value out)
{
struct checkpoint *here;
pic_value val;
assert(pic_proc_p(pic, thunk));
pic_call(pic, in, 0); /* enter */
here = pic->cp;

View File

@ -22,7 +22,7 @@ pic_get_backtrace(pic_state *pic)
trace = pic_str_cat(pic, trace, pic_lit_value(pic, " at "));
trace = pic_str_cat(pic, trace, pic_lit_value(pic, "(anonymous lambda)"));
if (pic_func_p(proc)) {
if (pic_func_p(pic, proc)) {
trace = pic_str_cat(pic, trace, pic_lit_value(pic, " (native function)\n"));
} else {
trace = pic_str_cat(pic, trace, pic_lit_value(pic, " (unknown location)\n")); /* TODO */

View File

@ -1050,22 +1050,13 @@ pic_compile(pic_state *pic, pic_value obj)
size_t ai = pic_enter(pic);
#if 0
fprintf(stdout, "ai = %zu\n", pic_enter(pic));
fprintf(stdout, "# input expression\n");
pic_write(pic, obj);
fprintf(stdout, "\n");
fprintf(stdout, "ai = %zu\n", pic_enter(pic));
pic_printf(pic, "# input expression\n~s\n", obj);
#endif
/* optimize */
obj = pic_optimize(pic, obj);
#if 0
fprintf(stdout, "## optimize completed\n");
pic_write(pic, obj);
fprintf(stdout, "\n");
fprintf(stdout, "ai = %zu\n", pic_enter(pic));
pic_printf(pic, "## optimize completed\n~s\n", obj);
#endif
SAVE(pic, ai, obj);
@ -1073,10 +1064,7 @@ pic_compile(pic_state *pic, pic_value obj)
/* analyze */
obj = pic_analyze(pic, obj);
#if 0
fprintf(stdout, "## analyzer completed\n");
pic_write(pic, obj);
fprintf(stdout, "\n");
fprintf(stdout, "ai = %zu\n", pic_enter(pic));
pic_printf(pic, "## analyzer completed\n~s\n", obj);
#endif
SAVE(pic, ai, obj);

View File

@ -467,9 +467,6 @@ gc_mark_phase(pic_state *pic)
/* features */
gc_mark(pic, pic->features);
/* parameter table */
gc_mark(pic, pic->ptable);
/* library table */
for (it = kh_begin(&pic->ltable); it != kh_end(&pic->ltable); ++it) {
if (! kh_exist(&pic->ltable, it)) {

View File

@ -185,10 +185,11 @@ pic_value pic_id_name(pic_state *, pic_value id);
void pic_rope_incref(pic_state *, struct rope *);
void pic_rope_decref(pic_state *, struct rope *);
#define pic_func_p(proc) (pic_type(pic, proc) == PIC_TYPE_FUNC)
#define pic_irep_p(proc) (pic_type(pic, proc) == PIC_TYPE_IREP)
#define pic_func_p(pic, proc) (pic_type(pic, proc) == PIC_TYPE_FUNC)
#define pic_irep_p(pic, proc) (pic_type(pic, proc) == PIC_TYPE_IREP)
void pic_wind(pic_state *, struct checkpoint *, struct checkpoint *);
pic_value pic_dynamic_wind(pic_state *, pic_value in, pic_value thunk, pic_value out);
#if defined(__cplusplus)

View File

@ -54,8 +54,6 @@ struct pic_state {
struct code *ip;
pic_value ptable; /* list of ephemerons */
struct lib *lib;
pic_value features;

View File

@ -918,7 +918,7 @@ pic_closure_ref(pic_state *pic, int n)
{
pic_value self = GET_OPERAND(pic, 0);
assert(pic_func_p(self));
assert(pic_func_p(pic, self));
if (n < 0 || pic_proc_ptr(pic, self)->u.f.localc <= n) {
pic_error(pic, "pic_closure_ref: index out of range", 1, pic_int_value(pic, n));
@ -931,7 +931,7 @@ pic_closure_set(pic_state *pic, int n, pic_value v)
{
pic_value self = GET_OPERAND(pic, 0);
assert(pic_func_p(self));
assert(pic_func_p(pic, self));
if (n < 0 || pic_proc_ptr(pic, self)->u.f.localc <= n) {
pic_error(pic, "pic_closure_ref: index out of range", 1, pic_int_value(pic, n));

View File

@ -290,9 +290,6 @@ pic_open(pic_allocf allocf, void *userdata)
xfopen_null(pic, "w");
#endif
/* parameter table */
pic->ptable = pic_nil_value(pic);
/* native stack marker */
pic->native_stack_start = &t;
@ -306,9 +303,6 @@ pic_open(pic_allocf allocf, void *userdata)
pic->cp->depth = 0;
pic->cp->in = pic->cp->out = NULL;
/* parameter table */
pic->ptable = pic_cons(pic, pic_make_weak(pic), pic_nil_value(pic));
/* standard libraries */
pic_make_library(pic, "picrin.user");
pic_in_library(pic, "picrin.user");

View File

@ -8,28 +8,12 @@
#include "picrin/private/state.h"
static pic_value
var_get(pic_state *pic, pic_value var)
var_conv(pic_state *pic, pic_value val, pic_value conv)
{
pic_value weak, it;
pic_for_each (weak, pic->ptable, it) {
if (pic_weak_has(pic, weak, var)) {
return pic_weak_ref(pic, weak, var);
}
if (! pic_false_p(pic, conv)) {
val = pic_call(pic, conv, 1, val);
}
PIC_UNREACHABLE();
}
static pic_value
var_set(pic_state *pic, pic_value var, pic_value val)
{
pic_value weak;
weak = pic_car(pic, pic->ptable);
pic_weak_set(pic, weak, var, val);
return pic_undef_value(pic);
return val;
}
static pic_value
@ -41,28 +25,48 @@ var_call(pic_state *pic)
n = pic_get_args(pic, "&|o", &self, &val);
if (n == 0) {
return var_get(pic, self);
return pic_closure_ref(pic, 0);
} else {
pic_value conv;
conv = pic_closure_ref(pic, 0);
if (! pic_false_p(pic, conv)) {
val = pic_call(pic, conv, 1, val);
}
return var_set(pic, self, val);
pic_closure_set(pic, 0, var_conv(pic, val, pic_closure_ref(pic, 1)));
return pic_undef_value(pic);
}
}
pic_value
pic_make_var(pic_state *pic, pic_value init, pic_value conv)
{
pic_value var;
return pic_lambda(pic, var_call, 2, var_conv(pic, init, conv), conv);
}
var = pic_lambda(pic, var_call, 1, conv);
static pic_value
dynamic_set(pic_state *pic)
{
pic_value var, val;
pic_call(pic, var, 1, init);
pic_get_args(pic, "");
return var;
var = pic_closure_ref(pic, 0);
val = pic_closure_ref(pic, 1);
pic_proc_ptr(pic, var)->locals[0] = val;
return pic_undef_value(pic);
}
pic_value
pic_dynamic_bind(pic_state *pic, pic_value var, pic_value val, pic_value thunk)
{
pic_value in, out, new_val, old_val;
old_val = pic_call(pic, var, 0);
new_val = var_conv(pic, val, pic_proc_ptr(pic, var)->locals[1]);
in = pic_lambda(pic, dynamic_set, 2, var, new_val);
out = pic_lambda(pic, dynamic_set, 2, var, old_val);
return pic_dynamic_wind(pic, in, thunk, out);
}
static pic_value
@ -76,24 +80,22 @@ pic_var_make_parameter(pic_state *pic)
}
static pic_value
pic_var_with_parameter(pic_state *pic)
pic_var_dynamic_bind(pic_state *pic)
{
pic_value body, val;
pic_value var, val, thunk;
pic_get_args(pic, "l", &body);
pic_get_args(pic, "lol", &var, &val, &thunk);
pic->ptable = pic_cons(pic, pic_make_weak(pic), pic->ptable);
if (! (pic_proc_p(pic, var) && pic_proc_ptr(pic, var)->u.f.func == var_call)) {
pic_error(pic, "parameter required", 1, var);
}
val = pic_call(pic, body, 0);
pic->ptable = pic_cdr(pic, pic->ptable);
return val;
return pic_dynamic_bind(pic, var, val, thunk);
}
void
pic_init_var(pic_state *pic)
{
pic_defun(pic, "make-parameter", pic_var_make_parameter);
pic_defun(pic, "with-parameter", pic_var_with_parameter);
pic_defun(pic, "dynamic-bind", pic_var_dynamic_bind);
}

13
t/issue/parameterize.scm Normal file
View File

@ -0,0 +1,13 @@
(import (scheme base)
(picrin test))
(test-begin)
(define a #f)
(parameterize ()
(set! a (make-parameter 1)))
(test 1 (a))
(test-end)