[armedbear-cvs] r12165 - trunk/abcl/src/org/armedbear/lisp

Erik Huelsmann ehuelsmann at common-lisp.net
Tue Sep 29 19:09:03 UTC 2009


Author: ehuelsmann
Date: Tue Sep 29 15:08:59 2009
New Revision: 12165

Log:
Removal of duplication of TAGBODY processing code in DO*/DO and TAGBODY.

Modified:
   trunk/abcl/src/org/armedbear/lisp/Do.java
   trunk/abcl/src/org/armedbear/lisp/Lisp.java
   trunk/abcl/src/org/armedbear/lisp/Primitives.java

Modified: trunk/abcl/src/org/armedbear/lisp/Do.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/Do.java	(original)
+++ trunk/abcl/src/org/armedbear/lisp/Do.java	Tue Sep 29 15:08:59 2009
@@ -120,62 +120,21 @@
         list = list.cdr();
       }
     // Look for tags.
-    LispObject remaining = body;
-    while (remaining != NIL)
-      {
-        LispObject current = remaining.car();
-        remaining = remaining.cdr();
-        if (current instanceof Cons)
-          continue;
-        // It's a tag.
-        ext.addTagBinding(current, remaining);
-      }
+    LispObject localTags = preprocessTagBody(body, ext);
+    LispObject blockId = new LispObject();
     try
       {
         // Implicit block.
-        ext.addBlock(NIL, new LispObject());
+        ext.addBlock(NIL, blockId);
         while (true)
           {
             // Execute body.
             // Test for termination.
             if (eval(end_test_form, ext, thread) != NIL)
               break;
-            remaining = body;
-            while (remaining != NIL)
-              {
-                LispObject current = remaining.car();
-                if (current instanceof Cons)
-                  {
-                    try
-                      {
-                        // Handle GO inline if possible.
-                        if (current.car() == Symbol.GO)
-                          {
-                            LispObject tag = current.cadr();
-                            Binding binding = ext.getTagBinding(tag);
-                            if (binding != null && binding.value != null)
-                              {
-                                remaining = binding.value;
-                                continue;
-                              }
-                            throw new Go(tag);
-                          }
-                        eval(current, ext, thread);
-                      }
-                    catch (Go go)
-                      {
-                        LispObject tag = go.getTag();
-                        Binding binding = ext.getTagBinding(tag);
-                        if (binding != null && binding.value != null)
-                          {
-                            remaining = binding.value;
-                            continue;
-                          }
-                        throw go;
-                      }
-                  }
-                remaining = remaining.cdr();
-              }
+
+            processTagBody(body, localTags, ext);
+
             // Update variables.
             if (sequential)
               {
@@ -230,7 +189,7 @@
       }
     catch (Return ret)
       {
-        if (ret.getTag() == NIL)
+        if (ret.getBlock() == blockId)
           {
             return ret.getResult();
           }

Modified: trunk/abcl/src/org/armedbear/lisp/Lisp.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/Lisp.java	(original)
+++ trunk/abcl/src/org/armedbear/lisp/Lisp.java	Tue Sep 29 15:08:59 2009
@@ -626,6 +626,81 @@
     return result;
   }
 
+  public static final LispObject preprocessTagBody(LispObject body,
+                                                   Environment env)
+    throws ConditionThrowable
+  {
+    LispObject localTags = NIL; // Tags that are local to this TAGBODY.
+    while (body != NIL)
+      {
+        LispObject current = body.car();
+        body = ((Cons)body).cdr;
+        if (current instanceof Cons)
+          continue;
+        // It's a tag.
+        env.addTagBinding(current, body);
+        localTags = new Cons(current, localTags);
+      }
+    return localTags;
+  }
+
+  public static final LispObject processTagBody(LispObject body,
+                                                LispObject localTags,
+                                                Environment env)
+    throws ConditionThrowable
+  {
+    LispObject remaining = body;
+    LispThread thread = LispThread.currentThread();
+    while (remaining != NIL)
+      {
+        LispObject current = remaining.car();
+        if (current instanceof Cons)
+          {
+            try {
+              // Handle GO inline if possible.
+              if (((Cons)current).car == Symbol.GO)
+                {
+                  if (interrupted)
+                    handleInterrupt();
+                  LispObject tag = current.cadr();
+                  Binding binding = env.getTagBinding(tag);
+                  if (binding == null)
+                    return error(new ControlError("No tag named " +
+                                                  tag.writeToString() +
+                                                  " is currently visible."));
+                  else if (memql(tag, localTags))
+                    {
+                      if (binding.value != null)
+                        {
+                          remaining = binding.value;
+                          continue;
+                        }
+                    }
+                  throw new Go(tag);
+                }
+              eval(current, env, thread);
+            }
+            catch (Go go)
+              {
+                LispObject tag = go.getTag();
+                if (memql(tag, localTags))
+                  {
+                    Binding binding = env.getTagBinding(tag);
+                    if (binding != null && binding.value != null)
+                      {
+                        remaining = binding.value;
+                        continue;
+                      }
+                  }
+                throw go;
+              }
+          }
+        remaining = ((Cons)remaining).cdr;
+      }
+    thread._values = null;
+    return NIL;
+  }
+
   // Environment wrappers.
   private static final boolean isSpecial(Symbol sym, LispObject ownSpecials,
                                          Environment env)

Modified: trunk/abcl/src/org/armedbear/lisp/Primitives.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/Primitives.java	(original)
+++ trunk/abcl/src/org/armedbear/lisp/Primitives.java	Tue Sep 29 15:08:59 2009
@@ -3496,65 +3496,7 @@
         throws ConditionThrowable
       {
         Environment ext = new Environment(env);
-        LispObject localTags = NIL; // Tags that are local to this TAGBODY.
-        LispObject body = args;
-        while (body != NIL)
-          {
-            LispObject current = body.car();
-            body = ((Cons)body).cdr;
-            if (current instanceof Cons)
-              continue;
-            // It's a tag.
-            ext.addTagBinding(current, body);
-            localTags = new Cons(current, localTags);
-          }
-        final LispThread thread = LispThread.currentThread();
-        LispObject remaining = args;
-        while (remaining != NIL)
-          {
-            LispObject current = remaining.car();
-            if (current instanceof Cons)
-              {
-                try
-                  {
-                    // Handle GO inline if possible.
-                    if (((Cons)current).car == Symbol.GO)
-                      {
-                        if (interrupted)
-                          handleInterrupt();
-                        LispObject tag = current.cadr();
-                        if (memql(tag, localTags))
-                          {
-                            Binding binding = ext.getTagBinding(tag);
-                            if (binding != null && binding.value != null)
-                              {
-                                remaining = binding.value;
-                                continue;
-                              }
-                          }
-                        throw new Go(tag);
-                      }
-                    eval(current, ext, thread);
-                  }
-                catch (Go go)
-                  {
-                    LispObject tag = go.getTag();
-                    if (memql(tag, localTags))
-                      {
-                        Binding binding = ext.getTagBinding(tag);
-                        if (binding != null && binding.value != null)
-                          {
-                            remaining = binding.value;
-                            continue;
-                          }
-                      }
-                    throw go;
-                  }
-              }
-            remaining = ((Cons)remaining).cdr;
-          }
-        thread._values = null;
-        return NIL;
+        return processTagBody(args, preprocessTagBody(args, ext), ext);
       }
     };
 




More information about the armedbear-cvs mailing list