[e-cvs] cvs commit: e/src/jsrc/org/quasiliteral/term Functor.java Term.java Term.updoc TermBuilder.java TermParser.java term.y

markm@eros.cs.jhu.edu markm@eros.cs.jhu.edu
Tue, 4 Dec 2001 19:46:12 -0500


markm       01/12/04 19:46:11

  Modified:    src/jsrc/org/erights/e/elang/syntax ELexer.java EParser.java
                        e.y
               src/jsrc/org/erights/e/elib/base MessageDesc.java
                        MethodNode.java ParamDesc.java
               src/jsrc/org/erights/e/elib/prim ConstructorNode.java
                        InstanceMethodNode.java JavaMemberNode.java
                        StaticMethodNode.java SugarMethodNode.java
                        VarGetterNode.java VarSetterNode.java
               src/jsrc/org/quasiliteral/astro Astro.java
                        AstroLexerSharedInputState.java AstroSchema.java
                        AstroTag.java BaseSchema.java
               src/jsrc/org/quasiliteral/syntax BaseLexer.java
                        FileFeeder.java TwineFeeder.java
               src/jsrc/org/quasiliteral/term Functor.java Term.java
                        Term.updoc TermBuilder.java TermParser.java term.y
  Added:       src/jsrc/org/quasiliteral/astro ASTBuilder.java
                        AstroBuilder.java
  Log:
  snapshot before removing Functor

Revision  Changes    Path
1.71      +2 -2      e/src/jsrc/org/erights/e/elang/syntax/ELexer.java

Index: ELexer.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/syntax/ELexer.java,v
retrieving revision 1.70
retrieving revision 1.71
diff -u -r1.70 -r1.71
--- ELexer.java	2001/12/03 03:30:54	1.70
+++ ELexer.java	2001/12/05 00:46:09	1.71
@@ -27,7 +27,7 @@
 import org.quasiliteral.astro.AstroToken;
 import org.quasiliteral.astro.AstroTag;
 import org.quasiliteral.astro.AstroBuilder;
-import org.quasiliteral.astro.BaseBuilder;
+import org.quasiliteral.astro.ASTBuilder;
 import org.quasiliteral.syntax.BaseLexer;
 import org.quasiliteral.syntax.FileFeeder;
 import org.quasiliteral.syntax.LineFeeder;
@@ -50,7 +50,7 @@
      *
      */
     static public final AstroBuilder FOR_ASTS =
-      new BaseBuilder(EParser.DEFAULT_SCHEMA);
+      new ASTBuilder(EParser.DEFAULT_SCHEMA);
 
     /**
      *



1.108     +1 -1      e/src/jsrc/org/erights/e/elang/syntax/EParser.java

Index: EParser.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/syntax/EParser.java,v
retrieving revision 1.107
retrieving revision 1.108
diff -u -r1.107 -r1.108
--- EParser.java	2001/12/03 03:30:54	1.107
+++ EParser.java	2001/12/05 00:46:09	1.108
@@ -1600,7 +1600,7 @@
  *
  */
 static public final AstroSchema DEFAULT_SCHEMA =
-  new BaseSchema(ConstList.fromArray(TheTokens));
+  new BaseSchema("E-Language", ConstList.fromArray(TheTokens));
 
 /**
  * These are the tokens that may appear at the end of a line, in which



1.98      +1 -1      e/src/jsrc/org/erights/e/elang/syntax/e.y

Index: e.y
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/syntax/e.y,v
retrieving revision 1.97
retrieving revision 1.98
diff -u -r1.97 -r1.98
--- e.y	2001/12/03 03:30:55	1.97
+++ e.y	2001/12/05 00:46:10	1.98
@@ -1647,7 +1647,7 @@
  *
  */
 static public final AstroSchema DEFAULT_SCHEMA =
-  new BaseSchema(ConstList.fromArray(TheTokens));
+  new BaseSchema("E-Language", ConstList.fromArray(TheTokens));
 
 /**
  * These are the tokens that may appear at the end of a line, in which



1.10      +17 -2     e/src/jsrc/org/erights/e/elib/base/MessageDesc.java

Index: MessageDesc.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/base/MessageDesc.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- MessageDesc.java	2001/11/10 19:40:44	1.9
+++ MessageDesc.java	2001/12/05 00:46:10	1.10
@@ -26,6 +26,9 @@
 import org.erights.e.elib.prim.StaticMaker;
 import org.erights.e.elib.serial.Persistent;
 import org.erights.e.elib.tables.ConstList;
+import org.erights.e.elib.slot.ValueGuard;
+import org.erights.e.elib.slot.NullOkMaker;
+import org.erights.e.elib.slot.SlotGuard;
 
 import java.io.IOException;
 
@@ -56,6 +59,11 @@
         out.lnPrint(" */");
     }
 
+    /**
+     * @param retType In order to avoid a circular dependency, this variable
+     * can hold a Class instead of a SlotGuard, in which case it will be
+     * converted to a SlotGuard as needed.
+     */
     public MessageDesc(String docComment,
                        String verb,
                        ConstList params,
@@ -78,8 +86,15 @@
         return myParams;
     }
 
