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

markm@eros.cs.jhu.edu markm@eros.cs.jhu.edu
Tue, 20 Nov 2001 07:32:07 -0500


markm       01/11/20 07:32:07

  Modified:    src/jsrc/org/erights/e/elang/evm FinalPattern.java
                        MetaExpr.java NounPattern.java VarPattern.java
               src/jsrc/org/erights/e/elang/syntax ELexer.java EParser.java
                        URI.java e.y
               src/jsrc/org/erights/e/elib/base EComparable.java
               src/jsrc/org/erights/e/elib/tables ConstMap.java
                        ConstSet.java
               src/jsrc/org/quasiliteral/quasiterm DollarHole.java
                        QuasiFunctor.java QuasiNode.java QuasiTerm.java
                        QuasiTermBuilder.java
               src/jsrc/org/quasiliteral/term Functor.java
                        SimpleTermBuilder.java Term.java Term.updoc
                        TermBuilder.java TermParser.java term.y
  Added:       src/jsrc/org/quasiliteral/quasiterm ArgHole.java AtHole.java
                        BaseHole.java ToFunctor.java ToLiteral.java
                        ToTerm.java
  Log:
  Major hole-structure reform

Revision  Changes    Path
1.13      +1 -1      e/src/jsrc/org/erights/e/elang/evm/FinalPattern.java

Index: FinalPattern.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/FinalPattern.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- FinalPattern.java	2001/11/17 18:25:54	1.12
+++ FinalPattern.java	2001/11/20 12:32:05	1.13
@@ -27,7 +27,7 @@
 
 
 /**
- * BNF: Identifier ':' expr <p>
+ * BNF: ID ':' expr <p>
  *
  * The identifier on the left is the defining occurrence of a variable
  * name.  The expression on the right is a "value guard expression".  The



1.12      +1 -1      e/src/jsrc/org/erights/e/elang/evm/MetaExpr.java

Index: MetaExpr.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/MetaExpr.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- MetaExpr.java	2001/11/10 19:40:39	1.11
+++ MetaExpr.java	2001/11/20 12:32:05	1.12
@@ -10,7 +10,7 @@
 
 
 /**
- * BNF: "meta(Identifier)" <p>
+ * BNF: "meta(ID)" <p>
  *
  * @see org.erights.e.elang.scope.Scope
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>



1.5       +1 -1      e/src/jsrc/org/erights/e/elang/evm/NounPattern.java

Index: NounPattern.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/NounPattern.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- NounPattern.java	2001/11/11 05:54:36	1.4
+++ NounPattern.java	2001/11/20 12:32:05	1.5
@@ -30,7 +30,7 @@
 import java.io.IOException;
 
 /**
- * BNF: Identifier ':' expr <p>
+ * BNF: ID ':' expr <p>
  *
  * The identifier on the left is the defining occurrence of a variable
  * name.  The expression on the right is a "value guard expression".  The



1.13      +1 -1      e/src/jsrc/org/erights/e/elang/evm/VarPattern.java

Index: VarPattern.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/evm/VarPattern.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- VarPattern.java	2001/11/17 18:25:54	1.12
+++ VarPattern.java	2001/11/20 12:32:05	1.13
@@ -31,7 +31,7 @@
 
 
 /**
- * BNF: 'var' Identifier ':' expr <p>
+ * BNF: 'var' ID ':' expr <p>
  *
  * The identifier on the left is the defining occurrence of a variable
  * name.  The expression on the right is a "slot guard expression".  The



1.65      +1 -1      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.64
retrieving revision 1.65
diff -u -r1.64 -r1.65
--- ELexer.java	2001/11/10 19:40:42	1.64
+++ ELexer.java	2001/11/20 12:32:05	1.65
@@ -967,7 +967,7 @@
         Twine source = endToken();
         int ttype = EParser.optKeywordType(source.bare());
         if (-1 == ttype) {
-            return new AstroToken(EParser.Identifier, source, source.bare());
+            return new AstroToken(EParser.ID, source, source.bare());
         } else {
             //keyword
             return new AstroToken(ttype, source);



1.102     +21 -21    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.101
retrieving revision 1.102
diff -u -r1.101 -r1.102
--- EParser.java	2001/11/11 17:51:13	1.101
+++ EParser.java	2001/11/20 12:32:05	1.102
@@ -165,7 +165,7 @@
 public final static short LiteralChar=259;
 public final static short LiteralString=260;
 public final static short LiteralTwine=261;
-public final static short Identifier=262;
+public final static short ID=262;
 public final static short VerbAssign=263;
 public final static short QuasiOpen=264;
 public final static short QuasiClose=265;
@@ -708,24 +708,24 @@
 null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
 null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
 null,null,null,null,null,null,null,null,null,"LiteralInteger","LiteralFloat64",
-"LiteralChar","LiteralString","LiteralTwine","Identifier","VerbAssign",
-"QuasiOpen","QuasiClose","DollarIdent","AtIdent","DollarOpen","AtOpen","URI",
-"URIStart","BodyStartWord","BodyNextWord","VTableStartWord","VTableNextWord",
-"BIND","CATCH","CLASS","DEF","DELEGATE","ELSE","ESCAPE","FINALLY","FOR","IF",
-"IN","MATCH","META","PRAGMA","SWITCH","THUNK","TO","TRY","VAR","WHEN","WHILE",
-"_","DEFINE","ON","SELECT","TYPEDEF","ABSTRACT","AN","AS","ATTRIBUTE","BE",
-"BEGIN","BEHALF","BELIEF","BELIEVE","BELIEVES","CASE","CONST","CONSTRUCTOR",
-"CONTEXT","DECLARE","DEFAULT","DEFMACRO","DEPRECATED","DISPATCH","DO",
-"ENCAPSULATE","ENCAPSULATED","ENCAPSULATES","END","ENSURE","ENUM","EVENTUAL",
-"EVENTUALLY","EXPORT","EXTENDS","FACET","FORALL","FUNCTION","GIVEN","HIDDEN",
-"HIDES","IMPLEMENTS","INTERFACE","IS","KNOW","KNOWS","LAMBDA","LET","METHOD",
-"METHODS","MODULE","NAMESPACE","NATIVE","OBEYS","OCTET","ONEWAY","PACKAGE",
-"PRIVATE","PROTECTED","PUBLIC","RAISES","RELIANCE","RELIANT","RELIES","RELY",
-"REVEAL","SAKE","SIGNED","STATIC","STRUCT","SUCHTHAT","SUPPORTS","SUSPECT",
-"SUSPECTS","SYNCHRONIZED","THIS","THROWS","TRANSIENT","TRUNCATABLE","UNSIGNED",
-"UNUM","USES","USING","UTF8","UTF16","VALUETYPE","VIRTUAL","VOLATILE","WSTRING",
-"EOL","OpLAnd","OpLOr","OpSame","OpNSame","OpButNot","OpLeq","OpABA","OpGeq",
-"OpThru","OpTill","OpAsl","OpAsr","OpFlrDiv","OpMod","OpPow","OpAss","OpAssAdd",
+"LiteralChar","LiteralString","LiteralTwine","ID","VerbAssign","QuasiOpen",
+"QuasiClose","DollarIdent","AtIdent","DollarOpen","AtOpen","URI","URIStart",
+"BodyStartWord","BodyNextWord","VTableStartWord","VTableNextWord","BIND",
+"CATCH","CLASS","DEF","DELEGATE","ELSE","ESCAPE","FINALLY","FOR","IF","IN",
+"MATCH","META","PRAGMA","SWITCH","THUNK","TO","TRY","VAR","WHEN","WHILE","_",
+"DEFINE","ON","SELECT","TYPEDEF","ABSTRACT","AN","AS","ATTRIBUTE","BE","BEGIN",
+"BEHALF","BELIEF","BELIEVE","BELIEVES","CASE","CONST","CONSTRUCTOR","CONTEXT",
+"DECLARE","DEFAULT","DEFMACRO","DEPRECATED","DISPATCH","DO","ENCAPSULATE",
+"ENCAPSULATED","ENCAPSULATES","END","ENSURE","ENUM","EVENTUAL","EVENTUALLY",
+"EXPORT","EXTENDS","FACET","FORALL","FUNCTION","GIVEN","HIDDEN","HIDES",
+"IMPLEMENTS","INTERFACE","IS","KNOW","KNOWS","LAMBDA","LET","METHOD","METHODS",
+"MODULE","NAMESPACE","NATIVE","OBEYS","OCTET","ONEWAY","PACKAGE","PRIVATE",
+"PROTECTED","PUBLIC","RAISES","RELIANCE","RELIANT","RELIES","RELY","REVEAL",
+"SAKE","SIGNED","STATIC","STRUCT","SUCHTHAT","SUPPORTS","SUSPECT","SUSPECTS",
+"SYNCHRONIZED","THIS","THROWS","TRANSIENT","TRUNCATABLE","UNSIGNED","UNUM",
+"USES","USING","UTF8","UTF16","VALUETYPE","VIRTUAL","VOLATILE","WSTRING","EOL",
+"OpLAnd","OpLOr","OpSame","OpNSame","OpButNot","OpLeq","OpABA","OpGeq","OpThru",
+"OpTill","OpAsl","OpAsr","OpFlrDiv","OpMod","OpPow","OpAss","OpAssAdd",
 "OpAssAnd","OpAssAprxDiv","OpAssFlrDiv","OpAssAsl","OpAssAsr","OpAssRemdr",
 "OpAssMod","OpAssMul","OpAssOr","OpAssPow","OpAssSub","OpAssXor","Send",
 "OpWhen","MapsTo","MatchBind","MisMatch","Audit",
@@ -991,7 +991,7 @@
 "map : MapsTo nounExpr",
 "verb : ident",
 "noun : ident",
-"ident : Identifier",
+"ident : ID",
 "ident : reserved",
 "assignop : OpAssAdd",
 "assignop : OpAssAnd",
@@ -1421,7 +1421,7 @@
     TheTokens[LiteralString]    = "LiteralString";
     TheTokens[LiteralTwine]     = "LiteralTwine";
 
-    TheTokens[Identifier]       = "Identifier";
+    TheTokens[ID]               = "ID";
     TheTokens[VerbAssign]       = "VerbAssign";
     TheTokens[QuasiOpen]        = "QuasiOpen";
     TheTokens[QuasiClose]       = "QuasiClose";



1.18      +4 -8      e/src/jsrc/org/erights/e/elang/syntax/URI.java

Index: URI.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/syntax/URI.java,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- URI.java	2001/11/10 19:40:42	1.17
+++ URI.java	2001/11/20 12:32:06	1.18
@@ -24,16 +24,13 @@
 
 /**
  * A URI is an E token and an E expression. <p> <pre>
- * URI ::=
- *      '<' Identifier ':' URICStart URICPart* '>'
- * URIStart ::=
- *      '<' Identifier ':'
+ *     URI ::= '<' identifier ':' URICStart URICPart* '>'
+ *     URIStart ::= '<' identifier ':'
  * </pre>
- * XXX This class should probably not define a separate subclass of
+ * XXX This class should not define a separate subclass of
  * AstroToken, but rather just provide some static conveniences for dealing
  * with AstroTokens that are of type URI or URIStart.
  *
- * @see org.erights.e.elang.syntax.Identifier
  * @see org.erights.e.elang.syntax.URI#isURICStart
  * @see org.erights.e.elang.syntax.URI#isURICPart
  *
@@ -134,9 +131,8 @@
     }
 
     /**
-     * The Identifier between the &lt; and the colon.
+     * The identifier between the &lt; and the colon.
      *
-     * @see org.erights.e.elang.syntax.Identifier
      */
     public String protocol() {
         return myProtocol;



1.94      +7 -7      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.93
retrieving revision 1.94
diff -u -r1.93 -r1.94
--- e.y	2001/11/06 06:27:32	1.93
+++ e.y	2001/11/20 12:32:06	1.94
@@ -55,12 +55,12 @@
 %token LiteralString    /* Double quoted */
 %token LiteralTwine     /* quasi-quoted without holes.  Not yet used */
 
-%token Identifier       /* like Java, but no "$"s, and not keyword */
-%token VerbAssign       /* Identifier "=" */
+%token ID               /* like Java's ident, but no "$"s, and not keyword */
+%token VerbAssign       /* ID "=" */
 %token QuasiOpen        /* ("`" char*) | (char*), up to hole */
 %token QuasiClose       /* QuasiOpen "`" */
-%token DollarIdent      /* "$" Identifier */
-%token AtIdent          /* ("@" Identifier) | "@_" */
+%token DollarIdent      /* "$" ID */
+%token AtIdent          /* ("@" ID) | "@_" */
 %token DollarOpen       /* "${" */
 %token AtOpen           /* "@{" */
 %token URI              /* "<" protocol ":" body ">" */
@@ -967,10 +967,10 @@
  ;
 
 /**
- * A non-reserved Identifier (as a String)
+ * A non-reserved ID (as a String)
  */
 ident:
-        Identifier              { $$ = ((AstroToken)$1).getValue(); }
+        ID                      { $$ = ((AstroToken)$1).getValue(); }
  |      reserved                { reserved("keyword \"" +
                                            ((AstroToken)$1).getText() +
                                            "\""); }
@@ -1466,7 +1466,7 @@
     TheTokens[LiteralString]    = "LiteralString";
     TheTokens[LiteralTwine]     = "LiteralTwine";
 
-    TheTokens[Identifier]       = "Identifier";
+    TheTokens[ID]               = "ID";
     TheTokens[VerbAssign]       = "VerbAssign";
     TheTokens[QuasiOpen]        = "QuasiOpen";
     TheTokens[QuasiClose]       = "QuasiClose";



1.2       +7 -7      e/src/jsrc/org/erights/e/elib/base/EComparable.java

Index: EComparable.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/base/EComparable.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- EComparable.java	2001/11/19 19:33:02	1.1
+++ EComparable.java	2001/11/20 12:32:06	1.2
@@ -9,17 +9,17 @@
 
     /**
      * 'x compareTo(y)' should return <ul>
-     * <li>0.0 is x is equivalent (in the order) to y: 'x <=> y'.</li>
-     * <li>A negative number if x is less than y: 'x < y'.</li>
-     * <li>A positive number if x is greater than y: 'x > y'.</li>
+     * <li>0.0 is x is equivalent (in the order) to y: 'x &lt;=&gt; y'.</li>
+     * <li>A negative number if x is less than y: 'x &lt; y'.</li>
+     * <li>A positive number if x is greater than y: 'x &gt; y'.</li>
      * <li>NaN is x and y are incomparable</li>
      * </ul>
      * This must follow the usual defintion of partial orders, except that we
      * don't require the order to be reflexive.  (In a reflexive order, for
-     * all x, 'x <=> x'.)  Rather, we require that for all x, either x is <=>
-     * itself or it is incomparable to itself.  This allows IEEE floating
-     * point numbers to play, even though NaNs break conventional reflexivity
-     * rules.
+     * all x, 'x &lt;=&gt; x'.)  Rather, we require that for all x, either x
+     * is &lt;=&gt; itself or it is incomparable to itself.  This allows IEEE
+     * floating point numbers to play, even though NaNs break conventional
+     * reflexivity rules.
      */
     double compareTo(EComparable other);
 }



