[e-cvs] cvs commit: e/src/jsrc/org/quasiliteral/term QuasiBuilder.java QuasiBuilderAdaptor.java TermParser.java term.y

markm@eros.cs.jhu.edu markm@eros.cs.jhu.edu
Tue, 18 Dec 2001 16:59:31 -0500


markm       01/12/18 16:59:31

  Modified:    src/jsrc Makefile
               src/jsrc/org/erights/e/elang/evm AssignExpr.java
                        CdrPattern.java EImpl.java EMethodNode.java
                        ENode.java ListPattern.java
               src/jsrc/org/erights/e/elang/interp Help.java
               src/jsrc/org/erights/e/elang/syntax EBuilder.java
               src/jsrc/org/erights/e/elang/visitors ETreeVisitor.java
               src/jsrc/org/erights/e/elib/base ClassDesc.java
                        MessageDesc.java ParamDesc.java TypeDesc.java
               src/jsrc/org/quasiliteral/term TermParser.java term.y
  Added:       src/jsrc/org/quasiliteral/quasiterm QAstroArg.java
                        QBuilder.java QTerm.java
               src/jsrc/org/quasiliteral/term QuasiBuilder.java
                        QuasiBuilderAdaptor.java
  Removed:     src/jsrc/org/quasiliteral/quasiterm QuasiBuilder.java
                        QuasiBuilderAdaptor.java
  Log:
  bare start on Term quasi processing.  Fixed a bug 125486 in list & cdr patterns.

Revision  Changes    Path
1.67      +1 -1      e/src/jsrc/Makefile

Index: Makefile
===================================================================
RCS file: /cvs/e/src/jsrc/Makefile,v
retrieving revision 1.66
retrieving revision 1.67
diff -u -r1.66 -r1.67
--- Makefile	2001/12/18 05:24:41	1.66
+++ Makefile	2001/12/18 21:59:30	1.67
@@ -42,7 +42,6 @@
 	find $(ER)/elib                 -name '*.java' > files.tmp
 	find org/quasiliteral/astro     -name '*.java' >> files.tmp
 	find org/quasiliteral/syntax    -name '*.java' >> files.tmp
-	find org/quasiliteral/quasiterm -name '*.java' >> files.tmp
 	find org/quasiliteral/term      -name '*.java' >> files.tmp
 	find $(ER)/meta/java            -name '*.java' >> files.tmp
 	# find $(ER)/meta/javax         -name '*.java' >> files.tmp
@@ -53,6 +52,7 @@
 quasi_1:
 	find org/quasiliteral/base      -name '*.java' > files.tmp
 	find org/quasiliteral/text      -name '*.java' >> files.tmp
+	find org/quasiliteral/quasiterm -name '*.java' >> files.tmp
 	$(JCOMPILE) @files.tmp
 
 # Third party parsing and regex tools



1.35      +1 -1      e/src/jsrc/org/erights/e/elang/evm/AssignExpr.java

Index: AssignExpr.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/AssignExpr.java,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- AssignExpr.java	2001/12/14 00:06:00	1.34
+++ AssignExpr.java	2001/12/18 21:59:30	1.35
@@ -30,7 +30,7 @@
 import org.erights.e.elib.tables.Twine;
 import org.quasiliteral.astro.Astro;
 import org.quasiliteral.astro.AstroTag;
-import org.quasiliteral.quasiterm.QuasiBuilder;
+import org.quasiliteral.term.QuasiBuilder;
 
 import java.io.IOException;
 



1.18      +7 -17     e/src/jsrc/org/erights/e/elang/evm/CdrPattern.java

Index: CdrPattern.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/CdrPattern.java,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- CdrPattern.java	2001/12/02 06:01:42	1.17
+++ CdrPattern.java	2001/12/18 21:59:30	1.18
@@ -28,6 +28,7 @@
 import org.erights.e.elib.tables.EList;
 import org.erights.e.elib.tables.FlexList;
 import org.erights.e.elib.util.OneArgFunc;
+import org.erights.e.elib.base.ClassDesc;
 
 import java.io.IOException;
 
