diff --git a/dict.c b/dict.c index 988a2a53..64b1ab92 100644 --- a/dict.c +++ b/dict.c @@ -65,7 +65,7 @@ pic_dict_del(pic_state *pic, struct pic_dict *dict, pic_sym key) } static pic_value -pic_dict_dict(pic_state *pic) +pic_dict_make_dictionary(pic_state *pic) { struct pic_dict *dict; @@ -77,7 +77,26 @@ pic_dict_dict(pic_state *pic) } static pic_value -pic_dict_dict_p(pic_state *pic) +pic_dict_dictionary(pic_state *pic) +{ + struct pic_dict *dict; + pic_value *argv; + size_t argc, i; + + pic_get_args(pic, "*", &argc, &argv); + + dict = pic_make_dict(pic); + + for (i = 0; i < argc; i += 2) { + pic_assert_type(pic, argv[i], sym); + pic_dict_set(pic, dict, pic_sym(argv[i]), argv[i+1]); + } + + return pic_obj_value(dict); +} + +static pic_value +pic_dict_dictionary_p(pic_state *pic) { pic_value obj; @@ -87,7 +106,7 @@ pic_dict_dict_p(pic_state *pic) } static pic_value -pic_dict_dict_ref(pic_state *pic) +pic_dict_dictionary_ref(pic_state *pic) { struct pic_dict *dict; pic_sym key; @@ -102,7 +121,7 @@ pic_dict_dict_ref(pic_state *pic) } static pic_value -pic_dict_dict_set(pic_state *pic) +pic_dict_dictionary_set(pic_state *pic) { struct pic_dict *dict; pic_sym key; @@ -116,7 +135,7 @@ pic_dict_dict_set(pic_state *pic) } static pic_value -pic_dict_dict_del(pic_state *pic) +pic_dict_dictionary_del(pic_state *pic) { struct pic_dict *dict; pic_sym key; @@ -129,7 +148,7 @@ pic_dict_dict_del(pic_state *pic) } static pic_value -pic_dict_dict_size(pic_state *pic) +pic_dict_dictionary_size(pic_state *pic) { struct pic_dict *dict; @@ -139,7 +158,7 @@ pic_dict_dict_size(pic_state *pic) } static pic_value -pic_dict_dict_map(pic_state *pic) +pic_dict_dictionary_map(pic_state *pic) { struct pic_proc *proc; struct pic_dict *dict; @@ -158,7 +177,7 @@ pic_dict_dict_map(pic_state *pic) } static pic_value -pic_dict_dict_for_each(pic_state *pic) +pic_dict_dictionary_for_each(pic_state *pic) { struct pic_proc *proc; struct pic_dict *dict; @@ -180,15 +199,92 @@ pic_dict_dict_for_each(pic_state *pic) return pic_none_value(); } +static pic_value +pic_dict_dictionary_to_alist(pic_state *pic) +{ + struct pic_dict *dict; + pic_value item, alist = pic_nil_value(); + xh_iter it; + + pic_get_args(pic, "d", &dict); + + xh_begin(&it, &dict->hash); + while (xh_next(&it)) { + item = pic_cons(pic, pic_sym_value(xh_key(it.e, pic_sym)), xh_val(it.e, pic_value)); + pic_push(pic, item, alist); + } + + return pic_reverse(pic, alist); +} + +static pic_value +pic_dict_alist_to_dictionary(pic_state *pic) +{ + struct pic_dict *dict; + pic_value alist, e; + + pic_get_args(pic, "o", &alist); + + dict = pic_make_dict(pic); + + pic_for_each (e, pic_reverse(pic, alist)) { + pic_assert_type(pic, pic_car(pic, e), sym); + pic_dict_set(pic, dict, pic_sym(pic_car(pic, e)), pic_cdr(pic, e)); + } + + return pic_obj_value(dict); +} + +static pic_value +pic_dict_dictionary_to_plist(pic_state *pic) +{ + struct pic_dict *dict; + pic_value plist = pic_nil_value(); + xh_iter it; + + pic_get_args(pic, "d", &dict); + + xh_begin(&it, &dict->hash); + while (xh_next(&it)) { + pic_push(pic, xh_val(it.e, pic_value), plist); + pic_push(pic, pic_sym_value(xh_key(it.e, pic_sym)), plist); + } + + return pic_reverse(pic, plist); +} + +static pic_value +pic_dict_plist_to_dictionary(pic_state *pic) +{ + struct pic_dict *dict; + pic_value plist, e; + + pic_get_args(pic, "o", &plist); + + dict = pic_make_dict(pic); + + for (e = pic_reverse(pic, plist); ! pic_nil_p(e); e = pic_cddr(pic, e)) { + pic_assert_type(pic, pic_car(pic, e), sym); + pic_dict_set(pic, dict, pic_sym(pic_car(pic, e)), pic_cadr(pic, e)); + } + + return pic_obj_value(dict); +} + void pic_init_dict(pic_state *pic) { - pic_defun(pic, "make-dictionary", pic_dict_dict); - pic_defun(pic, "dictionary?", pic_dict_dict_p); - pic_defun(pic, "dictionary-ref", pic_dict_dict_ref); - pic_defun(pic, "dictionary-set!", pic_dict_dict_set); - pic_defun(pic, "dictionary-delete", pic_dict_dict_del); - pic_defun(pic, "dictionary-size", pic_dict_dict_size); - pic_defun(pic, "dictionary-map", pic_dict_dict_map); - pic_defun(pic, "dictionary-for-each", pic_dict_dict_for_each); + pic_defun(pic, "make-dictionary", pic_dict_make_dictionary); + pic_defun(pic, "dictionary?", pic_dict_dictionary_p); + pic_defun(pic, "dictionary", pic_dict_dictionary); + pic_defun(pic, "dictionary-ref", pic_dict_dictionary_ref); + 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-map", pic_dict_dictionary_map); + pic_defun(pic, "dictionary-for-each", pic_dict_dictionary_for_each); + pic_defun(pic, "dictionary->alist", pic_dict_dictionary_to_alist); + pic_defun(pic, "alist->dictionary", pic_dict_alist_to_dictionary); + pic_defun(pic, "dictionary->plist", pic_dict_dictionary_to_plist); + pic_defun(pic, "plist->dictionary", pic_dict_plist_to_dictionary); }