commit 26f6e0730e24921a4f462215dd02816d9a7eeae8
parent 13815696f641e7d0742b3de7c21ff2ed8adaaa6c
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Wed, 20 Apr 2011 00:24:52 -0300
Changed table code to simplify setting and getting of symbols. Also used hash of symbols directly instead of the pointer address. Bugfix: only immutable strings use strhash, mutable strings are compared by pointer.
Diffstat:
3 files changed, 48 insertions(+), 9 deletions(-)
diff --git a/src/Makefile b/src/Makefile
@@ -64,7 +64,7 @@ kmem.o: kmem.c kmem.h klisp.h kerror.h klisp.h kstate.h kgc.h klispconf.h
 kerror.o: kerror.c kerror.h klisp.h kstate.h klisp.h kmem.h kstring.h kpair.h
 kauxlib.o: kauxlib.c kauxlib.h klisp.h kstate.h klisp.h
 kenvironment.o: kenvironment.c kenvironment.h kpair.h kobject.h kerror.h \
-	kmem.h kstate.h klisp.h kgc.h
+	kmem.h kstate.h klisp.h kgc.h ktable.h
 kcontinuation.o: kcontinuation.c kcontinuation.h kmem.h kstate.h kobject.h \
 	klisp.h kgc.h
 koperative.o: koperative.c koperative.h kmem.h kstate.h kobject.h \
@@ -78,7 +78,7 @@ kpromise.o: kpromise.c kpromise.h kmem.h kstate.h kobject.h \
 kport.o: kport.c kport.h kmem.h kstate.h kobject.h klisp.h kerror.h kstring.h \
 	kgc.h
 ktable.o: ktable.c ktable.h kobject.h kstate.h kmem.h klisp.h kgc.h \
-	kapplicative.h kgeqp.h
+	kapplicative.h kgeqp.h kstring.h
 keval.o: keval.c keval.h kcontinuation.h kenvironment.h kstate.h kobject.h \
 	kpair.h kerror.h klisp.h
 krepl.o: krepl.c krepl.h kcontinuation.h kstate.h kobject.h keval.h klisp.h \
diff --git a/src/ktable.c b/src/ktable.c
@@ -5,6 +5,11 @@
 */
 
 /*
+** XXX/TODO: allow KNIL values and keys. Use other value
+** to indicate missing entries (also in kgc.c)
+*/
+
+/*
 ** SOURCE NOTE: This is almost textually from lua.
 ** Parts that don't apply, or don't apply yet to klisp are in comments.
 ** In klisp arrays are indexed from 0, (while in Lua they are indexed from
@@ -13,7 +18,6 @@
 ** that's bad, should probably use a sentinel value that is unavailable
 ** to the program, and throw an error on get of an unsetted value...
 ** for now however stick to the "Lua way"
-** GC: check all of this for possible unrooted objects
 */
 
 /*
@@ -40,7 +44,7 @@
 #include "ktable.h"
 #include "kapplicative.h"
 #include "kgeqp.h"
-
+#include "kstring.h"
 
 /*
 ** max size of array part is 2^MAXBITS
@@ -52,6 +56,7 @@
 #define hashpow2(t,n)      (gnode(t, lmod((n), sizenode(t))))
   
 #define hashstr(t,str)  hashpow2(t, (str)->hash)
+#define hashsym(t,sym)  hashpow2(t, (sym)->hash)
 #define hashboolean(t,p)        hashpow2(t, p? 1 : 0)
 
 
@@ -113,9 +118,12 @@ static Node *mainposition (const Table *t, TValue key) {
   case K_TBOOLEAN:
       return hashboolean(t, bvalue(key));
   case K_TSTRING:
-      return hashstr(t, tv2str(key));
+      if (kstring_immutablep(key))
+	  return hashstr(t, tv2str(key));
+      else /* mutable strings are eq iff they are the same object */
+	  return hashpointer(t, gcvalue(key));
   case K_TSYMBOL:
