commit f68ac487af96d9b58f0d53ac794a88d53562af72
parent 5b66729c016af058c3f50bed846edb24934ea10f
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Wed,  9 Mar 2011 17:02:20 -0300
Changed bind macros to use throw_extra to allow use of non constant strings as names
Diffstat:
| M | src/kground.c |  |  | 67 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- | 
1 file changed, 59 insertions(+), 8 deletions(-)
diff --git a/src/kground.c b/src/kground.c
@@ -36,13 +36,13 @@
 #define bind_1tp(K_, n_, ptree_, tstr_, t_, v_)	\
     TValue v_; \
     if (!ttispair(ptree_) || !ttisnil(kcdr(ptree_))) { \
-	klispE_throw(K_, n_ ": Bad ptree (expected one argument)"); \
+	klispE_throw_extra(K_, n_ , ": Bad ptree (expected one argument)"); \
 	return; \
     } \
     v_ = kcar(ptree_); \
     if (!t_(v_)) { \
-	klispE_throw(K_, n_ ": Bad type on first argument (expected " \
-		     tstr_ ")");				     \
+	klispE_throw_extra(K_, n_ , ": Bad type on first argument " \
+			   "(expected "	tstr_ ")");     \
 	return; \
     } 
 
@@ -55,17 +55,17 @@
     TValue v1_, v2_;					\
     if (!ttispair(ptree_) || !ttispair(kcdr(ptree_)) || \
 	    !ttisnil(kcddr(ptree_))) {		\
-	klispE_throw(K_, n_ ": Bad ptree (expected two arguments)"); \
+	klispE_throw_extra(K_, n_ , ": Bad ptree (expected two arguments)"); \
 	return; \
     } \
     v1_ = kcar(ptree_); \
     v2_ = kcadr(ptree_); \
     if (!t1_(v1_)) { \
-	klispE_throw(K_, n_ ": Bad type on first argument (expected " \
+	klispE_throw_extra(K_, n_, ": Bad type on first argument (expected " \
 		     tstr1_ ")");				     \
 	return; \
     } else if (!t2_(v2_)) { \
-	klispE_throw(K_, n_ ": Bad type on second argument (expected " \
+	klispE_throw_extra(K_, n_, ": Bad type on second argument (expected " \
 		     tstr2_ ")");				     \
 	return; \
     }
@@ -74,7 +74,7 @@
     TValue v1_, v2_, v3_;					\
     if (!ttispair(ptree_) || !ttispair(kcdr(ptree_)) || \
 	  !ttispair(kcddr (ptree_)) || !ttisnil(kcdddr(ptree_))) {  \
-	klispE_throw(K_, n_ ": Bad ptree (expected tree arguments)"); \
+	klispE_throw_extra(K_, n_, ": Bad ptree (expected tree arguments)"); \
 	return; \
     } \
     v1_ = kcar(ptree_); \
@@ -261,7 +261,58 @@ void set_cdrB(klisp_State *K, TValue *xparams, TValue ptree, TValue denv)
 }
 
 /* 4.7.2 copy-es-immutable */
-/* TODO */
+
+/* Helper (also used by $vau, $lambda, etc) */
+TValue copy_es_immutable_h(klisp_State *K, char *name, TValue ptree);
+
+void copy_es_immutable(klisp_State *K, TValue *xparams, 
+		       TValue ptree, TValue denv)
+{
+    /*
+    ** xparams[0]: copy-es-immutable symbol
+    */
+    char *name = ksymbol_buf(xparams[0]);
+    bind_1p(K, name, ptree, obj);
+
+    TValue copy = copy_es_immutable_h(K, name, obj);
+    kapply_cc(K, copy);
+}
+
+/*
+** This is in a helper method to use it from $lambda, $vau, etc
+**
+** We mark each seen mutable pair with the corresponding copied 
+** immutable pair to construct a structure that is isomorphic to 
+** the original.
+** All objects that aren't mutable pairs are retained without 
+** copying
+** sstack is used to keep track of pairs and tbstack is used
+** to keep track of which of car or cdr we were copying,
+** 0 means just pushed, 1 means return from car, 2 means return from cdr
+*/
+
+#define CEI_ST_PUSH ((char) 0)
+#define CEI_ST_CAR ((char) 1)
+#define CEI_ST_CDR ((char) 2)
+
+TValue copy_es_immutable_h(klisp_State *K, char *name, TValue obj)
+{
+    /* 
+    ** GC: obj is rooted because it is in the stack at all times.
+    ** The copied pair should be kept safe some other way
+    */
+    TValue copy = obj;
+
+    ks_spush(K, obj);
+    ks_tbpush(K, CEI_ST_PUSH);
+
+    while(!ks_sisempty(K)) {
+	char state = ks_tbpop(K);
+    }
+
+    return copy;
+}
+
 
 /*
 ** 4.8 Environments