change dictionary interface.
use #undefined object as sentinel
This commit is contained in:
parent
2a1b7cf287
commit
448bbf679d
|
@ -16,11 +16,10 @@
|
||||||
(define setter
|
(define setter
|
||||||
(letrec ((setter
|
(letrec ((setter
|
||||||
(lambda (proc)
|
(lambda (proc)
|
||||||
(receive (setter exists) (dictionary-ref (attribute proc)
|
(let ((setter (dictionary-ref (attribute proc) '@@setter)))
|
||||||
'@@setter)
|
(if (undefined? setter)
|
||||||
(if exists
|
(error "no setter found")
|
||||||
setter
|
setter))))
|
||||||
(error "No setter found")))))
|
|
||||||
(set-setter!
|
(set-setter!
|
||||||
(lambda (proc setter)
|
(lambda (proc setter)
|
||||||
(dictionary-set! (attribute proc) '@@setter setter))))
|
(dictionary-set! (attribute proc) '@@setter setter))))
|
||||||
|
|
|
@ -101,9 +101,7 @@ Technically, picrin's array is implemented as a ring-buffer, effective double-en
|
||||||
(picrin dictionary)
|
(picrin dictionary)
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
Object-to-object table. Internally it is implemented on hash-table. Equivalence is tested with equal? procedure.
|
Symbol-to-object hash table.
|
||||||
|
|
||||||
Note that dictionary is not a weak map; if you are going to make a highly memory-consuming program with dictionaries, you should know that dictionaries keep their bound objects and never let them free until you explicitly deletes bindings.
|
|
||||||
|
|
||||||
- **(make-dictionary)**
|
- **(make-dictionary)**
|
||||||
|
|
||||||
|
@ -119,15 +117,13 @@ Note that dictionary is not a weak map; if you are going to make a highly memory
|
||||||
|
|
||||||
- **(dictionary-ref dict key)**
|
- **(dictionary-ref dict key)**
|
||||||
|
|
||||||
Look up dictionary dict for a value associated with key. It returns two values: first is the associated value if exists, and second is a boolean of lookup result.
|
Look up dictionary dict for a value associated with key. If dict has a slot for key `key`, the value stored in the slot is returned. Otherwise `#undefined` is returned.
|
||||||
|
|
||||||
- **(dictionary-set! dict key obj)**
|
- **(dictionary-set! dict key obj)**
|
||||||
|
|
||||||
If there is no value already associated with key, this function newly creates a binding of key with obj. Otherwise, updates the existing binding with given obj.
|
If there is no value already associated with key, this function newly creates a binding of key with obj. Otherwise, updates the existing binding with given obj.
|
||||||
|
|
||||||
- **(dictionary-delete dict key)**
|
If obj is `#undefined`, this procedure behaves like a deleter: it will remove the key/value slot with the name `key` from the dictionary. When no slot is associated with `key`, it will do nothing.
|
||||||
|
|
||||||
Deletes the binding associated with key from dict. If no binding on dict is associated with key, an error will be raised.
|
|
||||||
|
|
||||||
- **(dictionary-size dict)**
|
- **(dictionary-size dict)**
|
||||||
|
|
||||||
|
|
|
@ -14,14 +14,13 @@ my $src = <<'EOL';
|
||||||
"memoize on symbols"
|
"memoize on symbols"
|
||||||
(define cache (make-dictionary))
|
(define cache (make-dictionary))
|
||||||
(lambda (sym)
|
(lambda (sym)
|
||||||
(call-with-values (lambda () (dictionary-ref cache sym))
|
(define value (dictionary-ref cache sym))
|
||||||
(lambda (value exists)
|
(if (not (undefined? value))
|
||||||
(if exists
|
value
|
||||||
value
|
(begin
|
||||||
(begin
|
(define val (f sym))
|
||||||
(define val (f sym))
|
(dictionary-set! cache sym val)
|
||||||
(dictionary-set! cache sym val)
|
val))))
|
||||||
val))))))
|
|
||||||
|
|
||||||
(define (er-macro-transformer f)
|
(define (er-macro-transformer f)
|
||||||
(lambda (mac-env)
|
(lambda (mac-env)
|
||||||
|
@ -395,147 +394,146 @@ EOL
|
||||||
|
|
||||||
const char pic_boot[][80] = {
|
const char pic_boot[][80] = {
|
||||||
"\n(define-library (picrin base)\n\n (define (memoize f)\n \"memoize on symbols\"\n ",
|
"\n(define-library (picrin base)\n\n (define (memoize f)\n \"memoize on symbols\"\n ",
|
||||||
" (define cache (make-dictionary))\n (lambda (sym)\n (call-with-values (l",
|
" (define cache (make-dictionary))\n (lambda (sym)\n (define value (dicti",
|
||||||
"ambda () (dictionary-ref cache sym))\n (lambda (value exists)\n (i",
|
"onary-ref cache sym))\n (if (not (undefined? value))\n value\n ",
|
||||||
"f exists\n value\n (begin\n (define val (f",
|
" (begin\n (define val (f sym))\n (dictionary-set! cache sy",
|
||||||
" sym))\n (dictionary-set! cache sym val)\n val))))))",
|
"m val)\n val))))\n\n (define (er-macro-transformer f)\n (lambda (mac-",
|
||||||
"\n\n (define (er-macro-transformer f)\n (lambda (mac-env)\n (lambda (expr u",
|
"env)\n (lambda (expr use-env)\n\n (define rename\n (memoize\n ",
|
||||||
"se-env)\n\n (define rename\n (memoize\n (lambda (sym)\n ",
|
" (lambda (sym)\n (make-identifier sym mac-env))))\n\n (de",
|
||||||
" (make-identifier sym mac-env))))\n\n (define (compare x y)\n ",
|
"fine (compare x y)\n (if (not (symbol? x))\n #f\n ",
|
||||||
" (if (not (symbol? x))\n #f\n (if (not (symbol? y))\n ",
|
" (if (not (symbol? y))\n #f\n (identifier=? use",
|
||||||
" #f\n (identifier=? use-env x use-env y))))\n\n ",
|
"-env x use-env y))))\n\n (f expr rename compare))))\n\n (define-syntax synta",
|
||||||
" (f expr rename compare))))\n\n (define-syntax syntax-error\n (er-macro-tran",
|
"x-error\n (er-macro-transformer\n (lambda (expr rename compare)\n (app",
|
||||||
"sformer\n (lambda (expr rename compare)\n (apply error (cdr expr)))))\n\n ",
|
"ly error (cdr expr)))))\n\n (define-syntax define-auxiliary-syntax\n (er-macro-",
|
||||||
" (define-syntax define-auxiliary-syntax\n (er-macro-transformer\n (lambda (",
|
"transformer\n (lambda (expr r c)\n (list (r 'define-syntax) (cadr expr)\n",
|
||||||
"expr r c)\n (list (r 'define-syntax) (cadr expr)\n (list (r 'lam",
|
" (list (r 'lambda) '_\n (list (r 'lambda) '_\n ",
|
||||||
"bda) '_\n (list (r 'lambda) '_\n (list (",
|
" (list (r 'error) (list (r 'string-append) \"invalid use of aux",
|
||||||
"r 'error) (list (r 'string-append) \"invalid use of auxiliary syntax: '\" (symbol-",
|
"iliary syntax: '\" (symbol->string (cadr expr)) \"'\"))))))))\n\n (define-auxiliary-",
|
||||||
">string (cadr expr)) \"'\"))))))))\n\n (define-auxiliary-syntax else)\n (define-aux",
|
"syntax else)\n (define-auxiliary-syntax =>)\n (define-auxiliary-syntax unquote)\n",
|
||||||
"iliary-syntax =>)\n (define-auxiliary-syntax unquote)\n (define-auxiliary-syntax",
|
" (define-auxiliary-syntax unquote-splicing)\n\n (define-syntax let\n (er-macro",
|
||||||
" unquote-splicing)\n\n (define-syntax let\n (er-macro-transformer\n (lambda ",
|
"-transformer\n (lambda (expr r compare)\n (if (symbol? (cadr expr))\n ",
|
||||||
"(expr r compare)\n (if (symbol? (cadr expr))\n (begin\n ",
|
" (begin\n (define name (car (cdr expr)))\n (defi",
|
||||||
" (define name (car (cdr expr)))\n (define bindings (car (cdr (cdr",
|
"ne bindings (car (cdr (cdr expr))))\n (define body (cdr (cdr (cdr",
|
||||||
" expr))))\n (define body (cdr (cdr (cdr expr))))\n (li",
|
" expr))))\n (list (r 'let) '()\n (list (r 'define) n",
|
||||||
"st (r 'let) '()\n (list (r 'define) name\n ",
|
"ame\n (cons (r 'lambda) (cons (map car bindings) body)))\n",
|
||||||
" (cons (r 'lambda) (cons (map car bindings) body)))\n (cons n",
|
" (cons name (map cadr bindings))))\n (begin\n ",
|
||||||
"ame (map cadr bindings))))\n (begin\n (set! bindings (cadr e",
|
" (set! bindings (cadr expr))\n (set! body (cddr expr))\n ",
|
||||||
"xpr))\n (set! body (cddr expr))\n (cons (cons (r 'lambda) ",
|
" (cons (cons (r 'lambda) (cons (map car bindings) body))\n (ma",
|
||||||
"(cons (map car bindings) body))\n (map cadr bindings)))))))\n\n ",
|
"p cadr bindings)))))))\n\n (define-syntax cond\n (er-macro-transformer\n (la",
|
||||||
"(define-syntax cond\n (er-macro-transformer\n (lambda (expr r compare)\n ",
|
"mbda (expr r compare)\n (let ((clauses (cdr expr)))\n (if (null? cla",
|
||||||
" (let ((clauses (cdr expr)))\n (if (null? clauses)\n #f\n ",
|
"uses)\n #f\n (begin\n (define clause (car cla",
|
||||||
" (begin\n (define clause (car clauses))\n (if ",
|
"uses))\n (if (compare (r 'else) (car clause))\n (c",
|
||||||
"(compare (r 'else) (car clause))\n (cons (r 'begin) (cdr clause",
|
"ons (r 'begin) (cdr clause))\n (if (if (>= (length clause) 2)\n ",
|
||||||
"))\n (if (if (>= (length clause) 2)\n ",
|
" (compare (r '=>) (list-ref clause 1))\n ",
|
||||||
"(compare (r '=>) (list-ref clause 1))\n #f)\n ",
|
" #f)\n (list (r 'let) (list (list (r 'x) (car cla",
|
||||||
" (list (r 'let) (list (list (r 'x) (car clause)))\n ",
|
"use)))\n (list (r 'if) (r 'x)\n ",
|
||||||
" (list (r 'if) (r 'x)\n (list (list-re",
|
" (list (list-ref clause 2) (r 'x))\n ",
|
||||||
"f clause 2) (r 'x))\n (cons (r 'cond) (cdr clau",
|
" (cons (r 'cond) (cdr clauses))))\n (list (r 'if) (car clau",
|
||||||
"ses))))\n (list (r 'if) (car clause)\n ",
|
"se)\n (cons (r 'begin) (cdr clause))\n ",
|
||||||
" (cons (r 'begin) (cdr clause))\n (cons (r 'con",
|
" (cons (r 'cond) (cdr clauses)))))))))))\n\n (define-syntax and\n (",
|
||||||
"d) (cdr clauses)))))))))))\n\n (define-syntax and\n (er-macro-transformer\n ",
|
|
||||||
"(lambda (expr r compare)\n (let ((exprs (cdr expr)))\n (cond\n ",
|
|
||||||
" ((null? exprs)\n #t)\n ((= (length exprs) 1)\n (car",
|
|
||||||
" exprs))\n (else\n (list (r 'let) (list (list (r 'it) (car expr",
|
|
||||||
"s)))\n (list (r 'if) (r 'it)\n (cons (r 'and",
|
|
||||||
") (cdr exprs))\n (r 'it)))))))))\n\n (define-syntax or\n (",
|
|
||||||
"er-macro-transformer\n (lambda (expr r compare)\n (let ((exprs (cdr expr",
|
"er-macro-transformer\n (lambda (expr r compare)\n (let ((exprs (cdr expr",
|
||||||
")))\n (cond\n ((null? exprs)\n #t)\n ((= (length",
|
")))\n (cond\n ((null? exprs)\n #t)\n ((= (length",
|
||||||
" exprs) 1)\n (car exprs))\n (else\n (list (r 'let) (li",
|
" exprs) 1)\n (car exprs))\n (else\n (list (r 'let) (li",
|
||||||
"st (list (r 'it) (car exprs)))\n (list (r 'if) (r 'it)\n ",
|
"st (list (r 'it) (car exprs)))\n (list (r 'if) (r 'it)\n ",
|
||||||
" (r 'it)\n (cons (r 'or) (cdr exprs))))))))))\n\n",
|
" (cons (r 'and) (cdr exprs))\n (r 'it)))))))))\n",
|
||||||
" (define-syntax quasiquote\n (er-macro-transformer\n (lambda (form rename ",
|
"\n (define-syntax or\n (er-macro-transformer\n (lambda (expr r compare)\n ",
|
||||||
"compare)\n\n (define (quasiquote? form)\n (and (pair? form) (compare ",
|
" (let ((exprs (cdr expr)))\n (cond\n ((null? exprs)\n ",
|
||||||
"(car form) (rename 'quasiquote))))\n\n (define (unquote? form)\n (and",
|
" #t)\n ((= (length exprs) 1)\n (car exprs))\n (else\n ",
|
||||||
" (pair? form) (compare (car form) (rename 'unquote))))\n\n (define (unquote-",
|
" (list (r 'let) (list (list (r 'it) (car exprs)))\n (list ",
|
||||||
"splicing? form)\n (and (pair? form) (pair? (car form))\n (com",
|
"(r 'if) (r 'it)\n (r 'it)\n (cons (r '",
|
||||||
"pare (car (car form)) (rename 'unquote-splicing))))\n\n (define (qq depth ex",
|
"or) (cdr exprs))))))))))\n\n (define-syntax quasiquote\n (er-macro-transformer\n",
|
||||||
"pr)\n (cond\n ;; unquote\n ((unquote? expr)\n (i",
|
" (lambda (form rename compare)\n\n (define (quasiquote? form)\n (",
|
||||||
"f (= depth 1)\n (car (cdr expr))\n (list (rename 'list",
|
"and (pair? form) (compare (car form) (rename 'quasiquote))))\n\n (define (un",
|
||||||
")\n (list (rename 'quote) (rename 'unquote))\n ",
|
"quote? form)\n (and (pair? form) (compare (car form) (rename 'unquote))))",
|
||||||
" (qq (- depth 1) (car (cdr expr))))))\n ;; unquote-splicing\n ",
|
"\n\n (define (unquote-splicing? form)\n (and (pair? form) (pair? (car",
|
||||||
" ((unquote-splicing? expr)\n (if (= depth 1)\n (list (ren",
|
" form))\n (compare (car (car form)) (rename 'unquote-splicing))))\n\n ",
|
||||||
"ame 'append)\n (car (cdr (car expr)))\n (q",
|
" (define (qq depth expr)\n (cond\n ;; unquote\n ((un",
|
||||||
"q depth (cdr expr)))\n (list (rename 'cons)\n (l",
|
"quote? expr)\n (if (= depth 1)\n (car (cdr expr))\n ",
|
||||||
"ist (rename 'list)\n (list (rename 'quote) (rename 'unq",
|
" (list (rename 'list)\n (list (rename 'quote) (rename '",
|
||||||
"uote-splicing))\n (qq (- depth 1) (car (cdr (car expr))",
|
"unquote))\n (qq (- depth 1) (car (cdr expr))))))\n ;;",
|
||||||
")))\n (qq depth (cdr expr)))))\n ;; quasiquote\n ",
|
" unquote-splicing\n ((unquote-splicing? expr)\n (if (= depth 1)",
|
||||||
" ((quasiquote? expr)\n (list (rename 'list)\n (list (",
|
"\n (list (rename 'append)\n (car (cdr (car expr)",
|
||||||
"rename 'quote) (rename 'quasiquote))\n (qq (+ depth 1) (car (cdr ",
|
"))\n (qq depth (cdr expr)))\n (list (rename 'con",
|
||||||
"expr)))))\n ;; list\n ((pair? expr)\n (list (rename 'co",
|
"s)\n (list (rename 'list)\n (list (r",
|
||||||
"ns)\n (qq depth (car expr))\n (qq depth (cdr expr)",
|
"ename 'quote) (rename 'unquote-splicing))\n (qq (- dept",
|
||||||
")))\n ;; vector\n ((vector? expr)\n (list (rename 'list",
|
"h 1) (car (cdr (car expr)))))\n (qq depth (cdr expr)))))\n ",
|
||||||
"->vector) (qq depth (vector->list expr))))\n ;; simple datum\n (",
|
" ;; quasiquote\n ((quasiquote? expr)\n (list (rename 'list",
|
||||||
"else\n (list (rename 'quote) expr))))\n\n (let ((x (cadr form)))\n ",
|
")\n (list (rename 'quote) (rename 'quasiquote))\n ",
|
||||||
" (qq 1 x)))))\n\n (define-syntax let*\n (er-macro-transformer\n (lambd",
|
"(qq (+ depth 1) (car (cdr expr)))))\n ;; list\n ((pair? expr)\n ",
|
||||||
"a (form r compare)\n (let ((bindings (cadr form))\n (body (cddr ",
|
" (list (rename 'cons)\n (qq depth (car expr))\n ",
|
||||||
"form)))\n (if (null? bindings)\n `(,(r 'let) () ,@body)\n ",
|
" (qq depth (cdr expr))))\n ;; vector\n ((vector? expr)\n ",
|
||||||
" `(,(r 'let) ((,(caar bindings)\n ,@(cdar binding",
|
" (list (rename 'list->vector) (qq depth (vector->list expr))))\n ;",
|
||||||
"s)))\n (,(r 'let*) (,@(cdr bindings))\n ,@body)))))))",
|
"; simple datum\n (else\n (list (rename 'quote) expr))))\n\n ",
|
||||||
"\n\n (define-syntax letrec*\n (er-macro-transformer\n (lambda (form r compar",
|
" (let ((x (cadr form)))\n (qq 1 x)))))\n\n (define-syntax let*\n (er-mac",
|
||||||
"e)\n (let ((bindings (cadr form))\n (body (cddr form)))\n ",
|
"ro-transformer\n (lambda (form r compare)\n (let ((bindings (cadr form))",
|
||||||
" (let ((vars (map (lambda (v) `(,v #f)) (map car bindings)))\n (ini",
|
"\n (body (cddr form)))\n (if (null? bindings)\n `(,",
|
||||||
"tials (map (lambda (v) `(,(r 'set!) ,@v)) bindings)))\n `(,(r 'let) (,@",
|
"(r 'let) () ,@body)\n `(,(r 'let) ((,(caar bindings)\n ",
|
||||||
"vars)\n ,@initials\n ,@body))))))\n\n (define-syntax letrec",
|
" ,@(cdar bindings)))\n (,(r 'let*) (,@(cdr bindings))\n ",
|
||||||
"\n (er-macro-transformer\n (lambda (form rename compare)\n `(,(rename ",
|
" ,@body)))))))\n\n (define-syntax letrec*\n (er-macro-transformer\n ",
|
||||||
"'letrec*) ,@(cdr form)))))\n\n (define-syntax let*-values\n (er-macro-transform",
|
" (lambda (form r compare)\n (let ((bindings (cadr form))\n (b",
|
||||||
"er\n (lambda (form r c)\n (let ((formals (cadr form)))\n (if (nul",
|
"ody (cddr form)))\n (let ((vars (map (lambda (v) `(,v #f)) (map car bindi",
|
||||||
"l? formals)\n `(,(r 'let) () ,@(cddr form))\n `(,(r 'call-",
|
"ngs)))\n (initials (map (lambda (v) `(,(r 'set!) ,@v)) bindings)))\n",
|
||||||
"with-values) (,(r 'lambda) () ,@(cdar formals))\n (,(r 'lambda) (,@",
|
" `(,(r 'let) (,@vars)\n ,@initials\n ,@body)))))",
|
||||||
"(caar formals))\n (,(r 'let*-values) (,@(cdr formals))\n ",
|
")\n\n (define-syntax letrec\n (er-macro-transformer\n (lambda (form rename c",
|
||||||
" ,@(cddr form)))))))))\n\n (define-syntax let-values\n (er-macro-transform",
|
"ompare)\n `(,(rename 'letrec*) ,@(cdr form)))))\n\n (define-syntax let*-valu",
|
||||||
"er\n (lambda (form r c)\n `(,(r 'let*-values) ,@(cdr form)))))\n\n (defin",
|
"es\n (er-macro-transformer\n (lambda (form r c)\n (let ((formals (cadr",
|
||||||
"e-syntax define-values\n (er-macro-transformer\n (lambda (form r compare)\n ",
|
" form)))\n (if (null? formals)\n `(,(r 'let) () ,@(cddr form))",
|
||||||
" (let ((formal (cadr form))\n (exprs (cddr form)))\n `(,",
|
"\n `(,(r 'call-with-values) (,(r 'lambda) () ,@(cdar formals))\n ",
|
||||||
"(r 'begin)\n ,@(let loop ((formal formal))\n (if (not (p",
|
" (,(r 'lambda) (,@(caar formals))\n (,(r 'let*-values) (,@",
|
||||||
"air? formal))\n (if (symbol? formal)\n `",
|
"(cdr formals))\n ,@(cddr form)))))))))\n\n (define-syntax let-valu",
|
||||||
"((,(r 'define) ,formal #f))\n '())\n `((",
|
"es\n (er-macro-transformer\n (lambda (form r c)\n `(,(r 'let*-values) ",
|
||||||
",(r 'define) ,(car formal) #f) . ,(loop (cdr formal)))))\n (,(r 'call-",
|
",@(cdr form)))))\n\n (define-syntax define-values\n (er-macro-transformer\n ",
|
||||||
"with-values) (,(r 'lambda) () ,@exprs)\n (,(r 'lambda) ,(r 'args)\n ",
|
"(lambda (form r compare)\n (let ((formal (cadr form))\n (exprs ",
|
||||||
" ,@(let loop ((formal formal) (args (r 'args)))\n ",
|
"(cddr form)))\n `(,(r 'begin)\n ,@(let loop ((formal formal))\n ",
|
||||||
" (if (not (pair? formal))\n (if (symbol? formal)\n ",
|
" (if (not (pair? formal))\n (if (symbol? formal)",
|
||||||
" `((,(r 'set!) ,formal ,args))\n '()",
|
"\n `((,(r 'define) ,formal #f))\n '(",
|
||||||
")\n `((,(r 'set!) ,(car formal) (,(r 'car) ,args))\n ",
|
"))\n `((,(r 'define) ,(car formal) #f) . ,(loop (cdr formal)))",
|
||||||
" ,@(loop (cdr formal) `(,(r 'cdr) ,args))))))))))))\n\n (define",
|
"))\n (,(r 'call-with-values) (,(r 'lambda) () ,@exprs)\n (",
|
||||||
"-syntax do\n (er-macro-transformer\n (lambda (form r compare)\n (let (",
|
",(r 'lambda) ,(r 'args)\n ,@(let loop ((formal formal) (args (r 'a",
|
||||||
"(bindings (car (cdr form)))\n (finish (car (cdr (cdr form))))\n ",
|
"rgs)))\n (if (not (pair? formal))\n (if ",
|
||||||
" (body (cdr (cdr (cdr form)))))\n `(,(r 'let) ,(r 'loop) ,(map",
|
"(symbol? formal)\n `((,(r 'set!) ,formal ,args))\n ",
|
||||||
" (lambda (x)\n (list (car x) (cadr x)))\n ",
|
" '())\n `((,(r 'set!) ,(car formal) ",
|
||||||
" bindings)\n (,(r 'if) ,(car finish)",
|
"(,(r 'car) ,args))\n ,@(loop (cdr formal) `(,(r 'cdr) ,a",
|
||||||
"\n (,(r 'begin) ,@(cdr finish))\n (,(r 'begin) ,@body\n ",
|
"rgs))))))))))))\n\n (define-syntax do\n (er-macro-transformer\n (lambda (for",
|
||||||
" (,(r 'loop) ,@(map (lambda (x)\n (if (nul",
|
"m r compare)\n (let ((bindings (car (cdr form)))\n (finish (ca",
|
||||||
"l? (cddr x))\n (car x)\n ",
|
"r (cdr (cdr form))))\n (body (cdr (cdr (cdr form)))))\n `(",
|
||||||
" (car (cddr x))))\n bindings))))))",
|
",(r 'let) ,(r 'loop) ,(map (lambda (x)\n (",
|
||||||
")))\n\n (define-syntax when\n (er-macro-transformer\n (lambda (expr rename c",
|
"list (car x) (cadr x)))\n bindings)\n ",
|
||||||
"ompare)\n (let ((test (cadr expr))\n (body (cddr expr)))\n ",
|
" (,(r 'if) ,(car finish)\n (,(r 'begin) ,@(cdr finish))\n ",
|
||||||
" `(,(rename 'if) ,test\n (,(rename 'begin) ,@body)\n #f",
|
"(,(r 'begin) ,@body\n (,(r 'loop) ,@(map (lambda (x)\n ",
|
||||||
")))))\n\n (define-syntax unless\n (er-macro-transformer\n (lambda (expr rena",
|
" (if (null? (cddr x))\n (ca",
|
||||||
"me compare)\n (let ((test (cadr expr))\n (body (cddr expr)))\n ",
|
"r x)\n (car (cddr x))))\n ",
|
||||||
" `(,(rename 'if) ,test\n #f\n (,(rename 'begin) ,@b",
|
" bindings)))))))))\n\n (define-syntax when\n (er-macro-transformer\n ",
|
||||||
"ody))))))\n\n (define-syntax case\n (er-macro-transformer\n (lambda (expr r ",
|
" (lambda (expr rename compare)\n (let ((test (cadr expr))\n (",
|
||||||
"compare)\n (let ((key (cadr expr))\n (clauses (cddr expr)))\n ",
|
"body (cddr expr)))\n `(,(rename 'if) ,test\n (,(rename 'begin",
|
||||||
" `(,(r 'let) ((,(r 'key) ,key))\n ,(let loop ((clauses clauses))\n ",
|
") ,@body)\n #f)))))\n\n (define-syntax unless\n (er-macro-transform",
|
||||||
" (if (null? clauses)\n #f\n (begi",
|
"er\n (lambda (expr rename compare)\n (let ((test (cadr expr))\n ",
|
||||||
"n\n (define clause (car clauses))\n `(,(r ",
|
" (body (cddr expr)))\n `(,(rename 'if) ,test\n #f\n ",
|
||||||
"'if) ,(if (compare (r 'else) (car clause))\n ",
|
" (,(rename 'begin) ,@body))))))\n\n (define-syntax case\n (er-macro-transfo",
|
||||||
"'#t\n `(,(r 'or)\n ",
|
"rmer\n (lambda (expr r compare)\n (let ((key (cadr expr))\n (",
|
||||||
" ,@(map (lambda (x)\n `(",
|
"clauses (cddr expr)))\n `(,(r 'let) ((,(r 'key) ,key))\n ,(let ",
|
||||||
",(r 'eqv?) ,(r 'key) (,(r 'quote) ,x)))\n ",
|
"loop ((clauses clauses))\n (if (null? clauses)\n #",
|
||||||
" (car clause))))\n ,(if (compare (r '=>) (list-ref cla",
|
"f\n (begin\n (define clause (car clauses))\n ",
|
||||||
"use 1))\n `(,(list-ref clause 2) ,(r 'key))\n ",
|
" `(,(r 'if) ,(if (compare (r 'else) (car clause))\n ",
|
||||||
" `(,(r 'begin) ,@(cdr clause)))\n ,(loop (",
|
" '#t\n `(,(r 'or)\n ",
|
||||||
"cdr clauses)))))))))))\n\n (define-syntax parameterize\n (er-macro-transformer\n",
|
" ,@(map (lambda (x)\n ",
|
||||||
" (lambda (form r compare)\n (let ((formal (cadr form))\n (bo",
|
" `(,(r 'eqv?) ,(r 'key) (,(r 'quote) ,x)))\n ",
|
||||||
"dy (cddr form)))\n `(,(r 'with-parameter)\n (lambda ()\n ",
|
" (car clause))))\n ,(if (com",
|
||||||
" ,@formal\n ,@body))))))\n\n (define-syntax letrec-syntax\n (er-m",
|
"pare (r '=>) (list-ref clause 1))\n `(,(list-ref claus",
|
||||||
"acro-transformer\n (lambda (form r c)\n (let ((formal (car (cdr form)))\n",
|
"e 2) ,(r 'key))\n `(,(r 'begin) ,@(cdr clause)))\n ",
|
||||||
" (body (cdr (cdr form))))\n `(let ()\n ,@(map (la",
|
" ,(loop (cdr clauses)))))))))))\n\n (define-syntax parameterize\n",
|
||||||
"mbda (x)\n `(,(r 'define-syntax) ,(car x) ,(cadr x)))\n ",
|
" (er-macro-transformer\n (lambda (form r compare)\n (let ((formal (ca",
|
||||||
" formal)\n ,@body)))))\n\n (define-syntax let-syntax\n (er",
|
"dr form))\n (body (cddr form)))\n `(,(r 'with-parameter)\n ",
|
||||||
"-macro-transformer\n (lambda (form r c)\n `(,(r 'letrec-syntax) ,@(cdr f",
|
" (lambda ()\n ,@formal\n ,@body))))))\n\n (define-synt",
|
||||||
"orm)))))\n\n (export let let* letrec letrec*\n let-values let*-values def",
|
"ax letrec-syntax\n (er-macro-transformer\n (lambda (form r c)\n (let (",
|
||||||
"ine-values\n quasiquote unquote unquote-splicing\n and or\n ",
|
"(formal (car (cdr form)))\n (body (cdr (cdr form))))\n `(let",
|
||||||
" cond case else =>\n do when unless\n parameterize\n ",
|
" ()\n ,@(map (lambda (x)\n `(,(r 'define-syntax) ,(",
|
||||||
"let-syntax letrec-syntax\n syntax-error))\n\n",
|
"car x) ,(cadr x)))\n formal)\n ,@body)))))\n\n (define",
|
||||||
|
"-syntax let-syntax\n (er-macro-transformer\n (lambda (form r c)\n `(,(",
|
||||||
|
"r 'letrec-syntax) ,@(cdr form)))))\n\n (export let let* letrec letrec*\n ",
|
||||||
|
"let-values let*-values define-values\n quasiquote unquote unquote-splici",
|
||||||
|
"ng\n and or\n cond case else =>\n do when unless\n ",
|
||||||
|
" parameterize\n let-syntax letrec-syntax\n syntax-error))\n\n",
|
||||||
"",
|
"",
|
||||||
""
|
""
|
||||||
};
|
};
|
||||||
|
|
|
@ -104,11 +104,10 @@ pic_dict_dictionary_ref(pic_state *pic)
|
||||||
|
|
||||||
pic_get_args(pic, "dm", &dict, &key);
|
pic_get_args(pic, "dm", &dict, &key);
|
||||||
|
|
||||||
if (pic_dict_has(pic, dict, key)) {
|
if (! pic_dict_has(pic, dict, key)) {
|
||||||
return pic_values2(pic, pic_dict_ref(pic, dict, key), pic_true_value());
|
return pic_undef_value();
|
||||||
} else {
|
|
||||||
return pic_values2(pic, pic_undef_value(), pic_false_value());
|
|
||||||
}
|
}
|
||||||
|
return pic_dict_ref(pic, dict, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
|
@ -120,21 +119,14 @@ pic_dict_dictionary_set(pic_state *pic)
|
||||||
|
|
||||||
pic_get_args(pic, "dmo", &dict, &key, &val);
|
pic_get_args(pic, "dmo", &dict, &key, &val);
|
||||||
|
|
||||||
pic_dict_set(pic, dict, key, val);
|
if (pic_undef_p(val)) {
|
||||||
|
if (pic_dict_has(pic, dict, key)) {
|
||||||
return pic_undef_value();
|
pic_dict_del(pic, dict, key);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
static pic_value
|
else {
|
||||||
pic_dict_dictionary_del(pic_state *pic)
|
pic_dict_set(pic, dict, key, val);
|
||||||
{
|
}
|
||||||
struct pic_dict *dict;
|
|
||||||
pic_sym *key;
|
|
||||||
|
|
||||||
pic_get_args(pic, "dm", &dict, &key);
|
|
||||||
|
|
||||||
pic_dict_del(pic, dict, key);
|
|
||||||
|
|
||||||
return pic_undef_value();
|
return pic_undef_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,7 +311,6 @@ pic_init_dict(pic_state *pic)
|
||||||
pic_defun(pic, "dictionary", pic_dict_dictionary);
|
pic_defun(pic, "dictionary", pic_dict_dictionary);
|
||||||
pic_defun(pic, "dictionary-ref", pic_dict_dictionary_ref);
|
pic_defun(pic, "dictionary-ref", pic_dict_dictionary_ref);
|
||||||
pic_defun(pic, "dictionary-set!", pic_dict_dictionary_set);
|
pic_defun(pic, "dictionary-set!", pic_dict_dictionary_set);
|
||||||
pic_defun(pic, "dictionary-delete!", pic_dict_dictionary_del);
|
|
||||||
pic_defun(pic, "dictionary-size", pic_dict_dictionary_size);
|
pic_defun(pic, "dictionary-size", pic_dict_dictionary_size);
|
||||||
pic_defun(pic, "dictionary-map", pic_dict_dictionary_map);
|
pic_defun(pic, "dictionary-map", pic_dict_dictionary_map);
|
||||||
pic_defun(pic, "dictionary-for-each", pic_dict_dictionary_for_each);
|
pic_defun(pic, "dictionary-for-each", pic_dict_dictionary_for_each);
|
||||||
|
|
|
@ -178,7 +178,6 @@
|
||||||
dictionary
|
dictionary
|
||||||
dictionary-ref
|
dictionary-ref
|
||||||
dictionary-set!
|
dictionary-set!
|
||||||
dictionary-delete!
|
|
||||||
dictionary-size
|
dictionary-size
|
||||||
dictionary-map
|
dictionary-map
|
||||||
dictionary-for-each
|
dictionary-for-each
|
||||||
|
|
|
@ -20,14 +20,13 @@
|
||||||
"memoize on symbols"
|
"memoize on symbols"
|
||||||
(define cache (make-dictionary))
|
(define cache (make-dictionary))
|
||||||
(lambda (sym)
|
(lambda (sym)
|
||||||
(call-with-values (lambda () (dictionary-ref cache sym))
|
(define value (dictionary-ref cache sym))
|
||||||
(lambda (value exists)
|
(if (not (undefined? value))
|
||||||
(if exists
|
value
|
||||||
value
|
(begin
|
||||||
(begin
|
(define val (f sym))
|
||||||
(define val (f sym))
|
(dictionary-set! cache sym val)
|
||||||
(dictionary-set! cache sym val)
|
val))))
|
||||||
val))))))
|
|
||||||
|
|
||||||
(define (make-syntactic-closure env free form)
|
(define (make-syntactic-closure env free form)
|
||||||
|
|
||||||
|
@ -105,11 +104,10 @@
|
||||||
(identifier=? mac-env x mac-env y))))
|
(identifier=? mac-env x mac-env y))))
|
||||||
|
|
||||||
(walk (lambda (sym)
|
(walk (lambda (sym)
|
||||||
(call-with-values (lambda () (dictionary-ref icache* sym))
|
(let ((value (dictionary-ref icache* sym)))
|
||||||
(lambda (value exists)
|
(if (undefined? value)
|
||||||
(if exists
|
(rename sym)
|
||||||
value
|
value)))
|
||||||
(rename sym)))))
|
|
||||||
(f (walk inject expr) inject compare)))))
|
(f (walk inject expr) inject compare)))))
|
||||||
|
|
||||||
;; (define (strip-syntax form)
|
;; (define (strip-syntax form)
|
||||||
|
|
Loading…
Reference in New Issue