@@ -43,6 +44,11 @@
  */
 public class CdrPattern extends Pattern {
 
+    /**
+     *
+     */
+    static private final ClassDesc EListGuard = ClassDesc.make(EList.class);
+
     private ListPattern myStart;
 
     private Pattern myRest;
@@ -104,23 +110,7 @@
     void testMatch(EvalContext ctx,
                    Object specimen,
                    OneArgFunc optEjector) {
-        //XXX should really coerce to a list here
-        specimen = Ref.resolution(specimen);
-        if (specimen == null) {
-            throw Thrower.toEject(optEjector,
-                                  "null doesn't match a list pattern");
-        }
-
-        EList list;
-        if (specimen instanceof EList) {
-            list = (EList)specimen;
-        } else if (specimen.getClass().isArray()) {
-            list = ConstList.fromArray(specimen);
-        } else {
-            throw Thrower.toEject(optEjector,
-                                  "must be a list");
-        }
-
+        EList list = (EList)EListGuard.coerce(specimen, optEjector);
         Pattern[] start = myStart.subPatterns();
 
         int len = list.size();



1.28      +6 -2      e/src/jsrc/org/erights/e/elang/evm/EImpl.java

Index: EImpl.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/EImpl.java,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- EImpl.java	2001/12/02 06:01:42	1.27
+++ EImpl.java	2001/12/18 21:59:30	1.28
@@ -86,8 +86,12 @@
     public TypeDesc getAllegedType() {
         FlexList mTypes = FlexList.fromType(MessageDesc.class);
         myScript.protocol(this, mTypes);
-        return new ProtocolDesc("XXX Missing docComment",
-                                null, //XXX
+        String optName = null;
+        if (myScript instanceof VTable) {
+            optName = ((VTable)myScript).optName();
+        }
+        return new ProtocolDesc("Missing docComment", //XXX for now
+                                optName,
                                 ConstList.EmptyList,
                                 mTypes.snapshot());
     }



1.28      +9 -0      e/src/jsrc/org/erights/e/elang/evm/EMethodNode.java

Index: EMethodNode.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/EMethodNode.java,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- EMethodNode.java	2001/12/10 20:30:08	1.27
+++ EMethodNode.java	2001/12/18 21:59:30	1.28
@@ -21,6 +21,7 @@
 
 import org.erights.e.develop.exception.ExceptionMgr;
 import org.erights.e.elib.base.MethodNode;
+import org.erights.e.elib.base.MessageDesc;
 import org.erights.e.elib.tables.FlexMap;
 
 
@@ -100,5 +101,13 @@
      * Do nothing
      */
     public void addJavaMemberNodesToMap(FlexMap map) {
+    }
+
+    /**
+     *
+     */
+    public MessageDesc makeMessageType(String verb) {
+        //XXX we should do better parameters if we can
+        return super.makeMessageType(verb);
     }
 }



1.11      +1 -1      e/src/jsrc/org/erights/e/elang/evm/ENode.java

Index: ENode.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/ENode.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- ENode.java	2001/12/10 20:30:08	1.10
+++ ENode.java	2001/12/18 21:59:30	1.11
@@ -25,7 +25,7 @@
 import org.erights.e.elang.visitors.ETreeVisitor;
 import org.erights.e.elib.util.AlreadyDefinedException;
 import org.quasiliteral.astro.Astro;
-import org.quasiliteral.quasiterm.QuasiBuilder;
+import org.quasiliteral.term.QuasiBuilder;
 
 /**
  * Those ParseNodes that--after expansion--define the kernel



1.16      +10 -17    e/src/jsrc/org/erights/e/elang/evm/ListPattern.java

Index: ListPattern.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/ListPattern.java,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- ListPattern.java	2001/12/02 06:01:42	1.15
+++ ListPattern.java	2001/12/18 21:59:30	1.16
@@ -28,6 +28,7 @@
 import org.erights.e.elib.tables.EList;
 import org.erights.e.elib.tables.FlexList;
 import org.erights.e.elib.util.OneArgFunc;
+import org.erights.e.elib.base.ClassDesc;
 
 import java.io.IOException;
 
@@ -41,6 +42,14 @@
  */
 public class ListPattern extends Pattern {
 
+    /**
+     *
+     */
+    static private final ClassDesc EListGuard = ClassDesc.make(EList.class);
+
+    /**
+     *
+     */
     private Pattern[] mySubs;
 
     /**
@@ -100,23 +109,7 @@
     void testMatch(EvalContext ctx,
                    Object specimen,
                    OneArgFunc optEjector) {
-        // TODO this looks a lot like the method in CdrPattern
-        //XXX should really coerce to a list here
-        specimen = Ref.resolution(specimen);
-        if (specimen == null) {
-            throw Thrower.toEject(optEjector,
-                                  "null doesn't match a list pattern");
-        }
-
-        EList list;
-        if (specimen instanceof EList) {
-            list = (EList)specimen;
-        } else if (specimen.getClass().isArray()) {
-            list = ConstList.fromArray(specimen);
-        } else {
-            throw Thrower.toEject(optEjector,
-                                  "must be a list");
-        }
+        EList list = (EList)EListGuard.coerce(specimen, optEjector);
 
         int len = list.size();
         if (len != mySubs.length) {



1.21      +9 -9      e/src/jsrc/org/erights/e/elang/interp/Help.java

Index: Help.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/interp/Help.java,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- Help.java	2001/12/12 06:35:57	1.20
+++ Help.java	2001/12/18 21:59:30	1.21
@@ -64,16 +64,16 @@
      */
     public UnQuote run(Object subject) throws IOException {
         StringWriter strWriter = new StringWriter();
-        run(subject, new TextWriter(strWriter));
+        run(subject, false, new TextWriter(strWriter));
         StringBuffer buf = strWriter.getBuffer();
         return new UnQuote(StringHelper.canonical(buf.toString()));
     }
 
     /**
-     * XXX This should probably be moved to
-     * TypeDesc.printHelpOn()
+     * XXX This should probably be moved to TypeDesc.printHelpOn()
      */
-    public void run(Object subject, TextWriter out) throws IOException {
+    public void run(Object subject, boolean fullFlag, TextWriter out)
+      throws IOException {
         subject = Ref.resolution(subject);
         if (null == subject) {
             out.println("a null");
@@ -85,12 +85,12 @@
               = (TypeDesc)E.call(subject, "getAllegedType");
             ConstMap mTypeMap = type.getMessageTypes().sortKeys();
             MessageDesc[] mTypes
-              = (MessageDesc[])mTypeMap.getValues();
+              = (MessageDesc[])mTypeMap.getValues(MessageDesc.class);
+            TextWriter nest = out.indent();
             for (int i = 0; i < mTypes.length; i++) {
                 MessageDesc mType = mTypes[i];
-                if (mType.getVerb().indexOf('(') == -1) {
-                    //XXX hack
-                    mType.printHelpOn(out.indent());
+                if (fullFlag || mType.getVerb().indexOf('(') == -1) {
+                    mType.printHelpOn(nest);
                 }
             }
         }
@@ -105,7 +105,7 @@
           "    shows this message\n" +
           "help(<expression>)\n" +
           "    shows what messages it responds to\n" +
-          "meta scope bindings\n" +
+          "meta scope() bindings()\n" +
           "    shows variable bindings in the current scope\n" +
           "Documentation on the E Language can be found at\n" +
           "    http://www.erights.org/elang/help.html");



1.92      +2 -2      e/src/jsrc/org/erights/e/elang/syntax/EBuilder.java

Index: EBuilder.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/syntax/EBuilder.java,v
retrieving revision 1.91
retrieving revision 1.92
diff -u -r1.91 -r1.92
--- EBuilder.java	2001/12/10 20:30:09	1.91
+++ EBuilder.java	2001/12/18 21:59:30	1.92
@@ -1821,7 +1821,7 @@
         Object[] auditPair = (Object[])audits;
         Object optOName = auditPair[0];
         Object auditors = auditPair[1];
-        return oType("XXX Needs docComment",
+        return oType("Needs docComment", //XXX for now
                      optOName,
                      auditors,
                      mTypes);
@@ -1886,7 +1886,7 @@
         }
         return call(MSGMAKER,
                     "new",
-                    list(new LiteralExpr("XXX Needs docComment"),
+                    list(new LiteralExpr("Needs docComment"), //XXX for now
                          new LiteralExpr((String)verb),
                          tuple(pTypes),
                          optRetType));



1.21      +2 -2      e/src/jsrc/org/erights/e/elang/visitors/ETreeVisitor.java

Index: ETreeVisitor.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/visitors/ETreeVisitor.java,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- ETreeVisitor.java	2001/12/01 10:38:42	1.20
+++ ETreeVisitor.java	2001/12/18 21:59:30	1.21
@@ -137,8 +137,8 @@
     Object visitNounExpr(String varName);
 
     /**
-     * "/**" synopsys
-     * "* /" "def" string-literal ("::" auditors)? (eScript | matcher) <p>
+     * "##" synopsys
+     * "def" string-literal ("::" auditors)? (eScript | matcher) <p>
      *
      * Define an object that responds to messages according to
      * eScript<p>



1.36      +1 -1      e/src/jsrc/org/erights/e/elib/base/ClassDesc.java

Index: ClassDesc.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/base/ClassDesc.java,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- ClassDesc.java	2001/12/18 05:24:42	1.35
+++ ClassDesc.java	2001/12/18 21:59:30	1.36
@@ -373,7 +373,7 @@
      *
      */
     public ClassDesc(Class clazz) {
-        super("XXX Missing docComment",
+        super("Missing docComment", //XXX for now
               typeSig(clazz),
               ConstList.EmptyList,
               mTypes(clazz));



1.14      +12 -4     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.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- MessageDesc.java	2001/12/18 05:24:42	1.13
+++ MessageDesc.java	2001/12/18 21:59:30	1.14
@@ -23,6 +23,7 @@
 
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.prim.StaticMaker;
+import org.erights.e.elib.prim.E;
 import org.erights.e.elib.serial.Persistent;
 import org.erights.e.elib.slot.ValueGuard;
 import org.erights.e.elib.slot.VoidMaker;
@@ -55,9 +56,7 @@
      */
     static /*package*/ void synopsize(TextWriter out, String str)
       throws IOException {
-        out.print("/**");
-        out.indent(" * ").lnPrint(str);
-        out.lnPrint(" */");
+        out.indent("## ").lnPrint(str);
     }
 
     /**
@@ -70,9 +69,14 @@
                        ConstList params,
                        Object retType) {
         myDocComment = docComment;
-        myVerb = verb;
         myParams = params;
         myRetType = retType;
+
+        int i = verb.indexOf('/');
+        if (-1 != i) {
+            verb = verb.substring(0, i);
+        }
+        myVerb = verb;
     }
 
     /**
@@ -100,9 +104,13 @@
      *
      */
     public ValueGuard getReturnType() {
+        if (myRetType instanceof ValueGuard) {
+            return (ValueGuard)myRetType;
+        }
         if (myRetType instanceof Class) {
             myRetType = ClassDesc.byJavaRules((Class)myRetType);
         }
+        myRetType = E.as(myRetType, ValueGuard.class);
         return (ValueGuard)myRetType;
     }
 



1.14      +5 -0      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.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- ParamDesc.java	2001/12/18 05:24:42	1.13
+++ ParamDesc.java	2001/12/18 21:59:30	1.14
@@ -23,6 +23,7 @@
 
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.prim.StaticMaker;
+import org.erights.e.elib.prim.E;
 import org.erights.e.elib.serial.Persistent;
 import org.erights.e.elib.slot.SimpleSlotMaker;
 import org.erights.e.elib.slot.SlotGuard;
@@ -73,9 +74,13 @@
      *
      */
     public SlotGuard getType() {
+        if (myType instanceof SlotGuard) {
+            return (SlotGuard)myType;
+        }
         if (myType instanceof Class) {
             myType = ClassDesc.byJavaRules((Class)myType);
         }
+        myType = E.as(myType, SlotGuard.class);
         return (SlotGuard)myType;
     }
 



1.18      +12 -4     e/src/jsrc/org/erights/e/elib/base/TypeDesc.java

Index: TypeDesc.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/base/TypeDesc.java,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- TypeDesc.java	2001/12/16 10:10:29	1.17
+++ TypeDesc.java	2001/12/18 21:59:30	1.18
@@ -99,9 +99,13 @@
     }
 
     /**
-     * Prints in the most expansive form accepted by typedef
+     * Prints in the most expansive form accepted by typedef.
+     * <p>
+     * fullFlag controls whether message names containing an '(' get printed
+     * too.  These are for capturing Java signatures.
      */
-    public void printTypedefOn(TextWriter out) throws IOException {
+    public void printTypedefOn(boolean fullFlag, TextWriter out)
+      throws IOException {
         MessageDesc.synopsize(out, myDocComment);
         out.lnPrint("typedef " + myName);
         int numAuditors = myAuditors.size();
@@ -113,9 +117,13 @@
         }
         out.print(" {");
         TextWriter nest = out.indent();
-        Object[] methTypes = (Object[])myMTypes.getValues();
+        MessageDesc[] methTypes =
+          (MessageDesc[])myMTypes.getValues(MessageDesc.class);
         for (int i = 0; i < methTypes.length; i++) {
-            nest.lnPrint(methTypes[i]);
+            MessageDesc methType = methTypes[i];
+            if (fullFlag || -1 == methType.getVerb().indexOf('(')) {
+                nest.lnPrint(methType);
+            }
         }
         out.lnPrint("}\n");
     }



1.1                  e/src/jsrc/org/quasiliteral/quasiterm/QAstroArg.java

Index: QAstroArg.java
===================================================================
package org.quasiliteral.quasiterm;

import org.erights.e.elib.eio.TextWriter;
import org.erights.e.elib.serial.PassByConstruction;
import org.erights.e.elib.serial.Persistent;
import org.erights.e.elib.tables.Selfless;
import org.erights.e.elib.tables.Twine;
import org.erights.e.elib.tables.ConstList;
import org.erights.e.elib.tables.FlexList;
import org.quasiliteral.base.MatchMaker;
import org.quasiliteral.base.ValueMaker;

import java.io.IOException;

//This file is hereby placed in the public domain

/**
 *
 * @author <a href="mailto:markm@caplet.com">Mark Miller</a>
 */
public abstract class QAstroArg
  implements Selfless, PassByConstruction, Persistent,
  ValueMaker, MatchMaker {

    /**
     * @serial What source text was originally lexed or parsed to produce
     *         this node?
     */
    protected final Twine mySource;

    /**
     *
     * @param source The source text this node was extracted from.  To
     *               provide no info, use "" rather than null.
     */
    public QAstroArg(Twine source) {
        mySource = source;
    }

    public ConstList matchBind(Object[] args, Object specimen) {
        FlexList bindings = FlexList.make();
        if (matchBind(args, specimen, bindings)) {
            return bindings.snapshot();
        } else {
            return null;
        }
    }

    /**
     * What source text was originally lexed or parsed to produce this node,
     * or a representative token of this node?
     */
    public Twine getSource() {
        return mySource;
    }

    /**
     *
     */
    public void printOn(TextWriter out) throws IOException {
        out.print("term`");
        prettyPrintOn(out.indent("     "));
        out.print("`");
    }

    /**
     *
     */
    public abstract void prettyPrintOn(TextWriter out)
      throws IOException;
}



1.1                  e/src/jsrc/org/quasiliteral/quasiterm/QBuilder.java

Index: QBuilder.java
===================================================================
package org.quasiliteral.quasiterm;

import org.quasiliteral.astro.BaseBuilder;
import org.quasiliteral.astro.Astro;
import org.quasiliteral.astro.AstroTag;
import org.quasiliteral.astro.AstroArg;
import org.quasiliteral.astro.AstroSchema;
import org.quasiliteral.term.QuasiBuilder;
import org.erights.e.elib.tables.Twine;

//This file is hereby placed in the public domain

/**
 *
 * @author <a href="mailto:markm@caplet.com">Mark Miller</a>
 */
public class QBuilder extends BaseBuilder implements QuasiBuilder {

    /**
     *
     */
    public QBuilder(AstroSchema schema) {
        super(schema);
    }

    protected Astro leafInternal(AstroTag tag,
                                 Object optData,
                                 Twine source) {
        throw new RuntimeException("XXX not yet implemented");
    }

    public Astro term(Astro leaf, Object args) {
        throw new RuntimeException("XXX not yet implemented");
    }

    public boolean doesQuasis() {
        throw new RuntimeException("XXX not yet implemented");
    }

    public Object list() {
        throw new RuntimeException("XXX not yet implemented");
    }

    public Astro termHole(Astro optIdent, Astro functorHole) {
        throw new RuntimeException("XXX not yet implemented");
    }

    public Object with(Object list, AstroArg next) {
        throw new RuntimeException("XXX not yet implemented");
    }

    public AstroArg alt(AstroArg leftArg, AstroArg rightArg) {
        throw new RuntimeException("XXX not yet implemented");
    }

    public AstroArg seq(Astro optTerm, String quant) {
        throw new RuntimeException("XXX not yet implemented");
    }

    public AstroArg group(Object args, String quant) {
        throw new RuntimeException("XXX not yet implemented");
    }

    public Astro dollarHole(Astro litInt) {
        throw new RuntimeException("XXX not yet implemented");
    }

    public Astro atHole(Astro litInt) {
        throw new RuntimeException("XXX not yet implemented");
    }
}



1.1                  e/src/jsrc/org/quasiliteral/quasiterm/QTerm.java

Index: QTerm.java
===================================================================
package org.quasiliteral.quasiterm;

import org.erights.e.develop.assertion.T;
import org.erights.e.develop.format.StringHelper;
import org.erights.e.elib.eio.TextWriter;
import org.erights.e.elib.prim.E;
import org.erights.e.elib.prim.StaticMaker;
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.Astro;
import org.quasiliteral.astro.AstroBuilder;
import org.quasiliteral.astro.AstroTag;

import java.io.IOException;

//This file is hereby placed in the public domain

/**
 * A quasi-literal Term, that matches or generates an actual {@link Term}.
 *
 * @author <a href="mailto:markm@caplet.com">Mark S Miller</a>
 */
public class QTerm extends QAstroArg
  implements Astro {

    /**
     *
     */
    static public final StaticMaker TermMaker =
      StaticMaker.make(QTerm.class);

    /**
     * @serial Represents the token-type of the functor of this term.
     */
    private final AstroTag myTag;

    /**
     * @serial If the functor represents a literal-data token, then this is
     * the data, and myTag must represent the cononical corresponding
     * token-type for this kind of data in this schema.
     */
    private final Object myOptData;

    /**
     * A term is a functor (the above three instance variables) as
     * parameterized by a list of argument Terms.  These are the arguments.  A
     * term of zero arguments is often refered to as a "functor", so there's
     * no information beyond the functor-part.
     */
    private final ConstList myArgs;

    /**
     * Just used to decide how to pretty print.
     * <p>
     * Initialized lazily.  0 if uninitialized, so does not need to be
     * recalculated on revival.
     */
    private transient int myHeight = 0;

    /**
     * Makes a Term that represents a node in an abstract syntax tree, ie,
     * a Term tree.
     * <p>
     * The invariants of a Term are not checked here, but rather are
     * enforced by the callers in this class and in TermBuilder.
     *
     * @param tag Identifies a token type in a particular grammar or set
     *            of related grammars, used as the functor (or "label") of
     *            this Term
     * @param optData Either {@link Character},
     *                {@link BigInteger}, {@link Double},
     *                or {@link Twine} or null.  If not null, then the tag
     *                must represent the canonical literal type for this
     *                kind of data in this schema.
     * @param args This Term's argument list -- a list of Terms
     */
    /*package*/
    QTerm(AstroTag tag,
          Object optData,
          Twine source,
          ConstList args) {

        super(source);
        myTag = tag;
        myOptData = optData;
        myArgs = args;
    }

    /**
     * Uses 'TermMaker new(myTag, myOptData, mySource, myArgs)'
     */
    public Object[] getCanonicalState() {
        Object[] result = {
            TermMaker, "new", myTag, myOptData, mySource, myArgs
        };
        return result;
    }

    /**
     *
     */
    public Astro build(AstroBuilder builder) {
        Astro func;
        if (null == myOptData) {
            func = builder.leafTag(myTag, mySource);
        } else {
            //Assumes tag adds no more info.
            func = builder.leafData(myOptData, mySource);
        }
        Object args = builder.list();
        int len = myArgs.size();
        for (int i = 0; i < len; i++) {
            Astro arg = ((QTerm)myArgs.get(i)).build(builder);
            args = builder.with(args, arg);
        }
        return builder.term(func, args);
    }

    /**
     * Represents the token-type of the functor of this term.
     */
    public AstroTag getTag() {
        return myTag;
    }

    /**
     *
     */
    public short getOptTagCode() {
        return myTag.getOptTagCode();
    }

    /**
     * Either literal data or null.  If not null, then the tag
     * must represent the canonical literal type for this
     * kind of data in this schema.
     */
    public Object getOptData() {
        return myOptData;
    }

    public String getOptString() {
        return ((Twine)getOptData()).bare();
    }

    /**
     *
     */
    public Object getOptArgData() {
        return ((QTerm)myArgs.get(0)).getOptData();
    }

    public Object getOptArgData(short tagCode) {
        //This is too much reporting work when the error doesn't happen.
        //Should consider putting into a thunk instead.
        AstroTag optTag = myTag.getSchema().getOptTagForCode(tagCode);
        T.require(tagCode == myTag.getOptTagCode(),
                  "Tag mismatch: ", myTag, " vs ",
                  (null == optTag ?
                   (Object)new Integer(tagCode) :
                   (Object)optTag));
        return ((QTerm)myArgs.get(0)).getOptData();
    }

    public String getOptArgString(short tagCode) {
        return ((Twine)getOptArgData(tagCode)).bare();
    }

    /**
     * A term is a functor (the above three instance variables) as
     * parameterized by a list of argument Terms.  These are the arguments.
     * A term of zero arguments is often refered to as a "functor", so there's
     * no information beyond the functor-part.
     */
    public ConstList getArgs() {
        return myArgs;
    }

    /**
     *
     */
    public Astro withoutArgs() {
        return new QTerm(myTag, myOptData, mySource, ConstList.EmptyList);
    }

    /**
     *
     */
    public Astro withArgs(ConstList args) {
        T.require(myArgs.size() == 0,
                  "To use as functor, must not have args: ", this);
        return new QTerm(myTag, myOptData, mySource, args);
    }

    public Object substitute(Object[] args) {
        throw new RuntimeException("XXX not yet implemented");
    }

    public boolean matchBind(Object[] args,
                             Object specimen,
                             FlexList bindings) {
        throw new RuntimeException("XXX not yet implemented");
    }

    /**
     * What's the longest distance to the bottom?
     * <p>
     * A leaf node is height 1.  All other nodes are one more than the height
     * of their highest child.  This is used for pretty printing.
     */
    public int getHeight() {
        if (myHeight <= 0) {
            myHeight = 1;
            for (int i = 0; i < myArgs.size(); i++) {
                int h = ((QTerm)myArgs.get(i)).getHeight();
                myHeight = Math.max(myHeight, h + 1);
            }
        }
        return myHeight;
    }

    /**
     *
     */
    public void prettyPrintOn(TextWriter out)
      throws IOException {
        String label = myTag.getTagName();
        if (null != myOptData) {
            label = E.toQuote(myOptData).bare();
            label = StringHelper.replaceAll(label, "$", "$$");
            label = StringHelper.replaceAll(label, "@", "@@");
            label = StringHelper.replaceAll(label, "`", "``");
        }
        out.print(label);
        int h = getHeight();
        if (h <= 1) {
            if (myArgs.size() != 0) {
                throw new RuntimeException("internal: bad height " + h);
            }
            //If it's a leaf, don't show parens either
            return;
        }
        if (h == 2) {
            //If it only contains leaves, do it on one line
            out.print("(");
            ((QAstroArg)myArgs.get(0)).prettyPrintOn(out);
            for (int i = 1; i < myArgs.size(); i++) {
                out.print(", ");
                ((QAstroArg)myArgs.get(i)).prettyPrintOn(out);
            }
            out.print(")");
            return;
        }
        //print each child lined up.
        out.print("(");
        int reps = label.length() + 1;
        String spaces = StringHelper.multiply(" ", reps);
        TextWriter sub = out.indent(spaces);

        ((QAstroArg)myArgs.get(0)).prettyPrintOn(sub);
        for (int i = 1; i < myArgs.size(); i++) {
            sub.println(",");
            ((QAstroArg)myArgs.get(i)).prettyPrintOn(sub);
        }
        sub.print(")");
    }
}



1.16      +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.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- TermParser.java	2001/12/12 06:36:00	1.15
+++ TermParser.java	2001/12/18 21:59:31	1.16
@@ -20,8 +20,8 @@
 import org.quasiliteral.astro.Astro;
 import org.quasiliteral.astro.AstroArg;
 import org.quasiliteral.astro.AstroTag;
-import org.quasiliteral.quasiterm.QuasiBuilder;
-import org.quasiliteral.quasiterm.QuasiBuilderAdaptor;
+import org.quasiliteral.term.QuasiBuilder;
+import org.quasiliteral.term.QuasiBuilderAdaptor;
 import org.quasiliteral.syntax.SyntaxException;
 
 import java.io.IOException;



1.15      +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.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- term.y	2001/12/12 06:36:00	1.14
+++ term.y	2001/12/18 21:59:31	1.15
@@ -15,8 +15,8 @@
 import org.quasiliteral.astro.Astro;
 import org.quasiliteral.astro.AstroArg;
 import org.quasiliteral.astro.AstroTag;
-import org.quasiliteral.quasiterm.QuasiBuilder;
-import org.quasiliteral.quasiterm.QuasiBuilderAdaptor;
+import org.quasiliteral.term.QuasiBuilder;
+import org.quasiliteral.term.QuasiBuilderAdaptor;
 import org.quasiliteral.syntax.SyntaxException;
 
 import java.io.IOException;



1.1                  e/src/jsrc/org/quasiliteral/term/QuasiBuilder.java

Index: QuasiBuilder.java
===================================================================
package org.quasiliteral.term;

import org.quasiliteral.astro.Astro;
import org.quasiliteral.astro.AstroArg;
import org.quasiliteral.astro.AstroBuilder;

//This file is hereby placed in the public domain

/**
 * AstroBuilder extended with additional building methods for the expression
 * of quasi-literal tree expressions and patterns.
 * <p>
 * These additional methods correspond to the quasi-oriented productions of
 * term.y.  XXX Once this is converted to an Antlr-based term.g, then we
 * should use Antlr's support for grammar inheritance to split it up into
 * the base term.y and the derived quasiterm.y.  The former can then use only
 * an AstroBuilder for building, and only the latter would require a
 * QuasiBuilder.  At such a time, this class should move to the
 * org.quasiliteral.quasiterm package, as that will no longer screw up our
 * layering.
 *
 * @author <a href="mailto:markm@caplet.com">Mark Miller</a>
 */
public interface QuasiBuilder extends AstroBuilder {

    /**
     * A kludge because of the current (pre-Antlr) lack of grammar
     * inheritance.
     * <p>
     * If this is false, then the only production which work are the ones
     * inherited from AstroBuilder, and this is really an AstroBuilder in
     * QuasiBuilder clothing.  This flag is also, by default, used to tell
     * the lexer whether to collapse double quasi characters -- '@', '$', and
     * '`'.
     */
    boolean doesQuasis();

    /**
     * Upgrades the functorHole to a TermHole.
     * <p>
     * If optIdent is provided, then it will only match terms with a matching
     * tag.
     */
    Astro termHole(Astro optIdent, Astro functorHole);

    /**
     * Matched anything matched by either leftArg or rightArg.
     * <p>
     * Adds a "?" to the rank of both arguments.
     */
    AstroArg alt(AstroArg leftArg, AstroArg rightArg);

    /**
     * Matches a consecutive sequence of Terms matched by optTerm.
     * <p>
     * Adds quant to the rank of optTerm.
     */
    AstroArg seq(Astro optTerm, String quant);

    /**
     * Treat the 'args' list as a repeating sequence.
     * <p>
     * Matches a consecutive sequence of subsequences matched by 'args'.
     * Adds quant to the rank of each arg.
     *
     * @param args is a list of AstroArg.
     */
    AstroArg group(Object args, String quant);

    /**
     * On substitution, "evaluates" to 'args[litInt]'.
     * <p>
     * On matching, matches if 'args[litInt] <=> specimen'
     */
    Astro dollarHole(Astro litInt);

    /**
     * Matches the specimen by placing it in 'bindings[litInt]'.
     */
    Astro atHole(Astro litInt);
}



1.1                  e/src/jsrc/org/quasiliteral/term/QuasiBuilderAdaptor.java

Index: QuasiBuilderAdaptor.java
===================================================================
package org.quasiliteral.term;

import org.erights.e.elib.tables.Twine;
import org.quasiliteral.astro.Astro;
import org.quasiliteral.astro.AstroArg;
import org.quasiliteral.astro.AstroBuilder;
import org.quasiliteral.astro.AstroSchema;
import org.quasiliteral.astro.AstroTag;

import java.math.BigInteger;

//This file is hereby placed in the public domain

/**
 * Wraps an {@link AstroBuilder} to pretend to be of type
 * {@link QuasiBuilder}.
 * <p>
 * This kludge exists only until we switch to Antlr, and make use of its
 * support for grammar inheritance.  Until then, the one grammar, term.y, must
 * support both literal and quasi-literal term trees, so it is therefore
 * defined in terms of the larger subtype -- QuasiBuilder.
 *
 * @author <a href="mailto:markm@caplet.com">Mark Miller</a>
 */
public class QuasiBuilderAdaptor implements QuasiBuilder {

    /**
     * Builds Term trees according to the term.y grammar
     */
    static public final QuasiBuilder FOR_TERMS =
      new QuasiBuilderAdaptor(TermBuilder.FOR_TERMS);

//    /**
//     * Builds ASTs according to the term.y grammar
//     */
//    static public final QuasiBuilder FOR_ASTS =
//      new QuasiBuilderAdaptor(TermBuilder.FOR_ASTS);

    private AstroBuilder myBuilder;

    public QuasiBuilderAdaptor(AstroBuilder builder) {
        myBuilder = builder;
    }

    /**
     *
     */
    public String toString() {
        return "<adapting " + myBuilder.toString() + ">";
    }

    public AstroSchema getSchema() {
        return myBuilder.getSchema();
    }

    public Astro leafTag(AstroTag tag, Twine source) {
        return myBuilder.leafTag(tag, source);
    }

    public Astro composite(AstroTag tag, Object data, Twine source) {
        return myBuilder.composite(tag, data, source);
    }

    public Astro leafData(Object data, Twine source) {
        return myBuilder.leafData(data, source);
    }

    public Astro leafChar(char data, Twine source) {
        return myBuilder.leafChar(data, source);
    }

    public Astro leafLong(long data, Twine source) {
        return myBuilder.leafLong(data, source);
    }

    public Astro leafInteger(BigInteger data, Twine source) {
        return myBuilder.leafInteger(data, source);
    }

    public Astro leafFloat64(double data, Twine source) {
        return myBuilder.leafFloat64(data, source);
    }

    public Astro leafString(String data, Twine source) {
        return myBuilder.leafString(data, source);
    }

    public Astro leafTwine(Twine data, Twine source) {
        return myBuilder.leafTwine(data, source);
    }

    public Astro term(Astro leaf, Object args) {
        return myBuilder.term(leaf, args);
    }

    public Object list() {
        return myBuilder.list();
    }

    public Object list(AstroArg first) {
        return myBuilder.list(first);
    }

    public Object list(AstroArg first, AstroArg second) {
        return myBuilder.list(first, second);
    }

    public Object list(AstroArg first, AstroArg second, AstroArg third) {
        return myBuilder.list(first, second, third);
    }

    public Object with(Object list, AstroArg next) {
        return myBuilder.with(list, next);
    }

    public Object unpack(Astro litString) {
        return myBuilder.unpack(litString);
    }

    public boolean doesQuasis() {
        return false;
    }

    public Astro termHole(Astro optIdent, Astro functorHole) {
        throw new RuntimeException("not quasi-ing");
    }

    public AstroArg alt(AstroArg leftArg, AstroArg rightArg) {
        throw new RuntimeException("not quasi-ing");
    }

    public AstroArg seq(Astro optTerm, String quant) {
        throw new RuntimeException("not quasi-ing");
    }

    public AstroArg group(Object args, String quant) {
        throw new RuntimeException("not quasi-ing");
    }

    public Astro dollarHole(Astro litInt) {
        throw new RuntimeException("not quasi-ing");
    }

    public Astro atHole(Astro litInt) {
        throw new RuntimeException("not quasi-ing");
    }
}