-      return hashstr(t, tv2str(tv2sym(key)->str));
+      return hashsym(t, tv2sym(key));
   case K_TUSER:
       return hashpointer(t, pvalue(key));
   case K_TAPPLICATIVE: 
@@ -485,10 +493,10 @@ const TValue *klispH_getfixint (Table *t, int32_t key)
 
 
 /*
-** search function for strings
-** (TODO check mutability)
+** search function for immutable strings
 */
 const TValue *klispH_getstr (Table *t, String *key) {
+    klisp_assert(kstring_immutablep(gc2str(key)));
     Node *n = hashstr(t, key);
     do {  /* check whether `key' is somewhere in the chain */
 	if (ttisstring(gkey(n)->this) && tv2str(gkey(n)->this) == key)
@@ -498,6 +506,19 @@ const TValue *klispH_getstr (Table *t, String *key) {
     return &knil;
 }
 
+/*
+** search function for symbol
+*/
+const TValue *klispH_getsym (Table *t, Symbol *key) {
+    Node *n = hashsym(t, key);
+    do {  /* check whether `key' is somewhere in the chain */
+	if (ttissymbol(gkey(n)->this) && tv2sym(gkey(n)->this) == key)
+	    return &gval(n);  /* that's it */
+	else n = gnext(n);
+    } while (n);
+    return &knil;
+}
+
 
 /*
 ** main search function
@@ -506,8 +527,12 @@ const TValue *klispH_get (Table *t, TValue key)
 {
     switch (ttype(key)) {
     case K_TNIL: return &knil;
-    case K_TSTRING: return klispH_getstr(t, tv2str(key));
+    case K_TSYMBOL: return klispH_getsym(t, tv2sym(key));
     case K_TFIXINT: return klispH_getfixint(t, ivalue(key));
+    case K_TSTRING: 
+	if (kstring_immutablep(key))
+	    return klispH_getstr(t, tv2str(key));
+	/* else fall through */
     default: {
 	Node *n = mainposition(t, key);
 	do {  /* check whether `key' is somewhere in the chain */
@@ -552,6 +577,7 @@ TValue *klispH_setfixint (klisp_State *K, Table *t, int32_t key)
 
 TValue *klispH_setstr (klisp_State *K, Table *t, String *key)
 {
+    klisp_assert(kstring_immutablep(gc2str(key)));
     const TValue *p = klispH_getstr(t, key);
     if (p != &knil)
 	return cast(TValue *, p);
@@ -561,6 +587,17 @@ TValue *klispH_setstr (klisp_State *K, Table *t, String *key)
 }
 
 
+TValue *klispH_setsym (klisp_State *K, Table *t, Symbol *key)
+{
+    const TValue *p = klispH_getsym(t, key);
+    if (p != &knil)
+	return cast(TValue *, p);
+    else {
+	return newkey(K, t, gc2sym(key));
+    }
+}
+
+
 /* klisp: Untested, may have off by one errors, check before using */
 static int32_t unbound_search (Table *t, int32_t j) {
   int32_t i = j;  /* i -1 or a present index */
diff --git a/src/ktable.h b/src/ktable.h
@@ -26,6 +26,8 @@ const TValue *klispH_getfixint (Table *t, int32_t key);
 TValue *klispH_setfixint (klisp_State *K, Table *t, int32_t key);
 const TValue *klispH_getstr (Table *t, String *key);
 TValue *klispH_setstr (klisp_State *K, Table *t, String *key);
+const TValue *klispH_getsym (Table *t, Symbol *key);
+TValue *klispH_setsym (klisp_State *K, Table *t, Symbol *key);
 const TValue *klispH_get (Table *t, TValue key);
 TValue *klispH_set (klisp_State *K, Table *t, TValue key);
 TValue klispH_new (klisp_State *K, int32_t narray, int32_t nhash,