-    public Object getReturnType() {
-        return myRetType;
+    public ValueGuard getReturnType() {
+        if (myRetType instanceof Class) {
+            Class clazz = (Class)myRetType;
+            myRetType = ClassDesc.make(clazz);
+            if (! clazz.isPrimitive()) {
+                myRetType = NullOkMaker.THE_ONE.run((ValueGuard)myRetType);
+            }
+        }
+        return (ValueGuard)myRetType;
     }
 
     public void printOn(TextWriter out) throws IOException {



1.18      +3 -2      e/src/jsrc/org/erights/e/elib/base/MethodNode.java

Index: MethodNode.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/base/MethodNode.java,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- MethodNode.java	2001/11/10 19:40:44	1.17
+++ MethodNode.java	2001/12/05 00:46:10	1.18
@@ -22,6 +22,7 @@
 import org.erights.e.elib.quasi.MatchMaker;
 import org.erights.e.elib.slot.SimpleSlotMaker;
 import org.erights.e.elib.slot.ValueGuard;
+import org.erights.e.elib.slot.SlotGuard;
 import org.erights.e.elib.tables.ConstList;
 import org.erights.e.elib.tables.FlexList;
 import org.erights.e.elib.tables.FlexMap;
@@ -76,13 +77,13 @@
      * Should be overridden by subclasses that can be more informative
      */
     public MessageDesc makeMessageType(String verb) {
-        ValueGuard any = SimpleSlotMaker.THE_ONE;
+        SlotGuard any = SimpleSlotMaker.THE_ONE;
         ParamDesc[] pType1 = { new ParamDesc(null, any) };
         ConstList pTypes = ConstList.fromArray(pType1).multiply(arity());
         return new MessageDesc("Missing docComment",
                                verb,
                                pTypes,
-                               any);
+                               (ValueGuard)any);
     }
 
     /**



1.10      +21 -4     e/src/jsrc/org/erights/e/elib/base/ParamDesc.java

Index: ParamDesc.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/base/ParamDesc.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- ParamDesc.java	2001/11/10 19:40:44	1.9
+++ ParamDesc.java	2001/12/05 00:46:10	1.10
@@ -25,6 +25,9 @@
 import org.erights.e.elib.prim.E;
 import org.erights.e.elib.prim.StaticMaker;
 import org.erights.e.elib.serial.Persistent;
+import org.erights.e.elib.slot.SlotGuard;
+import org.erights.e.elib.slot.NullOkMaker;
+import org.erights.e.elib.slot.ValueGuard;
 
 import java.io.IOException;
 
@@ -39,11 +42,18 @@
     /** @serial Writes "_" for anonymous parameter */
     private String myName;
 
-    /** @serial Any object that acts like an E type */
+    /**
+     * @serial Guards the parameter variable.
+     * In order to avoid a circular dependency, this variable can hold a
+     * Class instead of a SlotGuard, in which case it will be converted to
+     * a SlotGuard as needed.
+     */
     private Object myType;
 
     /**
-     *
+     * @param type In order to avoid a circular dependency, this variable
+     * can hold a Class instead of a SlotGuard, in which case it will be
+     * converted to a SlotGuard as needed.
      */
     public ParamDesc(String optName, Object type) {
         if (null == optName) {
@@ -64,8 +74,15 @@
     /**
      *
      */
-    public Object getType() {
-        return myType;
+    public SlotGuard getType() {
+        if (myType instanceof Class) {
+            Class clazz = (Class)myType;
+            myType = ClassDesc.make(clazz);
+            if (! clazz.isPrimitive()) {
+                myType = NullOkMaker.THE_ONE.run((ValueGuard)myType);
+            }
+        }
+        return (SlotGuard)myType;
     }
 
     /**



1.18      +8 -0      e/src/jsrc/org/erights/e/elib/prim/ConstructorNode.java

Index: ConstructorNode.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/prim/ConstructorNode.java,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- ConstructorNode.java	2001/12/02 06:01:45	1.17
+++ ConstructorNode.java	2001/12/05 00:46:10	1.18
@@ -84,6 +84,14 @@
     }
 
     /**
+     * The return type is the declaring class of the Constructor, since we're
+     * not concerned about 'super(...)' invocations.
+     */
+    protected Class returnType() {
+        return ((Constructor)member()).getDeclaringClass();
+    }
+
+    /**
      *
      */
     public Class receiverType() {



1.17      +7 -0      e/src/jsrc/org/erights/e/elib/prim/InstanceMethodNode.java

Index: InstanceMethodNode.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/prim/InstanceMethodNode.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- InstanceMethodNode.java	2001/12/02 06:01:45	1.16
+++ InstanceMethodNode.java	2001/12/05 00:46:10	1.17
@@ -109,6 +109,13 @@
     /**
      *
      */
+    protected Class returnType() {
+        return ((Method)member()).getReturnType();
+    }
+
+    /**
+     *
+     */
     public Class receiverType() {
         return member().getDeclaringClass();
     }



1.32      +27 -0     e/src/jsrc/org/erights/e/elib/prim/JavaMemberNode.java

Index: JavaMemberNode.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/prim/JavaMemberNode.java,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- JavaMemberNode.java	2001/12/02 06:01:45	1.31
+++ JavaMemberNode.java	2001/12/05 00:46:10	1.32
@@ -23,11 +23,18 @@
 import org.erights.e.elib.base.ClassDesc;
 import org.erights.e.elib.base.Ejector;
 import org.erights.e.elib.base.MethodNode;
+import org.erights.e.elib.base.MessageDesc;
+import org.erights.e.elib.base.ParamDesc;
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.ref.Ref;
 import org.erights.e.elib.tables.FlexList;
 import org.erights.e.elib.tables.FlexMap;
+import org.erights.e.elib.tables.ConstList;
 import org.erights.e.elib.util.OneArgFunc;
+import org.erights.e.elib.slot.ValueGuard;
+import org.erights.e.elib.slot.SimpleSlotMaker;
+import org.erights.e.elib.slot.NullOkMaker;
+import org.erights.e.elib.slot.SlotGuard;
 
 import java.io.IOException;
 import java.lang.reflect.Member;
@@ -57,6 +64,21 @@
     /**
      *
      */
+    public MessageDesc makeMessageType(String verb) {
+        Class[] paramTypes = parameterTypes();
+        ParamDesc[] paramDescs = new ParamDesc[paramTypes.length];
+        for (int i = 0; i < paramTypes.length; i++) {
+            paramDescs[i] = new ParamDesc(null, paramTypes[i]);
+        }
+        return new MessageDesc("Missing docComment",
+                               verb,
+                               ConstList.fromArray(paramDescs),
+                               returnType());
+    }
+
+    /**
+     *
+     */
     public String verb() {
         //Note: the result isn't necessarily interned, but that's ok.
         String result = myMember.getName();
@@ -216,6 +238,11 @@
      *
      */
     protected abstract Class[] parameterTypes();
+
+    /**
+     *
+     */
+    protected abstract Class returnType();
 
     /**
      *



1.21      +7 -0      e/src/jsrc/org/erights/e/elib/prim/StaticMethodNode.java

Index: StaticMethodNode.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/prim/StaticMethodNode.java,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- StaticMethodNode.java	2001/12/02 06:01:46	1.20
+++ StaticMethodNode.java	2001/12/05 00:46:10	1.21
@@ -116,6 +116,13 @@
     /**
      *
      */
+    protected Class returnType() {
+        return ((Method)member()).getReturnType();
+    }
+
+    /**
+     *
+     */
     public Class receiverType() {
         return StaticMaker.class;
     }



1.19      +7 -0      e/src/jsrc/org/erights/e/elib/prim/SugarMethodNode.java

Index: SugarMethodNode.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/prim/SugarMethodNode.java,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- SugarMethodNode.java	2001/11/10 19:40:45	1.18
+++ SugarMethodNode.java	2001/12/05 00:46:10	1.19
@@ -150,6 +150,13 @@
     }
 
     /**
+     *
+     */
+    protected Class returnType() {
+        return ((Method)member()).getReturnType();
+    }
+
+    /**
      * If the printOkFlag is not set, then suppress printing of this
      * method node.
      */



1.15      +7 -0      e/src/jsrc/org/erights/e/elib/prim/VarGetterNode.java

Index: VarGetterNode.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/prim/VarGetterNode.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- VarGetterNode.java	2001/12/02 06:01:46	1.14
+++ VarGetterNode.java	2001/12/05 00:46:10	1.15
@@ -67,6 +67,13 @@
     /**
      *
      */
+    protected Class returnType() {
+        return ((Field)member()).getType();
+    }
+
+    /**
+     *
+     */
     public Class receiverType() {
         if (Modifier.isStatic(member().getModifiers())) {
             return StaticMaker.class;



1.14      +9 -0      e/src/jsrc/org/erights/e/elib/prim/VarSetterNode.java

Index: VarSetterNode.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/prim/VarSetterNode.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- VarSetterNode.java	2001/12/02 06:01:46	1.13
+++ VarSetterNode.java	2001/12/05 00:46:10	1.14
@@ -19,6 +19,8 @@
 Contributor(s): ______________________________________.
 */
 
+import org.erights.e.elib.slot.VoidMaker;
+
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 
@@ -66,6 +68,13 @@
     public Class[] parameterTypes() {
         Class[] result = { ((Field)member()).getType() };
         return result;
+    }
+
+    /**
+     *
+     */
+    protected Class returnType() {
+        return Void.TYPE;
     }
 
     /**



1.6       +21 -7     e/src/jsrc/org/quasiliteral/astro/Astro.java

Index: Astro.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/astro/Astro.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- Astro.java	2001/12/03 03:30:55	1.5
+++ Astro.java	2001/12/05 00:46:11	1.6
@@ -45,6 +45,13 @@
     }
 
     /**
+     *
+     */
+    public String toString() {
+        return "" + myOptToken;
+    }
+
+    /**
      * Builds an equivalent of this AST using the building methods of
      * 'builder'.
      * <p>
@@ -55,11 +62,15 @@
      */
     public Object build(AstroBuilder builder) {
         Object func = AstroToken.build(myOptToken, builder);
+        Astro optSub = (Astro)getFirstChild();
+        if (null == optSub) {
+            //This case is broken out in order to allow 'func' to be a Node
+            //rather than a Leaf.  This would happen is myOptToken is
+            //a composite.
+            return builder.node(func);
+        }
         Object args = builder.argList();
-        for (Astro optSub = (Astro)getFirstChild();
-             null != optSub;
-             optSub = (Astro)optSub.getNextSibling()) {
-
+        for (; null != optSub; optSub = (Astro)optSub.getNextSibling()) {
             args = builder.argList(args, optSub.build(builder));
         }
         return builder.node(func, args);
@@ -82,10 +93,13 @@
         } else {
             Object func = builder.leafTag(self.getType(),
                                           Twine.fromString(self.getText()));
+            AST optSub = self.getFirstChild();
+            if (null == optSub) {
+                //See comment in build/1 above
+                return builder.node(func);
+            }
             Object args = builder.argList();
-            for (AST optSub = self.getFirstChild();
-                 null != optSub;
-                 optSub = optSub.getNextSibling()) {
+            for (; null != optSub; optSub = optSub.getNextSibling()) {
 
                 args = builder.argList(args, build(optSub, builder));
             }



1.4       +8 -0      e/src/jsrc/org/quasiliteral/astro/AstroLexerSharedInputState.java

Index: AstroLexerSharedInputState.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/astro/AstroLexerSharedInputState.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- AstroLexerSharedInputState.java	2001/11/27 07:27:54	1.3
+++ AstroLexerSharedInputState.java	2001/12/05 00:46:11	1.4
@@ -40,6 +40,14 @@
         this(s, null);
     }
 
+    public String toString() {
+        if (null == mySourceURL) {
+            return "<AstroLexerSharedInputState>";
+        } else {
+            return "<AstroLexerSharedInputState:" + mySourceURL + ">";
+        }
+    }
+
     /**
      * Get the current line of this instance.
      *



1.6       +6 -0      e/src/jsrc/org/quasiliteral/astro/AstroSchema.java

Index: AstroSchema.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/astro/AstroSchema.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- AstroSchema.java	2001/12/03 03:30:55	1.5
+++ AstroSchema.java	2001/12/05 00:46:11	1.6
@@ -13,6 +13,12 @@
 public interface AstroSchema extends PassByConstruction, Persistent {
 
     /**
+     * The name of the language this is a Schema for, for diagnostic purposes
+     * only.
+     */
+    String getName();
+
+    /**
      * Returns the tag represented by this type code in the grammar described
      * by this schema, or null.
      */



1.3       +6 -0      e/src/jsrc/org/quasiliteral/astro/AstroTag.java

Index: AstroTag.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/astro/AstroTag.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- AstroTag.java	2001/12/01 07:52:14	1.2
+++ AstroTag.java	2001/12/05 00:46:11	1.3
@@ -50,6 +50,12 @@
         myOptSchema = optSchema;
     }
 
+    public String toString() {
+        return "<" + myTypeName +
+          (null == myOptSchema ? "" : (":" + myOptSchema)) +
+          ">";
+    }
+
     /**
      * The enumerated type code, or Token.INVALID_TYPE.
      */



1.6       +22 -1     e/src/jsrc/org/quasiliteral/astro/BaseSchema.java

Index: BaseSchema.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/astro/BaseSchema.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- BaseSchema.java	2001/12/03 03:30:55	1.5
+++ BaseSchema.java	2001/12/05 00:46:11	1.6
@@ -20,6 +20,11 @@
 public class BaseSchema implements AstroSchema {
 
     /**
+     * For diagnostic purposes only.
+     */
+    private final String myName;
+
+    /**
      *
      */
     private final AstroTag[] myByTypeCodes;
@@ -52,7 +57,9 @@
     /**
      *
      */
-    public BaseSchema(ConstList typeNames) {
+    public BaseSchema(String name, ConstList typeNames) {
+        myName = name;
+
         FlexList byCodes = FlexList.fromType(AstroTag.class,
                                              typeNames.size());
         FlexMap byNames = FlexMap.fromTypes(String.class,
@@ -69,6 +76,20 @@
         }
         myByTypeCodes = (AstroTag[])byCodes.getArray(AstroTag.class);
         myByTypeName = byNames.snapshot();
+    }
+
+    /**
+     *
+     */
+    public String toString() {
+        return "<Schema for " + myName + ">";
+    }
+
+    /**
+     *
+     */
+    public String getName() {
+        return myName;
     }
 
     /**



1.1                  e/src/jsrc/org/quasiliteral/astro/ASTBuilder.java

Index: ASTBuilder.java
===================================================================
package org.quasiliteral.astro;

import org.erights.e.elib.prim.E;
import org.erights.e.elib.tables.Twine;

//This file is hereby placed in the public domain

/**
 * The default implementation (and default superclass) for implementing
 * AstroBuilder simply, for building Astro-trees with AstroToken leaves.
 * <p>
 * The type parameterization of AstroBuilder is: <pre>
 *     Leaf is AstroToken
 *     Node is Astro
 *     Arg is Astro
 *     Args is null (for empty list) or Astro (for it and its siblings).
 * </pre>
 *
 * @author <a href="mailto:markm@caplet.com">Mark Miller</a>
 */
public class ASTBuilder implements AstroBuilder {

    /**
     *
     */
    private final AstroSchema mySchema;

    /**
     *
     */
    public ASTBuilder(AstroSchema schema) {
        mySchema = schema;
    }

    /**
     *
     */
    public String toString() {
        return "<building ASTs for " + mySchema.getName() + ">";
    }

    /**
     *
     */
    public AstroSchema getSchema() {
        return mySchema;
    }

    /**
     * @return :AstroToken
     */
    public Object leafTag(int typeCode, Twine source) {
        return new AstroToken(mySchema.getTagForCode(typeCode), null, source);
    }

    /**
     * @param data Must not be null
     * @param source
     * @return :AstroToken
     */
    public Object leafData(Object data, Twine source) {
        return new AstroToken(mySchema.getLiteralDataTag(data), data, source);
    }

    /**
     * Returns a complex token rather than a AST.
     *
     * @param data Nust not be null
     * @return :AstroToken
     */
    public Object composite(int typeCode, Object data, Twine source) {
        return new AstroToken(mySchema.getTagForCode(typeCode), data, source);
    }

    /**
     * @param leaf :AstroToken
     */
    public int getCodeOfLeaf(Object leaf) {
        return ((AstroToken)leaf).getType();
    }

    /**
     * @param func :(AstroToken | Astro)
     * @return :Astro
     */
    public Object node(Object func) {
        if (func instanceof Astro) {
            return func;
        }
        return new Astro((AstroToken)func);
    }

    /**
     * @param func :AstroToken
     * @param args :(Astro | null)
     * @return :Astro
     */
    public Object node(Object func, Object args) {
        AstroToken funcToken = (AstroToken)func;
        Astro optArgs = (Astro)args;
        Astro result = new Astro(funcToken);
        for (; null != optArgs; optArgs = (Astro)optArgs.getNextSibling()) {
            result.addChild(optArgs);
        }
        return result;
    }

    /**
     * @return null
     */
    public Object argList() {
        return null;
    }

    /**
     * Returns 'first' after severing its nest sibling pointer
     *
     * @param first :Astro
     * @return :Astro
     */
    public Object argList(Object first) {
        Astro result = (Astro)first;
        result.setNextSibling(null);
        return result;
    }

    /**
     * Modifies the last sibling in 'list' to be 'next', which is modified to
     * not have any further siblings.
     *
     * @param list :(Astro | null)
     * @param next :Astro
     * @return :Astro
     */
    public Object argList(Object list, Object next) {
        Astro optList = (Astro)list;
        Astro nextNode = (Astro)next;
        nextNode.setNextSibling(null);
        if (null == optList) {
            return next;
        }
        Astro sib = optList;
        while (true) {
            Astro optNextSib = (Astro)sib.getNextSibling();
            if (null == optNextSib) {
                sib.setNextSibling(nextNode);
                return optList;
            }
            sib = optNextSib;
        }
    }
}



1.1                  e/src/jsrc/org/quasiliteral/astro/AstroBuilder.java

Index: AstroBuilder.java
===================================================================
package org.quasiliteral.astro;

import org.erights.e.elib.serial.PassByConstruction;
import org.erights.e.elib.serial.Persistent;
import org.erights.e.elib.tables.Twine;

//This file is hereby placed in the public domain

/**
 * Used to describe an Antlr grammar, and to build a tree that could represent
 * the results of parsing such a grammar.
 * <p>
 * Several arguments and return types are 'Object' below because the actual
 * types are to be determined by the implementors of AstroBuilder.  However,
 * these choices need to be consistent.  We express the required consistency
 * using pretend parameterized types encoded in the javadoc comments.
 * Concrete subclasses of AstroBuilder should say what concrete types they use
 * for these parameterized types.
 * <p>
 * The pretend parameterized types are: <pre>
 *     Leaf -- Leaves of the tree, representing tokens of the grammar.
 *     Node -- Lnternal nodes of the tree, looks like application of a Leaf
 *             as an functor to Args.
 *     Arg -- An individual argument in a list of arguments.  Typically the
 *            same as Node, but not always.  See QuasiTermBuilder.
 *     Args -- Represents a list of Arg.
 * </pre>
 *
 * @author <a href="mailto:markm@caplet.com">Mark Miller</a>
 */
public interface AstroBuilder extends PassByConstruction, Persistent {

    /**
     * Describes the grammar whose trees we're building.
     */
    AstroSchema getSchema();

    /**
     * Makes a Leaf (eg, a Token or Functor) not representing literal data,
     * but just a type code
     *
     * @return :Leaf
     */
    Object leafTag(int typeCode, Twine source);

    /**
     * Makes a leaf (eg, a Token or Functor) representing literal data
     *
     * @return :Leaf
     */
    Object leafData(Object data, Twine source);

    /**
     * Makes a Leaf or Node representing the given type code as parameterized
     * by the given data.
     * <p>
     * Exists to support legacy usage of Antlr Tokens, and in order to allow
     * lexers, which wish to emit composites, to still emit only leaves if
     * allowed by the concrete builder.
     * <p>
     * Builders that don't allow composite leaves (like TermBuilder) should
     * instead emit the equivalent of <pre>
     *     node(leafTag(typeCode, src),
     *          argList(node(leafData(data, src), argList())))
     * </pre>
     *
     * @return :(Leaf | Node)
     */
    Object composite(int typeCode, Object data, Twine source);

    /**
     * Given a Leaf that could have been produced by this builder, return its
     * type code.
     *
     * @param leaf :Leaf
     * @return The leaf's type code.
     */
    int getCodeOfLeaf(Object leaf);

    /**
     * Names an internal node (eg, an AST or Term), for which 'func' is the
     * "label" and there are no arguments.
     * <p>
     * To accomodate composites, which may be Leaves in one representation and
     * Nodes in another, 'node' accepts a 'func' that's a Node, in which case
     * that Node is returned.
     *
     * @param func :(Leaf | Node)
     * @return :Node
     */
    Object node(Object func);

    /**
     * Names an internal node (eg, an AST or Term), for which 'func' is the
     * "label" and 'args' are the arguments.
     * <p>
     * May be destructive of 'args'.
     *
     * @param func :Leaf
     * @param args :Args
     * @return :Node
     */
    Object node(Object func, Object args);

    /**
     * The empty args list
     *
     * @return :Args
     */
    Object argList();

    /**
     * The args list of one element.
     * <p>
     * May be destructive of that element, as when it's an AST.
     * <p>
     * Should be equivalent to 'argList(argList(), first)'
     *
     * @param first :Arg
     * @return :Args
     */
    Object argList(Object first);

    /**
     * Extend args list with an additional term, like a backwards cons.
     * <p>
     * May be destructive of 'list' and 'next'
     *
     * @param list :Args
     * @param next :Arg
     * @return :Args
     */
    Object argList(Object list, Object next);
}



1.3       +8 -1      e/src/jsrc/org/quasiliteral/syntax/BaseLexer.java

Index: BaseLexer.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/syntax/BaseLexer.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- BaseLexer.java	2001/12/03 03:30:55	1.2
+++ BaseLexer.java	2001/12/05 00:46:11	1.3
@@ -121,6 +121,13 @@
     }
 
     /**
+     *
+     */
+    public String toString() {
+        return "<Lexing " + myBuilder.getSchema().getName() + ">";
+    }
+
+    /**
      * Does not affect the partial flag
      */
     public void setSource(Twine newSource) {
@@ -225,7 +232,7 @@
     }
 
     /**
-     * @return :Leaf (see {@link AstroBuilder}
+     * @return :Leaf (see {@link AstroBuilder})
      */
     public Object nextToken() throws IOException, SyntaxException {
         try {



1.2       +7 -0      e/src/jsrc/org/quasiliteral/syntax/FileFeeder.java

Index: FileFeeder.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/syntax/FileFeeder.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- FileFeeder.java	2001/12/02 18:42:02	1.1
+++ FileFeeder.java	2001/12/05 00:46:11	1.2
@@ -58,6 +58,13 @@
     /**
      *
      */
+    public String toString() {
+        return "<Feeding from " + myUrl + ">";
+    }
+
+    /**
+     *
+     */
     public Twine optNextLine(boolean quoted,
                              int indent,
                              char closer,



1.2       +7 -0      e/src/jsrc/org/quasiliteral/syntax/TwineFeeder.java

Index: TwineFeeder.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/syntax/TwineFeeder.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TwineFeeder.java	2001/12/02 18:42:02	1.1
+++ TwineFeeder.java	2001/12/05 00:46:11	1.2
@@ -44,6 +44,13 @@
     /**
      *
      */
+    public String toString() {
+        return "<TwineFeeder>";
+    }
+
+    /**
+     *
+     */
     public Twine optNextLine(boolean quoted,
                              int indent,
                              char closer,



1.14      +44 -1     e/src/jsrc/org/quasiliteral/term/Functor.java

Index: Functor.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/term/Functor.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- Functor.java	2001/12/03 03:30:56	1.13
+++ Functor.java	2001/12/05 00:46:11	1.14
@@ -1,6 +1,7 @@
 package org.quasiliteral.term;
 
 import org.erights.e.elib.prim.StaticMaker;
+import org.erights.e.elib.prim.E;
 import org.erights.e.elib.serial.PassByConstruction;
 import org.erights.e.elib.serial.Persistent;
 import org.erights.e.elib.tables.Selfless;
@@ -11,8 +12,27 @@
 //This file is hereby placed in the public domain
 
 /**
+ * Like an Antlr {@link Token}, but with differences that make it suitable
+ * for quasiliteral processing.
+ * <p>
+ * The differences are
+ * <ul>
+ * <li>It knows how to convert to and from an Antlr Token, in a way that
+ *     preserves the semantics of vanilla Tokens.
+ * <li>It's PassByCopy, necessitating it be Immutable.</li>
+ * <li>The token-type is identified by a string instead of a number,
+ *     enabling it to make sense wrt a source grammar instead of a compiled
+ *     grammar.</li>
+ * <li>The token-text is a {@link Twine} instead of a string, and can
+ *     therefore remember its source positions.</li>
+ * <li>The semantically significant value is separate from the source
+ *     text.</li>
+ * <li>It has a convenient printed form.</li>
+ * </ul>
  *
- * @author <a href="mailto:markm@caplet.com">Mark Miller</a>
+ * @author <a href="mailto:markm@caplet.com">Mark S Miller</a>
+ * @author Many ideas from Danfuzz Bornstein
+ * @author Many thanks also to Dean Tribble
  */
 public class Functor
   implements Selfless, PassByConstruction, Persistent {
@@ -53,6 +73,29 @@
         myTag = tag;
         myOptData = optData;
         mySource = source;
+    }
+
+    /**
+     * quasiFlag defaults to false.
+     */
+    public String toString() {
+        return toString(false);
+    }
+
+    /**
+     *
+     */
+    public String toString(boolean quasiFlag) {
+        if (null == myOptData) {
+            return myTag.getTypeName().bare();
+        }
+        Twine result = E.toQuote(myOptData);
+        if (quasiFlag) {
+            result.replaceAll("@", "@@");
+            result.replaceAll("$", "$$");
+            result.replaceAll("`", "``");
+        }
+        return result.bare();
     }
 
     /**



1.10      +56 -1     e/src/jsrc/org/quasiliteral/term/Term.java

Index: Term.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/term/Term.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- Term.java	2001/12/03 03:30:56	1.9
+++ Term.java	2001/12/05 00:46:11	1.10
@@ -5,13 +5,29 @@
 import org.erights.e.elib.serial.Persistent;
 import org.erights.e.elib.tables.ConstList;
 import org.erights.e.elib.tables.Selfless;
+import org.erights.e.develop.format.StringHelper;
 import org.quasiliteral.astro.AstroBuilder;
 
 //This file is hereby placed in the public domain
 
 /**
+ * Like an Antlr {@link AST}, but with differences that make it suitable for
+ * quasiliteral processing.
+ * <p>
+ * The differences are:<ul>
+ * <li>It knows how to convert to and from an Antlr AST, in a way that
+ *     mostly preserves the semantics of vanilla ASTs.
+ * <li>It's PassByCopy, necessitating it be Immutable.</li>
+ * <li>Each Term only points downward, not rightward, making them
+ *     sharable by different containing contexts.</li>
+ * <li>The functor is a {@link Functor}, which is likewise like an Antlr
+ *     {@link Token}, rather than just storing a String and an int.</li>
+ * <li>It has a more conventional printed form, like a prolog term tree.</li>
+ * </ul>
  *
- * @author <a href="mailto:markm@caplet.com">Mark Miller</a>
+ * @author <a href="mailto:markm@caplet.com">Mark S Miller</a>
+ * @author Many ideas from Danfuzz Bornstein
+ * @author Many thanks also to Dean Tribble
  */
 public class Term
   implements Selfless, PassByConstruction, Persistent {
@@ -41,6 +57,38 @@
     }
 
     /**
+     *
+     */
+    public String toString() {
+        return "term`" + toString("     ", true) + "`";
+    }
+
+    /**
+     *
+     */
+    public String toString(String prefix, boolean quasiFlag) {
+        String func = myFunctor.toString(quasiFlag);
+        int len = myArgs.size();
+        if (0 == len) {
+            return func;
+        }
+        StringBuffer buf = new StringBuffer(func);
+        buf.append("(");
+        int indentCount = func.length() + 1; //for the "("
+        String indent = prefix + StringHelper.multiply(" ", indentCount);
+        Term child = (Term)myArgs.get(0);
+        buf.append(child.toString(indent, quasiFlag));
+        for (int i = 1; i < len; i++) {
+            buf.append(",\n");
+            buf.append(indent);
+            child = (Term)myArgs.get(i);
+            buf.append(child.toString(indent, quasiFlag));
+        }
+        buf.append(")");
+        return buf.toString();
+    }
+
+    /**
      * Uses 'TermMaker new(myFunctor, myArgs)'
      */
     public Object[] getCanonicalState() {
@@ -57,6 +105,13 @@
         Object func = myFunctor.build(builder);
         Object args = builder.argList();
         int len = myArgs.size();
+        if (0 == len) {
+            //It shouldn't be possible for myFunctor to be turned into
+            //a composite, but just to accomodate this possibility, in order
+            //to keep the composition of contracts clean, we call node/1 when
+            //there are no args.
+            return builder.node(func);
+        }
         for (int i = 0; i < len; i++) {
             Object arg = ((Term)myArgs.get(i)).build(builder);
             args = builder.argList(args, arg);



1.13      +20 -9     e/src/jsrc/org/quasiliteral/term/Term.updoc

Index: Term.updoc
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/term/Term.updoc,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- Term.updoc	2001/12/03 03:30:56	1.12
+++ Term.updoc	2001/12/05 00:46:11	1.13
@@ -9,14 +9,14 @@
     ? def qq__uriGetter := <unsafe:org.quasiliteral.*>
     # value: <unsafe:org.quasiliteral.*>
     
-    ? def miniSchema := <qq:astro.BaseSchema> new(["tag", "foo", "LiteralString"])
-    # value: org.quasiliteral.astro.BaseSchema@127cb58
+    ? def miniSchema := <qq:astro.BaseSchema> new("mini", ["tag", "foo", "LiteralString"])
+    # value: <Schema for mini>
     
     ? def miniBuilder := <qq:astro.BaseBuilder> new(miniSchema)
-    # value: org.quasiliteral.astro.BaseBuilder@127df6a
+    # value: <building ASTs for mini>
     
     ? def ast := dom build(miniBuilder)
-    # value: 
+    # value: ["",<0>]
     
     ? ast getType()
     # value: 0
@@ -28,14 +28,14 @@
     # value: ["",<0>]
     
     ? def tag := token getOptTag()
-    # value: org.quasiliteral.astro.AstroTag@127cae3
+    # value: <tag:<Schema for mini>>
     
     ? tag getTypeName()
     # value: "tag"
     
     ? ast getNextSibling()
     ? def c1 := ast getFirstChild()
-    # value: 
+    # value: ["",<2>]
     
     ? c1 getType()
     # value: 2
@@ -46,6 +46,12 @@
     ? tok1 getOptData()
     # value: "text"
     
+    ? def miniTermBuilder := <qq:term.TermBuilder> new(miniSchema)
+    # value: <building Term trees for mini>
+    
+    ? def term := dom build(miniTermBuilder)
+    # value: term`tag("text")`
+    
     ? 
     ? 
     ? 
@@ -72,6 +78,8 @@
     ? 
     ? 
     ? def term__uriGetter := <unsafe:org.quasiliteral.term.*>
+    # value: <unsafe:org.quasiliteral.term.*>
+    
     ? def qterm__uriGetter := <unsafe:org.quasiliteral.quasiterm.*>
     # value: <unsafe:org.quasiliteral.quasiterm.*>
     
@@ -84,13 +92,16 @@
     #                 zip)`
     
     ? 
+    ? 
+    ? 
     ? def TermParserMaker := <term:TermParser>
     # value: <unsafe:org.quasiliteral.term.TermParser>
     
     ? def term := TermParserMaker(<file:~/Desktop/termtest.txt> getText())
-    # value: term`foo(3,
-    #                 x(3, 'x'),
-    #                 zip)`
+    # problem: <ClassCastException: org.quasiliteral.term.Term>
+    #
+    #   <unsafe:org.quasiliteral.term.TermParser>("foo(3, x(3, \'x\'), zip)\n\ ")
+    #   <interactive interp> evalPrint(e`def term :any := TermParserMaker run(file__uriGetter get("~/Desktop/termtest.txt") getText())`)
     
     ? term getFunctor()
     # value: foo



1.10      +46 -19    e/src/jsrc/org/quasiliteral/term/TermBuilder.java

Index: TermBuilder.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/term/TermBuilder.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- TermBuilder.java	2001/12/03 03:30:56	1.9
+++ TermBuilder.java	2001/12/05 00:46:11	1.10
@@ -3,9 +3,10 @@
 import org.erights.e.elib.prim.E;
 import org.erights.e.elib.tables.ConstList;
 import org.erights.e.elib.tables.Twine;
+import org.erights.e.elib.tables.FlexList;
 import org.quasiliteral.astro.AstroBuilder;
 import org.quasiliteral.astro.AstroSchema;
-import org.quasiliteral.astro.BaseBuilder;
+import org.quasiliteral.astro.ASTBuilder;
 
 //This file is hereby placed in the public domain
 
@@ -16,7 +17,7 @@
  *     Leaf -- {@link Functor}
  *     Node -- {@link Term}
  *     Arg -- {@link Term}
- *     Args -- a {@link ConstList} of Term
+ *     Args -- a {@link FlexList} of Term
  * </pre>
  *
  * @author <a href="mailto:markm@caplet.com">Mark Miller</a>
@@ -37,8 +38,8 @@
     /**
      * Builds Term trees according to the term.y grammar
      */
-    static public final BaseBuilder FOR_ASTS =
-      new BaseBuilder(TermParser.DEFAULT_SCHEMA);
+    static public final ASTBuilder FOR_ASTS =
+      new ASTBuilder(TermParser.DEFAULT_SCHEMA);
 
     /**
      *
@@ -50,6 +51,13 @@
     /**
      *
      */
+    public String toString() {
+        return "<building Term trees for " + mySchema.getName() + ">";
+    }
+
+    /**
+     *
+     */
     public AstroSchema getSchema() {
         return mySchema;
     }
@@ -81,7 +89,7 @@
      */
     public Object composite(int typeCode, Object data, Twine source) {
         return node(leafTag(typeCode, source),
-                    argList(leafData(data, source)));
+                    argList(node(leafData(data, source))));
     }
 
     /**
@@ -94,41 +102,60 @@
 
     /**
      * @param func :(Functor | Term)
-     * @param args :(ConstList of(Term))
      * @return :Term
      */
-    public Object node(Object func, Object args) {
-        ConstList argList = (ConstList)E.as(args, ConstList.class);
+    public Object node(Object func) {
         if (func instanceof Term) {
-            E.require(argList.size() == 0,
-                      "Cannot doubly parameterize: ", func);
             return func;
         }
-        return new Term(((Functor)func), argList);
+        return new Term(((Functor)func), ConstList.EmptyList);
     }
 
     /**
-     * @return :(ConstList of(Term))
+     * @param func :Functor
+     * @param args :(FlexList of(Term))
+     * @return :Term
      */
+    public Object node(Object func, Object args) {
+        FlexList argList = (FlexList)E.as(args, FlexList.class);
+        return new Term(((Functor)func), argList.snapshot());
+    }
+
+    /**
+     * Returns a new empty FlexList that can be consumed by further
+     * productions.
+     *
+     * @return :(FlexList of(Term))
+     */
     public Object argList() {
-        return ConstList.EmptyList;
+        return FlexList.fromType(Term.class);
     }
 
     /**
+     * Returns a new FlexList containing only 'first'.
+     *
      * @param first :Term
-     * @return :(ConstList of(Term))
+     * @return :(FlexList of(Term))
      */
     public Object argList(Object first) {
-        return ConstList.EmptyList.with(first);
+        FlexList result = FlexList.fromType(Term.class);
+        result.push(first);
+        return result;
     }
 
     /**
-     * @param list :(ConstList of(Term))
+     * 'list' is consumed (should no longer be considered valid by the caller)
+     * in order to efficiently produce the output.
+     * <p>
+     * In fact, this simply pushes 'next' onto 'list' and returns 'list'
+     *
+     * @param list :(FlexList of(Term))
      * @param next :Term
-     * @return :(ConstList of(Term))
+     * @return :(FlexList of(Term))
      */
     public Object argList(Object list, Object next) {
-        ConstList argList = (ConstList)E.as(list, ConstList.class);
-        return argList.with(next);
+        FlexList argList = (FlexList)E.as(list, FlexList.class);
+        argList.push(next);
+        return argList;
     }
 }



1.11      +2 -2      e/src/jsrc/org/quasiliteral/term/TermParser.java

Index: TermParser.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/term/TermParser.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- TermParser.java	2001/12/03 03:30:56	1.10
+++ TermParser.java	2001/12/05 00:46:11	1.11
@@ -434,7 +434,7 @@
  * Builds ASTs according to the term.y grammar
  */
 static public final AstroSchema DEFAULT_SCHEMA =
-  new BaseSchema(ConstList.fromArray(TheTokens));
+  new BaseSchema("Term-Tree-Language", ConstList.fromArray(TheTokens));
 
 //#line 388 "TermParser.java"
 //###############################################################
@@ -588,7 +588,7 @@
 break;
 case 2:
 //#line 76 "term.y"
-{ yyval = b.node(val_peek(0), b.argList()); }
+{ yyval = b.node(val_peek(0)); }
 break;
 case 3:
 //#line 77 "term.y"



1.10      +2 -2      e/src/jsrc/org/quasiliteral/term/term.y

Index: term.y
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/term/term.y,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- term.y	2001/12/03 03:30:56	1.9
+++ term.y	2001/12/05 00:46:11	1.10
@@ -73,7 +73,7 @@
 ;
 
 term:
-        functor                         { $$ = b.node($1, b.argList()); }
+        functor                         { $$ = b.node($1); }
  |      functor     '(' argList ')'     { $$ = b.node($1, $3); }
  |      functorHole '(' argList ')'     { $$ = b.node($1, $3); }
 
@@ -263,5 +263,5 @@
  * Builds ASTs according to the term.y grammar
  */
 static public final AstroSchema DEFAULT_SCHEMA =
-  new BaseSchema(ConstList.fromArray(TheTokens));
+  new BaseSchema("Term-Tree-Language", ConstList.fromArray(TheTokens));