module dictionaries; import std.array; import environment; import formals; import lqtools; import lqtypes; LqType s_dict(LqType[] args, kwdict kwargs, Environment env) { /* (dict [pairs...] [:static] [:readonly]) */ auto d = new LqDictionary(); foreach(int i, LqType q; args) { check_arg(args[i], i, "pair", "dict"); LqPair pair = cast(LqPair)q; LqType key = pair.head(); check_arg(pair.tail(), i, "pair", "dict"); LqType value = (cast(LqPair)pair.tail()).head(); /* MUST exist */ d.add(key, value); } return d; } LqType s_dict_set(LqType[] args, kwdict kwargs, Environment env) { /* (dict-set! ) */ check_arglength(args, 3, 3, "dict-set!"); check_arg(args[0], 0, "dict", "dict-set!"); auto dict = cast(LqDictionary)(args[0]); dict.add(args[1], args[2]); return LQ_UNSPECIFIED(); } LqType s_dict_get(LqType[] args, kwdict kwargs, Environment env) { /* (dict-get ) => (key value) or #f */ check_arglength(args, 2, 2, "dict-get"); check_arg(args[0], 0, "dict", "dict-get"); auto dict = cast(LqDictionary)(args[0]); lqtypepair result; try { result = dict.get(args[1]); } catch (ArrayBoundsError e) { return LQ_FALSE(); } return LqPair.from_list(result); } LqType s_dict_delete(LqType[] args, kwdict kwargs, Environment env) { /* (dict-delete! ) Returns #t if key was found and deleted, #f otherwise. */ check_arglength(args, 2, 2, "dict-delete!"); check_arg(args[0], 0, "dict", "dict-delete!"); auto dict = cast(LqDictionary)(args[0]); bool deleted = dict.remove(args[1]); /* may raise error */ return deleted ? LQ_TRUE() : LQ_FALSE(); } LqType s_dict_items(LqType[] args, kwdict kwargs, Environment env) { /* (dict-keys ) */ check_arglength(args, 1, 1, "dict-items"); check_arg(args[0], 0, "dict", "dict-items"); auto dict = cast(LqDictionary)(args[0]); LqType[] items = []; foreach(lqtypepair tp; dict.items()) { LqType[] kvpair = [tp[0], tp[1]]; items ~= LqPair.from_list(kvpair); } return LqList.from_list(items); } bfun[string] get_builtins() { /* using an associative array literal here seems to have complications */ bfun[string] z; z["dict"] = &s_dict; z["dict-set!"] = &s_dict_set; z["dict-get"] = &s_dict_get; z["dict-items"] = &s_dict_items; z["dict-delete!"] = &s_dict_delete; return z; }