let dictionary-ref return two values

This commit is contained in:
Yuichi Nishiwaki 2014-08-29 23:57:55 +09:00
parent 059ee0c5cb
commit 3b3a74e114
3 changed files with 20 additions and 23 deletions

View File

@ -227,7 +227,7 @@ 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 symbol key. If no object is associated with key, it will raise an error. Look up dictionary dict for a value associated with symbol key. It returns two values: first is the associated value if exists, and second is a boolean of lookup result.
- **(dictionary-set! dict key obj)** - **(dictionary-set! dict key obj)**

View File

@ -27,12 +27,14 @@
"memoize on symbols" "memoize on symbols"
(define cache (make-dictionary)) (define cache (make-dictionary))
(lambda (sym) (lambda (sym)
(if (dictionary-has? cache sym) (call-with-values (lambda () (dictionary-ref cache sym))
(dictionary-ref cache sym) (lambda (value exists)
(begin (if exists
(define val (f sym)) value
(dictionary-set! cache sym val) (begin
val)))) (define val (f sym))
(dictionary-set! cache sym val)
val))))))
(define (identifier=? env1 sym1 env2 sym2) (define (identifier=? env1 sym1 env2 sym2)
@ -117,9 +119,11 @@
(identifier=? mac-env x mac-env y)))) (identifier=? mac-env x mac-env y))))
(walk (lambda (sym) (walk (lambda (sym)
(if (dictionary-has? icache* sym) (call-with-values (lambda () (dictionary-ref icache* sym))
(dictionary-ref icache* sym) (lambda (value exists)
(rename sym))) (if exists
value
(rename sym)))))
(f (walk inject expr) inject compare)))) (f (walk inject expr) inject compare))))
(define (strip-syntax form) (define (strip-syntax form)

View File

@ -4,6 +4,7 @@
#include "picrin.h" #include "picrin.h"
#include "picrin/dict.h" #include "picrin/dict.h"
#include "picrin/cont.h"
struct pic_dict * struct pic_dict *
pic_dict_new(pic_state *pic) pic_dict_new(pic_state *pic)
@ -92,7 +93,11 @@ pic_dict_dict_ref(pic_state *pic)
pic_get_args(pic, "dm", &dict, &key); pic_get_args(pic, "dm", &dict, &key);
return pic_dict_ref(pic, dict , key); if (pic_dict_has(pic, dict, key)) {
return pic_values2(pic, pic_dict_ref(pic, dict , key), pic_true_value());
} else {
return pic_values2(pic, pic_none_value(), pic_false_value());
}
} }
static pic_value static pic_value
@ -109,17 +114,6 @@ pic_dict_dict_set(pic_state *pic)
return pic_none_value(); return pic_none_value();
} }
static pic_value
pic_dict_dict_has_p(pic_state *pic)
{
struct pic_dict *dict;
pic_sym key;
pic_get_args(pic, "dm", &dict, &key);
return pic_bool_value(pic_dict_has(pic, dict, key));
}
static pic_value static pic_value
pic_dict_dict_del(pic_state *pic) pic_dict_dict_del(pic_state *pic)
{ {
@ -166,7 +160,6 @@ pic_init_dict(pic_state *pic)
pic_deflibrary (pic, "(picrin dictionary)") { pic_deflibrary (pic, "(picrin dictionary)") {
pic_defun(pic, "make-dictionary", pic_dict_dict); pic_defun(pic, "make-dictionary", pic_dict_dict);
pic_defun(pic, "dictionary?", pic_dict_dict_p); pic_defun(pic, "dictionary?", pic_dict_dict_p);
pic_defun(pic, "dictionary-has?", pic_dict_dict_has_p);
pic_defun(pic, "dictionary-ref", pic_dict_dict_ref); pic_defun(pic, "dictionary-ref", pic_dict_dict_ref);
pic_defun(pic, "dictionary-set!", pic_dict_dict_set); pic_defun(pic, "dictionary-set!", pic_dict_dict_set);
pic_defun(pic, "dictionary-delete", pic_dict_dict_del); pic_defun(pic, "dictionary-delete", pic_dict_dict_del);