summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2011-11-12 11:24:08 -0800
committerKaz Kylheku <kaz@kylheku.com>2011-11-12 11:24:08 -0800
commitf1507e43b0c05178deca7af610d18de5dbc269d7 (patch)
tree10fbed916d9cdfc5caa6277e1086a256c4f4e4fb /lib.c
parentd70e7b808cb61af565fe0fbf0e5211e8a3c5352b (diff)
downloadtxr-f1507e43b0c05178deca7af610d18de5dbc269d7.tar.gz
txr-f1507e43b0c05178deca7af610d18de5dbc269d7.tar.bz2
txr-f1507e43b0c05178deca7af610d18de5dbc269d7.zip
Infrastructure for storing line number information
outside of the code, in hash tables. * filter.c (make_trie, trie_add): Update to three-argument make_hash. * hash.c (struct hash): New members, hash_fun, assoc_fun acons_new_l_fun. (ll_hash): Renamed to equal_hash. (eql_hash): New static function. (cobj_hash_op): Follows ll_hash rename. (hash_grow): Use new function indirection to call hashing function. (make_hash): New argument to specify type of hashing. Initialize new members of struct hash. (gethash_l, gethash, remhash): Use function indirection for hashing and chain search and update. (pushhash): New function. * hash.h (make_hash): Declaration updated with new parameter. (pushhash): Declared. * lib.c (eql_f): New global variable. (eql, assq, aconsq_new, aconsq_new_l): New functions. (make_package): Updated to new three-argument make_hash. (obj_init): gc-protect and initialize new variable eql_f. * lib.h (eql, assq, aconsq_new, aconsq_new_l): Declared. * match.c (dir_tables_init): Updated to there-argument make_hash. * parser.h (form_to_ln_hash, ln_to_forms_hash): Global variables declared. * parser.l (form_to_ln_hash, ln_to_forms_hash): New global variables. (grammar): Set yylval.lineno for tokens that are classified to that type in parser.y. (parse_init): Initialize and gc-protect new global variables. * parser.y (rl): New static helper function. (%union): New member, lineno. (ALL, SOME, NONE, MAYBE, CASES, CHOOSE, GATHER, AND, OR, END, COLLECT, UNTIL, COLL, OUTPUT, REPEAT, REP, SINGLE, FIRST, LAST, EMPTY, DEFINE, TRY, CATCH, FINALLY, ERRTOK, '('): Reclassified as lineno type. In the grammar, these keywords can thus provide a stable line number from the lexer. (grammar): Numerous rules updated to add constructs to the line number hash tables via the rl helper. * dep.mk: Updated. * Makefile (depend): Use the installed, stable txr in the system path to update dependencies rather than locally built ./txr, to prevent the problem that txr is broken because out out-of-date dependencies, and thus cannot regenerate dependencies.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c57
1 files changed, 54 insertions, 3 deletions
diff --git a/lib.c b/lib.c
index 72cbd551..7b3f9765 100644
--- a/lib.c
+++ b/lib.c
@@ -76,7 +76,7 @@ val null_string;
val nil_string;
val null_list;
-val identity_f, equal_f, eq_f, car_f;
+val identity_f, equal_f, eql_f, eq_f, car_f;
val prog_string;
@@ -440,6 +440,14 @@ val flatten(val list)
cnum c_num(val num);
+val eql(val left, val right)
+{
+ /* eql is same as eq for now, but when we get bignums,
+ eql will compare different bignum objects which are
+ the same number as equal. */
+ return eq(left, right);
+}
+
val equal(val left, val right)
{
/* Bitwise equality is equality, period. */
@@ -1300,7 +1308,7 @@ val make_package(val name)
val obj = make_obj();
obj->pk.type = PKG;
obj->pk.name = name;
- obj->pk.symhash = make_hash(nil, nil);
+ obj->pk.symhash = make_hash(nil, nil, lit("t")); /* don't have t yet! */
push(cons(name, obj), &packages);
return obj;
@@ -2073,6 +2081,18 @@ val assoc(val list, val key)
return nil;
}
+val assq(val list, val key)
+{
+ while (list) {
+ val elem = car(list);
+ if (eql(car(elem), key))
+ return elem;
+ list = cdr(list);
+ }
+
+ return nil;
+}
+
val acons(val list, val car, val cdr)
{
return cons(cons(car, cdr), list);
@@ -2107,6 +2127,36 @@ val *acons_new_l(val *list, val key, val *new_p)
}
}
+val aconsq_new(val list, val key, val value)
+{
+ val existing = assq(list, key);
+
+ if (existing) {
+ *cdr_l(existing) = value;
+ return list;
+ } else {
+ return cons(cons(key, value), list);
+ }
+}
+
+val *aconsq_new_l(val *list, val key, val *new_p)
+{
+ val existing = assq(*list, key);
+
+ if (existing) {
+ if (new_p)
+ *new_p = nil;
+ return cdr_l(existing);
+ } else {
+ val nc = cons(key, nil);
+ *list = cons(nc, *list);
+ if (new_p)
+ *new_p = t;
+ return cdr_l(nc);
+ }
+}
+
+
static val alist_remove_test(val item, val key)
{
return eq(car(item), key);
@@ -2346,7 +2396,7 @@ static void obj_init(void)
protect(&packages, &system_package, &keyword_package,
&user_package, &null_string, &nil_string,
- &null_list, &equal_f, &eq_f, &car_f,
+ &null_list, &equal_f, &eq_f, &eql_f, &car_f,
&identity_f, &prog_string, &env_list,
(val *) 0);
@@ -2451,6 +2501,7 @@ static void obj_init(void)
equal_f = func_n2(equal);
eq_f = func_n2(eq);
+ eql_f = func_n2(eql);
identity_f = func_n1(identity);
car_f = func_n1(car);
prog_string = string(progname);