1.30      +3 -3      e/src/jsrc/org/erights/e/elib/tables/ConstMap.java

Index: ConstMap.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/tables/ConstMap.java,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -r1.29 -r1.30
--- ConstMap.java	2001/11/19 19:15:35	1.29
+++ ConstMap.java	2001/11/20 12:32:06	1.30
@@ -112,8 +112,8 @@
 
     /**
      * This method enables E's magnitude comparison operators
-     * (<, <=, <=>, >=, >) to express subset-ness of the domains of
-     * ConstMaps. <p>
+     * (&lt;, &lt;=, &lt;=&gt;, &gt;=, &gt;) to express subset-ness of the
+     * domains of ConstMaps. <p>
      *
      * If this ConstMap's domain is a strict subset of other's, return -1.0.
      * If this ConstMap has the same domain as other, return 0.0.
@@ -123,7 +123,7 @@
      * The canonical implementation of ConstMap (ConstMapImpl)
      * recursively turns the question around of this ConstMap's size()
      * is smaller that other's.  Therefore, the base case is one in
-     * which this ConstMap's size() is >= other's.  Therefore,
+     * which this ConstMap's size() is &gt;= other's.  Therefore,
      * alternate implementations of ConstMaps must also treat this as
      * the base case.  XXX security implications?
      */



1.3       +2 -1      e/src/jsrc/org/erights/e/elib/tables/ConstSet.java

Index: ConstSet.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/tables/ConstSet.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ConstSet.java	2001/11/19 19:15:35	1.2
+++ ConstSet.java	2001/11/20 12:32:06	1.3
@@ -73,7 +73,8 @@
 
     /**
      * This method enables E's magnitude comparison operators
-     * (<, <=, <=>, >=, >) to express subset-ness of these sets.
+     * (&lt;, &lt;=, &lt;=&gt;, &gt;=, &gt;) to express subset-ness of these
+     * sets.
      * <p>
      * If this set is a strict subset of other's, return -1.0.
      * If this set has the same elements as other, return 0.0.



1.2       +23 -33    e/src/jsrc/org/quasiliteral/quasiterm/DollarHole.java

Index: DollarHole.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/quasiterm/DollarHole.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DollarHole.java	2001/11/19 19:33:02	1.1
+++ DollarHole.java	2001/11/20 12:32:06	1.2
@@ -15,6 +15,7 @@
 import org.erights.e.elib.tables.FlexList;
 import org.erights.e.elib.quasi.ValueMaker;
 import org.erights.e.elib.quasi.MatchMaker;
+import org.erights.e.elib.util.OneArgFunc;
 import org.quasiliteral.astro.AstroToken;
 import org.quasiliteral.term.TermLexer;
 import org.quasiliteral.term.TermParser;
@@ -25,41 +26,30 @@
 
 /**
  * Corresponds to a "${<expression>}".
- * <p>
- * Depending on context, it may represent a Functor, a Term, or a list of
- * Terms.
  *
  * @author <a href="mailto:markm@caplet.com">Mark S Miller</a>
  */
