changed lisp_free to an iterative algorithm
authorMatthias Braun <matze@braunis.de>
Mon, 28 Jun 2004 22:01:29 +0000 (22:01 +0000)
committerMatthias Braun <matze@braunis.de>
Mon, 28 Jun 2004 22:01:29 +0000 (22:01 +0000)
SVN-Revision: 1517

src/lispreader.cpp

index 3a0c7b1..83b4fbf 100644 (file)
@@ -20,8 +20,8 @@
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
-
 #include <iostream>
+#include <queue>
 #include <string>
 #include <cctype>
 #include <cstdlib>
@@ -506,30 +506,43 @@ lisp_free (lisp_object_t *obj)
   if (obj == 0)
     return;
 
-  switch (obj->type)
-    {
-    case LISP_TYPE_INTERNAL :
-    case LISP_TYPE_PARSE_ERROR :
-    case LISP_TYPE_EOF :
-      return;
-
-    case LISP_TYPE_SYMBOL :
-    case LISP_TYPE_STRING :
-      free(obj->v.string);
-      break;
-
-    case LISP_TYPE_CONS :
-    case LISP_TYPE_PATTERN_CONS :
-      lisp_free(obj->v.cons.car);
-      lisp_free(obj->v.cons.cdr);
-      break;
-
-    case LISP_TYPE_PATTERN_VAR :
-      lisp_free(obj->v.pattern.sub);
-      break;
+  /** We have to use this iterative code, because the recursive function
+   * produces a stack overflow and crashs on OSX 10.2
+   */
+  std::queue<lisp_object_t*> objs;
+  objs.push(obj);
+
+  while(!objs.empty()) {
+    lisp_object_t* obj = objs.front();
+    objs.pop();
+        
+    switch (obj->type) {
+      case LISP_TYPE_INTERNAL :
+      case LISP_TYPE_PARSE_ERROR :
+      case LISP_TYPE_EOF :
+        return;
+
+      case LISP_TYPE_SYMBOL :
+      case LISP_TYPE_STRING :
+        free(obj->v.string);
+        break;
+
+      case LISP_TYPE_CONS :
+      case LISP_TYPE_PATTERN_CONS :
+        if(obj->v.cons.car)
+          objs.push(obj->v.cons.car);
+        if(obj->v.cons.cdr)
+          objs.push(obj->v.cons.cdr);
+        break;
+
+      case LISP_TYPE_PATTERN_VAR :
+        if(obj->v.pattern.sub)
+          objs.push(obj->v.pattern.sub);
+        break;
     }
 
-  free(obj);
+    free(obj);
+  }
 }
 
 lisp_object_t*