-public class DollarHole extends QuasiNode {
+public class DollarHole extends BaseHole {
 
     /**
      *
      */
-    public static StaticMaker DollarHoleMaker =
+    static public StaticMaker DollarHoleMaker =
       StaticMaker.make(DollarHole.class);
 
     /**
-     * @serial In normal usage, this should have the source position of the
-     *         expression that was extracted to leave this hole behind.
-     */
-    private final Twine mySource;
-
-    /**
-     * @serial Which dollar-hole is this?
-     */
-    private final BigInteger myIndex;
-
-    /**
      * @param index Which dollar-hole is this?
      */
-    public DollarHole(Twine source, BigInteger index) {
-        mySource = source;
-        myIndex = index;
+    public DollarHole(Twine source, BigInteger index, OneArgFunc converter) {
+        super(source, index, converter);
     }
 
     /**
+     * XXX This method is confused since we added converters.
      *
+     * @return Actually, when using the QuasiTermBuilder, this will return
+     *         a LitHole wrapping an equivalent DollarHole.  This is the
+     *         best we can do, as DollarHole is actually an internal type.
      */
     public Object qbuild(TermBuilder builder) {
         AstroToken token = new AstroToken(TermParser.LiteralInteger,
@@ -69,39 +59,32 @@
     }
 
     /**
-     * 'DollarHole new(mySource, myIndex)'
+     * 'DollarHole new(mySource, myIndex, myConverter)'
      */
     public Object[] getCanonicalState() {
         Object[] result = {
             DollarHoleMaker, "new",
-            mySource, myIndex
+            mySource, myIndex, myConverter
         };
         return result;
     }
 
     /**
-     * "Evaluates" to args[myIndex]
+     * "Evaluates" to convert(args[index])
      */
     public Object substitute(Object[] args) {
-        return args[myIndex.intValue()];
+        return myConverter.run(args[myIndex.intValue()]);
     }
 
     /**
-     * Matches iff the specimen is <=> args[index], where this dollar-hole is
-     * encoded as '${<index>}'.
+     * Matches iff the convert(specimen) &lt;=&gt; convert(args[index])
      */
     public boolean matchBind(Object[] args,
                              Object specimen,
                              FlexList bindings)
     {
-        if (! (specimen instanceof EComparable)) {
-            return false;
-        }
-        EComparable mine = (EComparable)args[myIndex.intValue()];
-        EComparable spec = (EComparable)specimen;
-        //XXX BUG: If mine and spec are types that don't compare, this will
-        //throw rather than returning false.  It's unclear where to fix this.
-        return 0.0 == mine.compareTo(spec);
+        return equiv(myConverter.run(specimen),
+                     myConverter.run(args[myIndex.intValue()]));
     }
 
     /**
@@ -109,5 +92,12 @@
      */
     public String toString(boolean quasiFlag) {
         return "${" + myIndex + "}";
+    }
+
+    /**
+     *
+     */
+    public BaseHole promote(OneArgFunc newConverter) {
+        return new DollarHole(mySource, myIndex, newConverter);
     }
 }



1.2       +11 -8     e/src/jsrc/org/quasiliteral/quasiterm/QuasiFunctor.java

Index: QuasiFunctor.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/quasiterm/QuasiFunctor.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- QuasiFunctor.java	2001/11/19 19:33:02	1.1
+++ QuasiFunctor.java	2001/11/20 12:32:06	1.2
@@ -129,10 +129,12 @@
     public Object qbuild(TermBuilder builder) {
         if (null == myValue) {
             return builder.functor(new AstroToken(TermParser.ID,
-                                              mySource,
-                                              myName));
+                                                  mySource,
+                                                  myName),
+                                   null);
         } else if (isJustLiteral()) {
-            return builder.literal(new AstroToken(myValueType,
+            return builder.functor(null,
+                                   new AstroToken(myValueType,
                                                   mySource,
                                                   myValue));
         } else {
@@ -192,9 +194,9 @@
      * Since QuasiFunctors currently contain no holes, this just determines
      * if the specimen matches.  For purposes of the match, the names must be
      * the same, the sources are ignored, and the values, if non-null, must be
-     * <=> (the same magnitude).  This has the peculiar consequence that a
-     * literal NaN can't be matched, since it isn't <=> to anything.  Further,
-     * 0.0 will match -0.0, since they are <=>.
+     * &lt;=&gt; (the same magnitude).  This has the peculiar consequence that a
+     * literal NaN can't be matched, since it isn't &lt;=&gt; to anything.  Further,
+     * 0.0 will match -0.0, since they are &lt;=&gt;.
      * <p>
      * If this QuasiFunctor's myValue is null, this is treated as a don't
      * care.  We should eventually be able to use an at-hole for this purpose
@@ -225,8 +227,9 @@
     /**
      * Is myName the name implied by the type of myValue?
      */
-    private boolean isJustLiteral() {
-        return TermParser.getTokenNames().get(myValueType).equals(myName);
+    public boolean isJustLiteral() {
+        return -1 != myValueType &&
+          TermParser.getTokenNames().get(myValueType).equals(myName);
     }
 
     /**



1.2       +11 -2     e/src/jsrc/org/quasiliteral/quasiterm/QuasiNode.java

Index: QuasiNode.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/quasiterm/QuasiNode.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- QuasiNode.java	2001/11/19 19:33:02	1.1
+++ QuasiNode.java	2001/11/20 12:32:06	1.2
@@ -34,8 +34,17 @@
   ValueMaker, MatchMaker {
 
     /**
+     * Possible source twine for tracking source position.
+     * <p>
+     * The default here just returns the empty twine.
+     */
+    public Twine getSource() {
+        return Twine.fromString("");
+    }
+
+    /**
      * When built using the QuasiTermBuilder, the result should be
-     * semantically equivalent to the original.
+     * semantically equivalent to the original except for source tracking.
      */
     public abstract Object qbuild(TermBuilder builder);
 
@@ -49,7 +58,7 @@
     /**
      * If the printed form is read by the term__quasiParser (the
      * QuasiTermBuilder), the result should be semantically equivalent to the
-     * original.
+     * original except for source tracking.
      */
     public abstract String toString(boolean quasiFlag);
 



1.2       +1 -4      e/src/jsrc/org/quasiliteral/quasiterm/QuasiTerm.java

Index: QuasiTerm.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/quasiterm/QuasiTerm.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- QuasiTerm.java	2001/11/19 19:33:02	1.1
+++ QuasiTerm.java	2001/11/20 12:32:06	1.2
@@ -65,10 +65,7 @@
     }
 
     /**
-     * Like a visitor pattern, where 'builder' is the visitor.
-     * <p>
-     * When built using the QuasiTermBuilder, the result should be
-     * a semantically equivalent copy.
+     *
      */
     public Object qbuild(TermBuilder builder) {
         Object builtFunctor = myFunctor.qbuild(builder);



1.2       +100 -78   e/src/jsrc/org/quasiliteral/quasiterm/QuasiTermBuilder.java

Index: QuasiTermBuilder.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/quasiterm/QuasiTermBuilder.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- QuasiTermBuilder.java	2001/11/19 19:33:02	1.1
+++ QuasiTermBuilder.java	2001/11/20 12:32:06	1.2
@@ -6,6 +6,7 @@
 import org.erights.e.elib.quasi.QuasiPatternParser;
 import org.erights.e.elib.quasi.ValueMaker;
 import org.erights.e.elib.quasi.MatchMaker;
+import org.erights.e.elib.prim.E;
 import org.quasiliteral.astro.AstroToken;
 import org.quasiliteral.term.TermBuilder;
 import org.quasiliteral.term.Term;
@@ -18,14 +19,17 @@
  * For building a quasiliteral for generating or matching Term/Functor trees.
  * <p>
  * The parameterization of types from TermBuilder are:<ul>
- * <li>PDollarHole -- ??</li>
- * <li>PAtHole -- ??</li>
- * <li>PHole -- ??</li>
- * <li>PDollarRepr -- ??</li>
- * <li>PFunctor -- {@link QuasiFunctor}</li>
- * <li>PTerm -- {@link QuasiTerm}</li>
- * <li>PTerms, PArgs -- a {@link ConstList} of {@link QuasiTerm}</li>
+ * <li>PLitHole -- a {@link BaseHole} of {@link ToLiteral}.</li>
+ * <li>PFunctorHole -- a {@link BaseHole} of {@link ToFunctor}.</li>
+ * <li>PTermHole -- a {@link BaseHole} of {@link ToTerm}.</li>
+ * <li>PArgHole -- an {@link ArgHole}.</li>
  * </ul>
+ * <ul>
+ * <li>PFunctor -- a {@link QuasiFunctor} or PFunctorHole.</li>
+ * <li>PTerm -- a {@link QuasiTerm} or PTermHole.</li>
+ * <li>PArg -- a {@link QuasiTerm}, PTermHole, or {@link ArgHole}.</li>
+ * <li>PArgs -- a {@link ConstList} of PArg.</li>
+ * </ul>
  *
  * @author <a href="mailto:markm@caplet.com">Mark S Miller</a>
  */
@@ -43,7 +47,7 @@
     private QuasiTermBuilder() {}
 
     /**
-     *
+     * XXX not yet implemented
      */
     public ValueMaker valueMaker(Twine template, int[] dlrHoles) {
         throw new RuntimeException
@@ -51,14 +55,14 @@
     }
 
     /**
-     *
+     * @return a {@link QuasiTerm} or PTermHole
      */
     public ValueMaker valueMaker(Twine template) {
-        return (QuasiTerm)TermParser.run(template, THE_ONE);
+        return (QuasiNode)TermParser.run(template, THE_ONE);
     }
 
     /**
-     *
+     * XXX not yet implemented
      */
     public MatchMaker matchMaker(Twine template,
                                  int[] dlrHoles,
@@ -69,10 +73,10 @@
     }
 
     /**
-     *
+     * @return a {@link QuasiTerm} or PTermHole
      */
     public MatchMaker matchMaker(Twine template) {
-        return (QuasiTerm)TermParser.run(template, THE_ONE);
+        return (QuasiNode)TermParser.run(template, THE_ONE);
     }
 
     /**
@@ -81,40 +85,32 @@
     public boolean doesQuasis() { return true; }
 
     /**
-     * @return :ConstList(QuasiTerm)
+     * @return :[(QuasiTerm | PTermHole | ArgHole)*]
      */
     public Object argList() {
         return ConstList.EmptyList;
     }
 
     /**
-     * @param first :QuasiTerm
-     * @return :ConstList(QuasiTerm)
+     * @param first :(QuasiTerm | PTermHole | ArgHole)
+     * @return :[(QuasiTerm | PTermHole | ArgHole)*]
      */
     public Object argList(Object first) {
         return ConstList.EmptyList.with(first);
     }
 
     /**
-     * @param list :ConstList(QuasiTerm)
-     * @param next :QuasiTerm
-     * @return :ConstList(QuasiTerm)
+     * @param list :[(QuasiTerm | PTermHole | ArgHole)*]
+     * @param next :(QuasiTerm | PTermHole | ArgHole)
+     * @return :[(QuasiTerm | PTermHole | ArgHole)*]
      */
     public Object argList(Object list, Object next) {
         return ((ConstList)list).with(next);
     }
 
-    /**
-     *
-     */
-    public Object term(Object fnctr) {
-        //XXX Must promote hole to Term hole
-        return term(fnctr, ConstList.EmptyList);
-    }
-
     /**
-     * @param fnctr :(QuasiNode
-     * @param args :ConstList(QuasiNode)
+     * @param fnctr :(QuasiFunctor | PFunctorHole)
+     * @param args :[(QuasiTerm | PTermHole | ArgHole)*]
      * @return :QuasiTerm
      */
     public Object term(Object fnctr, Object args) {
@@ -122,82 +118,108 @@
     }
 
     /**
-     * @param ident :AstroToken(ID)
+     * @param optIdent :(AstroToken(ID) | null)
+     * @param optLit :(AstroToken(Literal*) | PLitHole | null)
      * @return :QuasiFunctor
      */
-    public Object functor(Object ident) {
-        AstroToken tok = (AstroToken)ident;
-        if (TermParser.ID != tok.getType()) {
-            throw new RuntimeException("Must be ID: " + ident);
-        }
-        String name = (String)tok.getValue();
-        if (null == name) {
-            throw new RuntimeException("Must have value: " + ident);
-        }
-        return new QuasiFunctor(name, tok.getSource(), null);
-    }
+    public Object functor(Object optIdent, Object optLit) {
+        AstroToken optIdTok = (AstroToken)optIdent;
 
-    /**
-     * @param lit :AstroToken(Literal*)
-     * @return :QuasiFunctor
-     */
-    public Object literal(Object lit) {
-        AstroToken tok = (AstroToken)lit;
-        //XXX check that it's a kind of literal
-        Functor functor = tok.asFunctor(TermParser.getTokenNames());
-        return new QuasiFunctor(functor);
+        String name = null;
+        Twine source = null;
+        Object value = null;
+
+        if (null == optIdTok) {
+            //Just a literal.  optLit may not be a LitHole.
+            E.require(null != optLit, "can't default entire functor");
+            AstroToken litTok = (AstroToken)optLit;
+            ConstList typeNames = TermParser.getTokenNames();
+            name = (String)typeNames.get(litTok.getType());
+            source = litTok.getSource();
+            value = litTok.getValue();
+
+        } else {
+            //Has an explicit name (a tagging identifier)
+            if (TermParser.ID != optIdTok.getType()) {
+                throw new RuntimeException("Must be ID: " + optIdTok);
+            }
+            name = (String)optIdTok.getValue();
+            if (null == name) {
+                throw new RuntimeException("Must have value: " + optIdTok);
+            }
+            source = (Twine)optIdTok.getSource();
+
+            if (null == optLit) {
+                //Just a name, all done
+
+            } else if (optLit instanceof AstroToken) {
+                //A name and a literal
+                AstroToken litTok = (AstroToken)optLit;
+                source = (Twine)source
+                  .add(":")
+                  .add(litTok.getSource());
+                value = litTok.getValue();
+
+            } else if (optLit instanceof BaseHole) {
+                //A name and a literal-hole
+                BaseHole litHole = (BaseHole)optLit;
+                source = (Twine)source
+                  .add(":")
+                  .add(litHole.getSource());
+                value = litHole;
+            }
+        }
+        return new QuasiFunctor(name, source, value);
     }
 
     /**
-     * @param ident :AstroToken(ID)
-     * @param lit :AstroToken(Literal*)
-     * @return :QuasiFunctor
+     *
      */
-    public Object functor(Object ident, Object lit) {
-        AstroToken idTok = (AstroToken)ident;
-        AstroToken litTok = (AstroToken)lit;
-
-        if (TermParser.ID != idTok.getType()) {
-            throw new RuntimeException("Must be ID: " + ident);
-        }
-        String name = (String)idTok.getValue();
-        if (null == name) {
-            throw new RuntimeException("Must have value: " + ident);
-        }
-        Twine source = (Twine)idTok.getSource()
-          .add(":")
-          .add(litTok.getSource());
-        return new QuasiFunctor(name, source, litTok.getValue());
+    public Object argHole(Object optTerm, Object quant) {
+        AstroToken qtoken = (AstroToken)quant;
+        char q = (char)qtoken.getType();
+        E.require("?+*".indexOf(q) >= 0,
+                  "Must be a '?', '+', or '*': " + q);
+        //XXX Should cache the three Characters.
+        return new ArgHole((QuasiNode)optTerm, new Character(q));
     }
 
     /**
      *
      */
-    public Object dollarHole(Object index) {
-        AstroToken token = ((AstroToken)index);
-        return new DollarHole((Twine)token.getSource(),
-                              (BigInteger)token.getValue());
+    public Object termHole(Object optIdent, Object fnctrHole) {
+        ToTerm converter = ToTerm.ANY_TERM;
+        if (null != optIdent) {
+            throw new RuntimeException("XXX not yet implemented");
+        }
+        return ((BaseHole)fnctrHole).promote(converter);
     }
 
     /**
      *
      */
-    public Object atHole(Object index) {
-        throw new RuntimeException("XXX Not yet implemented");
+    public Object functorHole(Object litHole) {
+        return ((BaseHole)litHole).promote(ToFunctor.THE_ONE);
     }
 
     /**
      *
      */
-    public Object dollarQuant(Object dHole, Object quant) {
-        throw new RuntimeException("XXX Not yet implemented");
+    public Object dollarHole(Object index) {
+        AstroToken token = ((AstroToken)index);
+        return new DollarHole((Twine)token.getSource(),
+                              (BigInteger)token.getValue(),
+                              ToLiteral.THE_ONE);
     }
 
     /**
      *
      */
-    public Object atQuant(Object optIdent, Object optQuant, Object atHole) {
-        throw new RuntimeException("XXX Not yet implemented");
+    public Object atHole(Object index) {
+        AstroToken token = ((AstroToken)index);
+        return new AtHole((Twine)token.getSource(),
+                          (BigInteger)token.getValue(),
+                          ToLiteral.THE_ONE);
     }
 
     /**



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

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

import org.quasiliteral.term.TermBuilder;
import org.quasiliteral.term.TermParser;
import org.quasiliteral.astro.AstroToken;
import org.erights.e.elib.tables.FlexList;
import org.erights.e.elib.tables.Twine;
import org.erights.e.elib.prim.StaticMaker;

/**
 * Represents a subsequence of Terms
 *
 * @author <a href="mailto:markm@caplet.com">Mark S Miller</a>
 */
public class ArgHole extends QuasiNode {

    /**
     *
     */
    static public StaticMaker ArgHoleMaker =
      StaticMaker.make(ArgHole.class);

    /**
     *
     */
    private final QuasiNode myOptTerm;

    /**
     * @serial One of '?', '+', or '*'
     */
    private final Character myQuant;

    /**
     *
     */
    public ArgHole(QuasiNode optTerm, Character quant) {
        myOptTerm = optTerm;
        myQuant = quant;
    }

    /**
     *
     */
    public Object qbuild(TermBuilder builder) {
        return builder.argHole(myOptTerm,
                               new AstroToken(myQuant.charValue(),
                                              Twine.fromString(""),
                                              null));
    }

    /**
     *
     */
    public String toString(boolean quasiFlag) {
        if (null == myOptTerm) {
            return myQuant.toString();
        } else {
            return myOptTerm.toString(quasiFlag) + " " + myQuant;
        }
    }

    /**
     * 'ArgHoleMaker new(myOptTerm, myQuant)'
     */
    public Object[] getCanonicalState() {
        Object[] result = {
            ArgHoleMaker, "new", myOptTerm, myQuant
        };
        return result;
    }

    /**
     *
     */
    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");
    }
}



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

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

import antlr.Token;
import org.erights.e.develop.format.StringHelper;
import org.erights.e.elib.base.SourceSpan;
import org.erights.e.elib.base.EComparable;
import org.erights.e.elib.prim.E;
import org.erights.e.elib.prim.StaticMaker;
import org.erights.e.elib.serial.PassByConstruction;
import org.erights.e.elib.serial.Persistent;
import org.erights.e.elib.tables.ConstList;
import org.erights.e.elib.tables.ConstMap;
import org.erights.e.elib.tables.Selfless;
import org.erights.e.elib.tables.Twine;
import org.erights.e.elib.tables.FlexList;
import org.erights.e.elib.quasi.ValueMaker;
import org.erights.e.elib.quasi.MatchMaker;
import org.erights.e.elib.util.OneArgFunc;
import org.quasiliteral.astro.AstroToken;
import org.quasiliteral.term.TermLexer;
import org.quasiliteral.term.TermParser;
import org.quasiliteral.term.TermBuilder;
import org.quasiliteral.term.Functor;

import java.math.BigInteger;

/**
 * Corresponds to a "@{<expression>}".
 * <p>
 * Depending on context, it may represent literal data, a Functor, or a Term.
 *
 * @author <a href="mailto:markm@caplet.com">Mark S Miller</a>
 */
public class AtHole extends BaseHole {

    /**
     *
     */
    static public StaticMaker AtHoleMaker =
      StaticMaker.make(AtHole.class);

    /**
     * @param index Which at-hole is this?
     */
    public AtHole(Twine source, BigInteger index, OneArgFunc converter) {
        super(source, index, converter);
    }

    /**
     * XXX This method is confused since we added converters.
     *
     * @return Actually, when using the QuasiTermBuilder, this will return
     *         a LitHole wrapping an equivalent AtHole.  This is the
     *         best we can do, as AtHole is actually an internal type.
     */
    public Object qbuild(TermBuilder builder) {
        AstroToken token = new AstroToken(TermParser.LiteralInteger,
                                          mySource,
                                          myIndex);
        return builder.atHole(token);
    }

    /**
     * 'AtHole new(mySource, myIndex, myConverter)'
     */
    public Object[] getCanonicalState() {
        Object[] result = {
            AtHoleMaker, "new", mySource, myIndex, myConverter
        };
        return result;
    }

    /**
     * Throws, since a tree with at-holes is not a valid ValueMaker
     */
    public Object substitute(Object[] args) {
        throw new RuntimeException("Not a valid ValueMaker");
    }

    /**
     * Places convert(specimen) at bindings[index], or, if bindings[index] is
     * already occupied, verifies that
     * convert(specimen) &lt;=&gt; convert(bindings[index]).
     * <p>
     * The second case (binding already occupied) cannot occur as a result of
     * the standard E quasiliteral expansion, but is defined to support other
     * uses of these abstractions.  The "occupied bindings must agree" rule
     * will be familiar to logic programmers.
     */
    public boolean matchBind(Object[] args,
                             Object specimen,
                             FlexList bindings)
    {
        specimen = myConverter.run(specimen);
        Object old = bindings.get(myIndex.intValue());
        if (null == old) {
            bindings.put(myIndex.intValue(), specimen);
            return true;
        } else {
            return DollarHole.equiv(myConverter.run(old), specimen);
        }
    }

    /**
     *
     */
    public String toString(boolean quasiFlag) {
        return "@{" + myIndex + "}";
    }

    /**
     *
     */
    public BaseHole promote(OneArgFunc newConverter) {
        return new AtHole(mySource, myIndex, newConverter);
    }
}



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

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

import antlr.Token;
import org.erights.e.develop.format.StringHelper;
import org.erights.e.elib.base.SourceSpan;
import org.erights.e.elib.base.EComparable;
import org.erights.e.elib.prim.E;
import org.erights.e.elib.prim.StaticMaker;
import org.erights.e.elib.serial.PassByConstruction;
import org.erights.e.elib.serial.Persistent;
import org.erights.e.elib.tables.ConstList;
import org.erights.e.elib.tables.ConstMap;
import org.erights.e.elib.tables.Selfless;
import org.erights.e.elib.tables.Twine;
import org.erights.e.elib.tables.FlexList;
import org.erights.e.elib.quasi.ValueMaker;
import org.erights.e.elib.quasi.MatchMaker;
import org.erights.e.elib.util.OneArgFunc;
import org.quasiliteral.astro.AstroToken;
import org.quasiliteral.term.TermLexer;
import org.quasiliteral.term.TermParser;
import org.quasiliteral.term.TermBuilder;
import org.quasiliteral.term.Functor;

import java.math.BigInteger;

/**
 * Superclass of DollarHole and AtHole
 * <p>
 * Depending on context, it may represent literal data, a Functor, or a Term.
 *
 * @author <a href="mailto:markm@caplet.com">Mark S Miller</a>
 */
public abstract class BaseHole extends QuasiNode {

    /**
     * @serial In normal usage, this should have the source position of the
     *         expression that was extracted to leave this hole behind.
     */
    /*package*/ final Twine mySource;

    /**
     * @serial Which hole is this?
     */
    /*package*/ final BigInteger myIndex;

    /**
     * @serial Converts various data types into this hole's target data type.
     */
    /*package*/ final OneArgFunc myConverter;

    /**
     * @param index Which hole is this?
     */
    /*package*/ BaseHole(Twine source,
                         BigInteger index,
                         OneArgFunc converter)
    {
        mySource = source;
        myIndex = index;
        myConverter = converter;
    }

    /**
     * Tests if x &lt;=&gt; y.
     * <p>
     * Assumes they've already been converted
     */
    static public boolean equiv(Object x, Object y) {
        if (! (x instanceof EComparable)) {
            //XXX Bug: is this right, or should we E.as() first, or should
            //we forget EComparable and just E.call(.., "compareTo", ...)?
            return false;
        }
        if (! (y instanceof EComparable)) {
            return false;
        }
        //XXX BUG: If mine and spec are types that don't compare, this will
        //throw rather than returning false.  It's unclear where to fix this.
        return 0.0 == ((EComparable)x).compareTo((EComparable)y);
    }

    /**
     *
     */
    public Twine getSource() {
        return mySource;
    }

    /**
     *
     */
    public BigInteger getIndex() {
        return myIndex;
    }

    /**
     * A BaseHole just like this one but using 'newConverter' instead of
     * 'myConverter'
     */
    public abstract BaseHole promote(OneArgFunc newConverter);
}



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

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

import org.erights.e.elib.tables.FlexList;
import org.erights.e.elib.tables.Twine;
import org.erights.e.elib.tables.Selfless;
import org.erights.e.elib.prim.StaticMaker;
import org.erights.e.elib.prim.E;
import org.erights.e.elib.util.OneArgFunc;
import org.erights.e.elib.serial.PassByConstruction;
import org.erights.e.elib.serial.Persistent;
import org.quasiliteral.term.TermBuilder;
import org.quasiliteral.term.Functor;
import org.quasiliteral.term.TermParser;
import org.quasiliteral.astro.AstroToken;

/**
 * Converts to a Functor
 *
 * @author <a href="mailto:markm@caplet.com">Mark S Miller</a>
 */
public class ToFunctor
  implements OneArgFunc, Selfless, PassByConstruction, Persistent {

    /**
     *
     */
    static public StaticMaker ToFunctorMaker =
      StaticMaker.make(ToFunctor.class);

    /**
     *
     */
    static public ToFunctor THE_ONE = new ToFunctor();

    /**
     *
     */
    private ToFunctor() {}

    /**
     * 'ToFunctorMaker THE_ONE()'
     */
    public Object[] getCanonicalState() {
        Object[] result = { ToFunctorMaker, "THE_ONE" };
        return result;
    }

    /**
     * Converts data of in one of the arg types to the result type.
     *
     * @param arg :(null | AstroToken(Literal*) | Functor |
     *              Character | BigInteger | Double | String | Twine)
     * @return :Functor
     */
    public Object run(Object arg) {
        if (null == arg) {
            return null;
        }
        if (arg instanceof AstroToken) {
            AstroToken token = (AstroToken)arg;
            return token.asFunctor(TermParser.getTokenNames());
        }
        if (arg instanceof Functor) {
            return (Functor)arg;
        }
        //If arg isn't one of the remaining allowed types -- the literal
        //data types themselves -- then literalType/1 will throw.
        int ttype = Functor.literalType(arg);
        String name = (String)TermParser.getTokenNames().get(ttype);
        return new Functor(name,
                           Twine.fromString(""),
                           arg);
    }
}



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

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

import org.erights.e.elib.tables.FlexList;
import org.erights.e.elib.tables.Twine;
import org.erights.e.elib.tables.Selfless;
import org.erights.e.elib.prim.StaticMaker;
import org.erights.e.elib.prim.E;
import org.erights.e.elib.util.OneArgFunc;
import org.erights.e.elib.serial.PassByConstruction;
import org.erights.e.elib.serial.Persistent;
import org.quasiliteral.term.TermBuilder;
import org.quasiliteral.term.Functor;
import org.quasiliteral.term.TermParser;
import org.quasiliteral.astro.AstroToken;

/**
 * Converts to one of the literal data types
 *
 * @author <a href="mailto:markm@caplet.com">Mark S Miller</a>
 */
public class ToLiteral
  implements OneArgFunc, Selfless, PassByConstruction, Persistent {

    /**
     *
     */
    static public StaticMaker ToLiteralMaker =
      StaticMaker.make(ToLiteral.class);

    /**
     *
     */
    static public ToLiteral THE_ONE = new ToLiteral();

    /**
     *
     */
    private ToLiteral() {}

    /**
     * 'ToLiteralMaker THE_ONE()'
     */
    public Object[] getCanonicalState() {
        Object[] result = { ToLiteralMaker, "THE_ONE" };
        return result;
    }

    /**
     * Converts data of in one of the arg types to the result type.
     *
     * @param arg :(null | AstroToken(Literal*) | Functor |
     *              Character | BigInteger | Double | String | Twine)
     * @return :(null | Character | BigInteger | Double | String | Twine)
     */
    public Object run(Object arg) {
        if (null == arg) {
            return null;
        }
        if (arg instanceof AstroToken) {
            AstroToken token = (AstroToken)arg;
            Object result = token.getValue();
            if (token.getType() == Functor.literalType(result)) {
                return result;
            }
            throw new RuntimeException("Must be a simple literal: " + token);
        }
        if (arg instanceof Functor) {
            Functor f = (Functor)arg;
            E.require(f.isJustLiteral(),
                      "Must be a simple literal: " + f);
            return run(new AstroToken(f.getValueType(),
                                      f.getSource(),
                                      f.getValue()));
        }
        //If arg isn't one of the remaining allowed types -- the literal
        //data types themselves -- then literalType/1 will throw.
        return new AstroToken(Functor.literalType(arg),
                              Twine.fromString(""),
                              arg);
    }
}



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

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

import org.erights.e.elib.tables.FlexList;
import org.erights.e.elib.tables.Twine;
import org.erights.e.elib.tables.Selfless;
import org.erights.e.elib.prim.StaticMaker;
import org.erights.e.elib.prim.E;
import org.erights.e.elib.util.OneArgFunc;
import org.erights.e.elib.serial.PassByConstruction;
import org.erights.e.elib.serial.Persistent;
import org.quasiliteral.term.TermBuilder;
import org.quasiliteral.term.Functor;
import org.quasiliteral.term.TermParser;
import org.quasiliteral.astro.AstroToken;

/**
 * Converts either to any Term (if optName is null), or to a Term with a
 * particular tag name.
 *
 * @author <a href="mailto:markm@caplet.com">Mark S Miller</a>
 */
public class ToTerm
  implements OneArgFunc, Selfless, PassByConstruction, Persistent {

    /**
     *
     */
    static public StaticMaker ToTermMaker =
      StaticMaker.make(ToTerm.class);

    /**
     *
     */
    static public ToTerm ANY_TERM = new ToTerm(null);

    /**
     *
     */
    private final String myOptName;

    /**
     *
     */
    public ToTerm(String optName) {
        myOptName = optName;
    }

    /**
     * 'ToTermMaker ANY_TERM()' or 'ToTermMaker new(name)'
     */
    public Object[] getCanonicalState() {
        if (null == myOptName) {
            Object[] result = { ToTermMaker, "ANY_TERM" };
            return result;
        } else {
            Object[] result = { ToTermMaker, "new", myOptName };
            return result;
        }
    }

    /**
     *
     */
    public String getOptName() { return myOptName; }

    /**
     * Converts data of in one of the arg types to the result type.
     *
     * @param arg :(null | AstroToken(Literal*) | Functor |
     *              Term | Astro |
     *              Character | BigInteger | Double | String | Twine)
     * @return :Term
     */
    public Object run(Object arg) {
        throw new RuntimeException("XXX not yet implemented");
    }
}



1.8       +34 -13    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.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- Functor.java	2001/11/19 19:15:35	1.7
+++ Functor.java	2001/11/20 12:32:07	1.8
@@ -100,29 +100,47 @@
         }
         myName = name;
         mySource = source;
+        myValueType = literalType(value);
+        myValue = value;
+    }
+
+    /**
+     * returns the literal type code according to the type of 'value'.
+     * <p>
+     * <pre>
+     *   If value is         return is
+     *       null              -1
+     *       a Character       TermParser.LiteralChar
+     *       a BigInteger      TermParser.LiteralInteger
+     *       a Double          TermParser.LiteralFloat64
+     *       a String          TermParser.LiteralString
+     *       a Twine           TermParser.LiteralString
+     *       anything else     throw a complaint
+     * </pre>
+     */
+    static public int literalType(Object value) {
         if (null == value) {
-            myValueType = -1;
+            return -1;
         } else if (value instanceof Character) {
-            myValueType = TermParser.LiteralChar;
+            return TermParser.LiteralChar;
         } else if (value instanceof Number) {
             if (value instanceof BigInteger) {
-                myValueType = TermParser.LiteralInteger;
+                return TermParser.LiteralInteger;
             } else if (value instanceof Double) {
-                myValueType = TermParser.LiteralFloat64;
+                return TermParser.LiteralFloat64;
             } else {
                 throw new RuntimeException
                   ("XXX Functor value coercion not yet implemented");
             }
         } else if (value instanceof String) {
-            myValueType = TermParser.LiteralString;
+            return TermParser.LiteralString;
             //XXX consider coercing value to Twine
         } else if (value instanceof Twine) {
-            myValueType = TermParser.LiteralString;
+            return TermParser.LiteralString;
         } else {
             throw new RuntimeException(value.getClass().getName() +
                                        " not a literal type");
         }
-        myValue = value;
     }
 
     /**
@@ -161,10 +179,12 @@
     public Object build(TermBuilder builder) {
         if (null == myValue) {
             return builder.functor(new AstroToken(TermParser.ID,
-                                              mySource,
-                                              myName));
+                                                  mySource,
+                                                  myName),
+                                   null);
         } else if (isJustLiteral()) {
-            return builder.literal(new AstroToken(myValueType,
+            return builder.functor(null,
+                                   new AstroToken(myValueType,
                                                   mySource,
                                                   myValue));
         } else {
@@ -248,10 +268,11 @@
     }
 
     /**
-     *
+     * Is myName the name implied by the type of myValue?
      */
-    private boolean isJustLiteral() {
-        return TermParser.getTokenNames().get(myValueType).equals(myName);
+    public boolean isJustLiteral() {
+        return -1 != myValueType &&
+          TermParser.getTokenNames().get(myValueType).equals(myName);
     }
 
     /**



1.6       +57 -61    e/src/jsrc/org/quasiliteral/term/SimpleTermBuilder.java

Index: SimpleTermBuilder.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/term/SimpleTermBuilder.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- SimpleTermBuilder.java	2001/11/19 19:15:35	1.5
+++ SimpleTermBuilder.java	2001/11/20 12:32:07	1.6
@@ -2,14 +2,14 @@
 
 import org.erights.e.elib.tables.ConstList;
 import org.erights.e.elib.tables.Twine;
+import org.erights.e.elib.prim.E;
 import org.quasiliteral.astro.AstroToken;
 
 /**
  * For building a actual (not quasiliteral) Term/Functor tree directly.
  * <p>
  * The parameterization of types from TermBuilder are:<ul>
- * <li>PDollarHole, PAtHole, PHole -- not applicable.</li>
- * <li>PLit -- AstroToken(Literal*).<.li>
+ * <li>PLitHole, PFunctorHole, PTermHole, PArgHole -- not applicable.</li>
  * <li>PFunctor -- {@link Functor}</li>
  * <li>PTerm, PArg -- {@link Term}</li>
  * <li>PArgs -- a {@link ConstList} of {@link Term}</li>
@@ -35,7 +35,7 @@
     public boolean doesQuasis() { return false; }
 
     /**
-     * @return :ConstList(Term)
+     * @return :[Term*]
      */
     public Object argList() {
         return ConstList.EmptyList;
@@ -43,16 +43,16 @@
 
     /**
      * @param first :Term
-     * @return :ConstList(Term)
+     * @return :[Term*]
      */
     public Object argList(Object first) {
         return ConstList.EmptyList.with(first);
     }
 
     /**
-     * @param list :ConstList(Term)
+     * @param list :[Term*]
      * @param next :Term
-     * @return :ConstList(Term)
+     * @return :[Term*]
      */
     public Object argList(Object list, Object next) {
         return ((ConstList)list).with(next);
@@ -60,94 +60,90 @@
 
     /**
      * @param fnctr :Functor
+     * @param args :[Term*]
      * @return :Term
      */
-    public Object term(Object fnctr) {
-        return new Term((Functor)fnctr, ConstList.EmptyList);
-    }
-
-    /**
-     * @param fnctr :Functor
-     * @param args :ConstList(Term)
-     * @return :Term
-     */
     public Object term(Object fnctr, Object args) {
         return new Term((Functor)fnctr, (ConstList)args);
     }
 
-    /**
-     * @param lit :AstroToken(Literal*)
-     * @return :Functor
-     */
-    public Object literal(Object lit) {
-        AstroToken tok = (AstroToken)lit;
-        //XXX check that it's a kind of literal
-        return tok.asFunctor(TermParser.getTokenNames());
-    }
-
     /**
-     * @param ident :AstroToken(ID)
+     * @param optIdent :(AstroToken(ID) | null)
+     * @param optLit :(AstroToken(Literal*) | null)
      * @return :Functor
      */
-    public Object functor(Object ident) {
-        AstroToken tok = (AstroToken)ident;
-        if (TermParser.ID != tok.getType()) {
-            throw new RuntimeException("Must be ID: " + ident);
+    public Object functor(Object optIdent, Object optLit) {
+        AstroToken optIdTok = (AstroToken)optIdent;
+        AstroToken optLitTok = (AstroToken)optLit;
+
+        String name = null;
+        Twine source = null;
+        Object value = null;
+
+        if (null == optIdTok) {
+            //Just a literal
+            E.require(null != optLitTok, "can't default entire functor");
+            ConstList typeNames = TermParser.getTokenNames();
+            name = (String)typeNames.get(optLitTok.getType());
+            source = optLitTok.getSource();
+            value = optLitTok.getValue();
+
+        } else {
+            //Has an explicit name (a tagging identifier)
+            if (TermParser.ID != optIdTok.getType()) {
+                throw new RuntimeException("Must be ID: " + optIdTok);
+            }
+            name = (String)optIdTok.getValue();
+            if (null == name) {
+                throw new RuntimeException("Must have value: " + optIdTok);
+            }
+            source = (Twine)optIdTok.getSource();
+
+            if (null == optLitTok) {
+                //Just a name, all done
+            } else {
+                //Has both
+                source = (Twine)source
+                  .add(":")
+                  .add(optLitTok.getSource());
+                value = optLitTok.getValue();
+            }
         }
-        String name = (String)tok.getValue();
-        if (null == name) {
-            throw new RuntimeException("Must have value: " + ident);
-        }
-        return new Functor(name, tok.getSource(), null);
+        return new Functor(name, source, value);
     }
 
     /**
-     * @param ident :AstroToken(ID)
-     * @param lit :AstroToken(Literal*)
-     * @return :Functor
+     * Not applicable -- doesn't do quasis.
      */
-    public Object functor(Object ident, Object lit) {
-        AstroToken idTok = (AstroToken)ident;
-        AstroToken litTok = (AstroToken)lit;
-
-        if (TermParser.ID != idTok.getType()) {
-            throw new RuntimeException("Must be ID: " + ident);
-        }
-        String name = (String)idTok.getValue();
-        if (null == name) {
-            throw new RuntimeException("Must have value: " + ident);
-        }
-        Twine source = (Twine)idTok.getSource()
-          .add(":")
-          .add(litTok.getSource());
-        return new Functor(name, source, litTok.getValue());
+    public Object argHole(Object optTerm, Object quant) {
+        throw new RuntimeException("No holes, not quasi parsing");
     }
 
     /**
-     * Not applicable
+     * Not applicable -- doesn't do quasis.
      */
-    public Object dollarHole(Object index) {
+    public Object termHole(Object optIdent, Object fnctrHole) {
         throw new RuntimeException("No holes, not quasi parsing");
     }
 
     /**
-     * Not applicable
+     * Not applicable -- doesn't do quasis.
      */
-    public Object atHole(Object index) {
+    public Object functorHole(Object litHole) {
         throw new RuntimeException("No holes, not quasi parsing");
     }
 
     /**
-     * Not applicable
+     * Not applicable -- doesn't do quasis.
      */
-    public Object dollarQuant(Object dHole, Object quant) {
+    public Object dollarHole(Object index) {
         throw new RuntimeException("No holes, not quasi parsing");
     }
 
     /**
-     * Not applicable
+     * Not applicable -- doesn't do quasis.
      */
-    public Object atQuant(Object optIdent, Object optQuant, Object atHole) {
+    public Object atHole(Object index) {
         throw new RuntimeException("No holes, not quasi parsing");
     }
 



1.4       +1 -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.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- Term.java	2001/11/19 19:15:35	1.3
+++ Term.java	2001/11/20 12:32:07	1.4
@@ -114,7 +114,7 @@
      * Like a visitor pattern, where 'builder' is the visitor.
      * <p>
      * When built using the SimpleTermBuilder, the result should be
-     * a semantically equivalent copy.
+     * a semantically equivalent copy except for source tracking.
      */
     public Object build(TermBuilder builder) {
         Object builtFunctor = myFunctor.build(builder);



1.8       +4 -1      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.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- Term.updoc	2001/11/19 19:15:35	1.7
+++ Term.updoc	2001/11/20 12:32:07	1.8
@@ -2,7 +2,10 @@
     # value: term`"foo"`
     
     ? def t2 := term`$t1(4)`
-    # value: term`"foo"(4)`
+    # problem: XXX not yet implemented
+    #
+    #   <QuasiTermBuilder> valueMaker("${0}(4)")
+    #   <interactive interp> evalPrint(e`def t2 :any := term__quasiParser valueMaker("${0}(4)") substitute(ListMaker run(t1))`)
     
     ? def t3 := term`$t1(bar, $t2)`
     # value: term`"foo"(bar,



1.5       +68 -76    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.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- TermBuilder.java	2001/11/19 19:15:35	1.4
+++ TermBuilder.java	2001/11/20 12:32:07	1.5
@@ -17,16 +17,18 @@
  * based on the productions in term.y.  Concrete subclasses should say what
  * concrete types they use for these parameterized types.
  * <p>
- * The pretend parameterized types, bottom to top, are:<ul>
+ * The pretend parameterized types, approximately bottom to top, are:<ul>
+ * <li>PLitHole -- as returned by dollarHole/1 and atHole/1.</li>
+ * <li>PFunctorHole -- as returned by functorHole/1.</li>
+ * <li>PTermHole -- as returned by termHole/2.</li>
+ * <li>PArgHole -- as returned by argHole/2.</li>
+ * </ul>
+ * <ul>
  * <li>{@link AstroToken} -- the actual concrete token type.</li>
- * <li>PDollarHole -- as returned by dollarHole/1.</li>
- * <li>PAtHole -- as returned by atHole/1.</li>
- * <li>PHole -- a PDollarHole or a PAtHole.</li>
- * <li>PLit -- an AstroToken(Literal*), PDollarHole, or PAtHole
- * <li>PFunctor -- a PHole or as returned by functor/1, functor/3, or
- *     literal/1.</li>
- * <li>PTerm -- as returned by term/1 and term/2.</li>
- * <li>PArg -- a PTerm or as returned by dollarQuant/2 or atQuant/3.</li>
+ * <li>PLit -- AstroToken(Literal*).<.li>
+ * <li>PFunctor -- a PFunctorHole or as returned by functor/2.</li>
+ * <li>PTerm -- as returned by term/2 or termHole/2.</li>
+ * <li>PArg -- a PTerm or PArgHole.</li>
  * <li>PArgs -- a list of PArgs, as returned by argList/0, argList/1,
  *     or argList/2.</li>
  * </ul>
@@ -55,6 +57,8 @@
 
     /**
      * The args list of one element.
+     * <p>
+     * Should be equivalent to 'argList(argList(), first)'
      *
      * @param first :PArg
      * @return :PArgs
@@ -71,19 +75,6 @@
     Object argList(Object list, Object next);
 
     /**
-     * A term without an explicit args list.
-     * <p>
-     * When fnctr is not a hole, term/1 just equivalent to term/2 with an
-     * empty args list.  When fnctr is a hole, then it is promoted from being
-     * a hole for a Functor to being a hole for a Term.  As a hole for a Term,
-     * it will still coerce a Functor to a Term with an empty args list.
-     *
-     * @param fnctr :PFunctor
-     * @return :PTerm
-     */
-    Object term(Object fnctr);
-
-    /**
      * The term 'fnctr(args...)'
      *
      * @param fnctr :PFunctor
@@ -93,85 +84,86 @@
     Object term(Object fnctr, Object args);
 
     /**
-     * The functor representing this literal
+     * Returns a representation of the functor whose type name is optIdent's
+     * value, and whose value is optLit's value.
+     * <p>
+     * At least one of optIdent and optLit must not be null.  If optIdent is
+     * null and optLit is literal, optIdent defaults to the name of the
+     * name of optLit's literal type.  If optLit is null, then, in a pattern,
+     * it means "don't-care".  In a non-pattern usage, null just means
+     * "no-data".
+     * <p>
+     * If optLit is a hole, then optIdent must be provided, and optLit remains
+     * a hole for literal data.  (The promotion of a lit-hole to a
+     * functor-hole is handled separately by functorHole/1.)
      *
-     * @param lit :AstroToken(Literal*)
+     * @param optIdent :(AstroToken(ID) | null)
+     * @param optLit :(PLit | PLitHole | null)
      * @return :PFunctor
      */
-    Object literal(Object lit);
+    Object functor(Object optIdent, Object optLit);
 
     /**
-     * The functor whose type name is ident's value.
+     * Promotes a term-hole to an arg-hole, which represents a sequence of
+     * terms.
+     * <p>
+     * An element of an args list may be an optional term or term-hole
+     * annotated with a quantity indicator: '?', '+', or '*' (with the usual
+     * meanings).
+     * <p>
+     * This should extract the maximal list of matching terms from the
+     * specimen, within the constraints of the quantity indicator and
+     * the term-hole's optional type name.
      *
-     * @param ident :AstroToken(ID)
-     * @return :PFunctor
+     * @param optTerm :(PTermHole | null)
+     * @param quant :AstroToken('?', '+', or '*')
+     * @return :PArg
      */
-    Object functor(Object ident);
+    Object argHole(Object optTerm, Object quant);
 
     /**
-     * The functor whose type name is ident's value, and whose value is
-     * lit's value.
+     * Promotes a functor-hole to a term-hole.
+     * <p>
+     * If the optIdent is provided, then it constrains the hole to only match
+     * Terms whose functor has that name.
      *
-     * @param ident :AstroToken(ID)
-     * @param lit :PLit
-     * @return :PFunctor
+     * @param optIdent :(AstroToken(ID) | null)
+     * @param fnctrHole :PFunctorHole
+     * @return :PTermHole
+     */
+    Object termHole(Object optIdent, Object fnctrHole);
+
+    /**
+     * Promotes a literal-hole to a functor-hole.
+     * <p>
+     * @param litHole :PLitHole
+     * @return :PFunctorHole
      */
-    Object functor(Object ident, Object lit);
+    Object functorHole(Object litHole);
 
     /**
      * A dollar-hole corresponds to an extracted expression whose value
      * should be substituted in at runtime.
+     * <p>
+     * As returned by dollarHole, this starts as a literal-hole (a hole
+     * representing literal data), but will often get promoted to another
+     * kind of hole.
      *
      * @param index :AstroToken(LiteralInteger)
-     * @return :PDollarHole
+     * @return :PLitHole
      */
     Object dollarHole(Object index);
 
     /**
      * An at-hole corresponds to an extracted pattern to be matched against
      * the corresponding part of the specimen at runtime.
+     * <p>
+     * As returned by dollarHole, this starts as a literal-hole (a hole
+     * representing literal data), but will often get promoted to another
+     * kind of hole.
      *
      * @param index :AstroToken(LiteralInteger)
-     * @return :PAtHole
+     * @return :PLitHole
      */
     Object atHole(Object index);
-
-    /**
-     * A dollar-quant represents some number of terms to be spliced into the
-     * args list (by substitution) at runtime.
-     * <p>
-     * This should coerce the substitution argument to a list of terms,
-     * require the size of the list to match the indicator, and splice
-     * this list into the args list of the resulting term.
-     *
-     * @param dHole :PDollarHole
-     * @param quant :AstroToken('?', '+', or '*')
-     * @return :PArg
-     */
-    Object dollarQuant(Object dHole, Object quant);
-
-    /**
-     * An element of an args list may be an at-hole annotated with a
-     * repetitions indicator, '?', '+', or '*' (with the usual meanings).
-     * <p>
-     * This should extract a list of terms from the specimen, require the
-     * size of the list to match the indicator, and provide this list for
-     * matching against the extracted pattern.
-     * <p>
-     * Actually, an optional functor-type identifier may be provided as well,
-     * and if it is, the quant argument may be left out.  If the identifier is
-     * provided, then only terms whose functor matches will be matched by
-     * this pattern.  If the quant is left out, then exactly one will be
-     * matched.
-     * <p>
-     * Note that, in the 'term' source language you may leave out both the
-     * identifier and quant, but that results in the term/1 production being
-     * called instead.
-     *
-     * @param optIdent :nullOk(AstroToken(ID))
-     * @param optQuant :nullOk(AstroToken('?', '+', or '*'))
-     * @param atHole :PAtHole
-     * @return :PArg
-     */
-    Object atQuant(Object optIdent, Object optQuant, Object atHole);
 }



1.6       +98 -94    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.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- TermParser.java	2001/11/19 19:15:35	1.5
+++ TermParser.java	2001/11/20 12:32:07	1.6
@@ -155,50 +155,49 @@
 public final static short LiteralString=261;
 public final static short YYERRCODE=256;
 final static short yylhs[] = {                           -1,
-    0,    1,    1,    3,    3,    4,    4,    5,    5,    5,
-    5,    5,    2,    2,    2,    2,    2,   10,   10,    6,
-    8,    7,    7,    7,    9,    9,    9,    9,
+    0,    2,    2,    3,    3,    4,    4,    4,    5,    5,
+    5,    1,    1,    1,    1,    1,    6,    6,    6,    6,
+    7,    8,    8,    8,    8,    9,    9,
 };
 final static short yylen[] = {                            2,
-    1,    1,    4,    0,    1,    1,    3,    1,    2,    3,
-    2,    2,    1,    1,    3,    1,    3,    1,    1,    4,
-    4,    1,    1,    1,    1,    1,    1,    1,
+    1,    0,    1,    1,    3,    1,    2,    1,    1,    1,
+    1,    1,    4,    4,    1,    2,    1,    1,    3,    3,
+    1,    1,    1,    1,    1,    4,    4,
 };
 final static short yydefred[] = {                         0,
-    0,   25,   26,   27,   28,    0,    0,    0,    1,    0,
-   18,   19,   13,   16,    0,    0,    0,    0,   15,   17,
-    0,    0,    0,   22,   23,   24,    8,    0,    0,    6,
-    0,    0,   20,   21,    0,   12,    3,    0,    9,   11,
-   10,    7,
+    0,   22,   23,   24,   25,    0,    0,    0,    1,    0,
+    0,   17,   21,    0,   16,    0,    0,    0,    0,   19,
+   20,    0,    0,    9,   10,   11,    0,    0,    0,    4,
+    8,    0,   26,   27,    7,   13,    0,   14,    5,
 };
 final static short yydgoto[] = {                          8,
-   27,   10,   28,   29,   30,   11,   32,   12,   13,   14,
+   27,   28,   29,   30,   31,   10,   11,   12,   13,
 };
 final static short yysindex[] = {                       -31,
-  -40,    0,    0,    0,    0, -102, -100,    0,    0,  -11,
-    0,    0,    0,    0,  -27, -235, -234,  -36,    0,    0,
-  -95,  -87,  -32,    0,    0,    0,    0,   -1,   -3,    0,
-  -29,  -20,    0,    0,  -20,    0,    0,  -36,    0,    0,
-    0,    0,
+  -34,    0,    0,    0,    0, -120, -119,    0,    0,  -26,
+  -25,    0,    0,  -27,    0, -242, -241,  -36,  -36,    0,
+    0, -106, -105,    0,    0,    0,  -32,  -20,  -22,    0,
+    0,  -18,    0,    0,    0,    0,  -36,    0,    0,
 };
 final static short yyrindex[] = {                         0,
-    3,    0,    0,    0,    0,    0,    0,    0,    0,    1,
-    0,    0,    0,    0,    0,    0,    0,    5,    0,    0,
-    0,    0,  -25,    0,    0,    0,    0,    0,    6,    0,
-   -5,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,
+    1,    0,    0,    0,    0,    0,    0,    0,    0,    8,
+   12,    0,    0,    0,    0,    0,    0,  -16,  -16,    0,
+    0,    0,    0,    0,    0,    0,  -28,    0,  -15,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,
 };
 final static short yygindex[] = {                         0,
-   48,    0,    0,    0,   11,  -16,  -19,  -15,   35,   36,
+   29,   13,    0,   -3,    9,    0,   34,   24,   25,
 };
 final static int YYTABLESIZE=234;
 final static short yytable[] = {                          6,
-    2,   31,   14,   35,    6,   26,   25,   36,    6,   26,
-   25,   39,   26,   25,   14,   14,   40,   15,   14,   41,
-   16,   31,   17,   21,   22,   15,   24,    7,   18,   33,
-   24,    7,    7,   24,   18,   18,    7,   34,   18,   37,
-   38,    2,   14,    7,    2,    4,    5,    9,   42,   19,
-   20,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+   18,    6,   16,   17,    6,   26,   25,   12,    6,   26,
+   25,   15,    6,   18,   19,    6,   22,   23,   33,   34,
+   36,   37,   38,   14,    2,    3,   24,    7,    9,    7,
+   24,   32,    7,   39,   15,   35,    7,   20,   21,    0,
+   18,   18,   18,   18,   18,    0,    0,    0,   12,   12,
+   12,   12,   15,   15,   15,   15,    0,    0,    0,    0,
+    0,    0,    0,   18,    0,    0,    0,    0,    0,    0,
+   12,    0,    0,    0,   15,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
@@ -213,19 +212,18 @@
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-   23,    2,    3,    4,    5,    1,    2,    3,    4,    5,
+    1,    2,    3,    4,    5,    1,    2,    3,    4,    5,
     2,    3,    4,    5,
 };
 final static short yycheck[] = {                         36,
-    0,   18,    0,   23,   36,   42,   43,   23,   36,   42,
-   43,   31,   42,   43,   40,   41,   32,   58,   44,   35,
-  123,   38,  123,  259,  259,   58,   63,   64,   40,  125,
-   63,   64,   64,   63,   40,   41,   64,  125,   44,   41,
-   44,   41,   40,   64,   44,   41,   41,    0,   38,   15,
-   15,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+    0,   36,  123,  123,   36,   42,   43,    0,   36,   42,
+   43,    0,   41,   40,   40,   44,  259,  259,  125,  125,
+   41,   44,   41,   58,   41,   41,   63,   64,    0,   64,
+   63,   19,   64,   37,    1,   27,   64,   14,   14,   -1,
+   40,   41,   42,   43,   44,   -1,   -1,   -1,   41,   42,
+   43,   44,   41,   42,   43,   44,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   63,   -1,   -1,   -1,   -1,   -1,   -1,
+   63,   -1,   -1,   -1,   63,   -1,   -1,   -1,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -240,7 +238,6 @@
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   257,  258,  259,  260,  261,  257,  258,  259,  260,  261,
   258,  259,  260,  261,
 };
@@ -269,33 +266,32 @@
 final static String yyrule[] = {
 "$accept : start",
 "start : term",
-"term : functor",
-"term : functor '(' argList ')'",
 "argList :",
 "argList : args",
 "args : arg",
 "args : args ',' arg",
 "arg : term",
-"arg : dollarHole quant",
-"arg : ID quant atHole",
-"arg : quant atHole",
-"arg : ID atHole",
-"functor : literal",
-"functor : ID",
-"functor : ID ':' literal",
-"functor : hole",
-"functor : ID ':' hole",
-"hole : dollarHole",
-"hole : atHole",
-"dollarHole : '$' '{' LiteralInteger '}'",
-"atHole : '@' '{' LiteralInteger '}'",
+"arg : term quant",
+"arg : quant",
 "quant : '?'",
 "quant : '+'",
 "quant : '*'",
+"term : functor",
+"term : functor '(' argList ')'",
+"term : functorHole '(' argList ')'",
+"term : functorHole",
+"term : ID functorHole",
+"functor : literal",
+"functor : ID",
+"functor : ID ':' literal",
+"functor : ID ':' litHole",
+"functorHole : litHole",
 "literal : LiteralChar",
 "literal : LiteralInteger",
 "literal : LiteralFloat64",
 "literal : LiteralString",
+"litHole : '$' '{' LiteralInteger '}'",
+"litHole : '@' '{' LiteralInteger '}'",
 };
 
 //#line 91 "term.y"
@@ -413,7 +409,7 @@
 static public ConstList getTokenNames() {
     return ConstList.fromArray(TheTokens);
 }
-//#line 365 "TermParser.java"
+//#line 361 "TermParser.java"
 //###############################################################
 // method: yylexdebug : check lexer state
 //###############################################################
@@ -560,70 +556,78 @@
       {
 //########## USER-SUPPLIED ACTIONS ##########
 case 1:
-//#line 27 "term.y"
+//#line 30 "term.y"
 { myOptResult = val_peek(0); }
 break;
 case 2:
-//#line 31 "term.y"
-{ yyval = b.term(val_peek(0)); }
-break;
-case 3:
-//#line 32 "term.y"
-{ yyval = b.term(val_peek(3), val_peek(1)); }
-break;
-case 4:
-//#line 36 "term.y"
+//#line 34 "term.y"
 { yyval = b.argList(); }
 break;
-case 6:
-//#line 41 "term.y"
+case 4:
+//#line 39 "term.y"
 { yyval = b.argList(val_peek(0)); }
 break;
-case 7:
-//#line 42 "term.y"
+case 5:
+//#line 40 "term.y"
 { yyval = b.argList(val_peek(2), val_peek(0)); }
 break;
-case 9:
-//#line 50 "term.y"
-{ yyval = b.dollarQuant(val_peek(1), val_peek(0)); }
-break;
-case 10:
-//#line 51 "term.y"
-{ yyval = b.atQuant(val_peek(2),   val_peek(1), val_peek(0)); }
-break;
-case 11:
-//#line 52 "term.y"
-{ yyval = b.atQuant(null, val_peek(1), val_peek(0)); }
+case 7:
+//#line 48 "term.y"
+{ yyval = b.argHole(  val_peek(1), val_peek(0)); }
+break;
+case 8:
+//#line 49 "term.y"
+{ yyval = b.argHole(null, val_peek(0)); }
 break;
 case 12:
-//#line 53 "term.y"
-{ yyval = b.atQuant(val_peek(1), null, val_peek(0)); }
+//#line 59 "term.y"
+{ yyval = b.term(val_peek(0), b.argList()); }
 break;
 case 13:
-//#line 57 "term.y"
-{ yyval = b.literal(val_peek(0)); }
+//#line 60 "term.y"
+{ yyval = b.term(val_peek(3), val_peek(1)); }
 break;
 case 14:
-//#line 58 "term.y"
-{ yyval = b.functor(val_peek(0)); }
+//#line 61 "term.y"
+{ yyval = b.term(val_peek(3), val_peek(1)); }
 break;
 case 15:
-//#line 59 "term.y"
-{ yyval = b.functor(val_peek(2), val_peek(0)); }
+//#line 63 "term.y"
+{ yyval = b.termHole(null, val_peek(0)); }
 break;
+case 16:
+//#line 64 "term.y"
+{ yyval = b.termHole(val_peek(1),   val_peek(0)); }
+break;
 case 17:
-//#line 61 "term.y"
+//#line 68 "term.y"
+{ yyval = b.functor(null, val_peek(0)); }
+break;
+case 18:
+//#line 69 "term.y"
+{ yyval = b.functor(val_peek(0), null); }
+break;
+case 19:
+//#line 70 "term.y"
 { yyval = b.functor(val_peek(2), val_peek(0)); }
 break;
 case 20:
-//#line 70 "term.y"
-{ yyval = b.dollarHole(val_peek(1)); }
+//#line 71 "term.y"
+{ yyval = b.functor(val_peek(2), val_peek(0)); }
 break;
 case 21:
-//#line 74 "term.y"
+//#line 75 "term.y"
+{ yyval = b.functorHole(val_peek(0)); }
+break;
+case 26:
+//#line 86 "term.y"
+{ yyval = b.dollarHole(val_peek(1)); }
+break;
+case 27:
+//#line 87 "term.y"
 { yyval = b.atHole(val_peek(1)); }
 break;
-//#line 572 "TermParser.java"
+//#line 576 "TermParser.java"
 //########## END OF USER-SUPPLIED ACTIONS ##########
     }//switch
     //#### Now let's reduce... ####



1.6       +28 -28    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.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- term.y	2001/11/19 19:15:35	1.5
+++ term.y	2001/11/20 12:32:07	1.6
@@ -23,15 +23,13 @@
 
 %%
 
+/**
+ * Represents a single Term
+ */
 start:
         term                            { myOptResult = $1; }
 ;
 
-term:
-        functor                         { $$ = b.term($1); }
- |      functor '(' argList ')'         { $$ = b.term($1, $3); }
- ;
-
 argList:
         /* empty */                     { $$ = b.argList(); }
  |      args
@@ -43,41 +41,38 @@
  ;
 
 /**
- * Each arg represents some number of terms
+ * Each arg represents some number of Terms
  */
 arg:
         term
- |      dollarHole quant                { $$ = b.dollarQuant($1, $2); }
- |      ID quant atHole                 { $$ = b.atQuant($1,   $2, $3); }
- |         quant atHole                 { $$ = b.atQuant(null, $1, $2); }
- |      ID       atHole                 { $$ = b.atQuant($1, null, $2); }
+ |      term quant                      { $$ = b.argHole(  $1, $2); }
+ |           quant                      { $$ = b.argHole(null, $1); }
  ;
 
-functor:
-        literal                         { $$ = b.literal($1); }
- |      ID                              { $$ = b.functor($1); }
- |      ID ':' literal                  { $$ = b.functor($1, $3); }
- |      hole
- |      ID ':' hole                     { $$ = b.functor($1, $3); }
+quant:
+        '?'
+ |      '+'
+ |      '*'
  ;
 
-hole:
-        dollarHole
- |      atHole
- ;
+term:
+        functor                         { $$ = b.term($1, b.argList()); }
+ |      functor     '(' argList ')'     { $$ = b.term($1, $3); }
+ |      functorHole '(' argList ')'     { $$ = b.term($1, $3); }
 
-dollarHole:
-        '$' '{' LiteralInteger '}'      { $$ = b.dollarHole($3); }
+ |         functorHole                  { $$ = b.termHole(null, $1); }
+ |      ID functorHole                  { $$ = b.termHole($1,   $2); }
  ;
 
-atHole:
-        '@' '{' LiteralInteger '}'      { $$ = b.atHole($3); }
+functor:
+               literal                  { $$ = b.functor(null, $1); }
+ |      ID                              { $$ = b.functor($1, null); }
+ |      ID ':' literal                  { $$ = b.functor($1, $3); }
+ |      ID ':' litHole                  { $$ = b.functor($1, $3); }
  ;
 
-quant:
-        '?'
- |      '+'
- |      '*'
+functorHole:
+        litHole                         { $$ = b.functorHole($1); }
  ;
 
 literal:
@@ -85,6 +80,11 @@
  |      LiteralInteger
  |      LiteralFloat64
  |      LiteralString
+ ;
+
+litHole:
+        '$' '{' LiteralInteger '}'      { $$ = b.dollarHole($3); }
+ |      '@' '{' LiteralInteger '}'      { $$ = b.atHole($3); }
  ;
 
 %%