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

markm@eros.cs.jhu.edu markm@eros.cs.jhu.edu
Sun, 4 Nov 2001 16:26:35 -0500


markm       01/11/04 16:26:34

  Modified:    src/jsrc/org/erights/e/elang/syntax EBuilder.java
                        ELexer.java EParser.java e.y
               src/jsrc/org/quasiliteral/term Functor.java
                        SimpleTermBuilder.java Term.updoc TermBuilder.java
                        TermLexer.java TermParser.java term.y
  Log:
  term language is much better

Revision  Changes    Path
1.81      +3 -17     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.80
retrieving revision 1.81
diff -u -r1.80 -r1.81
--- EBuilder.java	2001/11/03 13:32:50	1.80
+++ EBuilder.java	2001/11/04 21:26:33	1.81
@@ -234,14 +234,10 @@
 
         String verbName;
         if (verb instanceof AstroToken) {
-            verbName = ((AstroToken)verb).getText();
+            verbName = (String)((AstroToken)verb).getOptValue();
         } else {
             verbName = (String)verb;
         }
-        if (verbName.endsWith("=")) {
-            verbName = verbName.substring(0, verbName.length() -1);
-        }
-
         if (lValue instanceof NounExpr) {
             /*
              *  x "verb=" z expands to x := x verb(z)
@@ -601,12 +597,7 @@
      * When an at-hole is '@<ident>' or '@_'
      */
     /*package*/ Pattern atNoun(Object token) {
-        String str = ((AstroToken)token).getText();
-        if (str.charAt(0) != '@') {
-            throw new RuntimeException("internal: \"" + str +
-                                       "\" needs initial @");
-        }
-        str = str.substring(1);
+        String str = (String)((AstroToken)token).getOptValue();
         str = hilbert(str);
         if ("_".equals(str)) {
             return ignore();
@@ -658,12 +649,7 @@
      * When a dollar-hole is '$<ident>'
      */
     /*package*/ EExpr dollarNoun(Object token) {
-        String str = ((AstroToken)token).getText();
-        if (str.charAt(0) != '$') {
-            throw new RuntimeException("internal: \"" + str +
-                                       "\" needs initial $");
-        }
-        str = str.substring(1);
+        String str = (String)((AstroToken)token).getOptValue();
         str = hilbert(str);
         return noun(str);
     }



1.61      +10 -6     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.60
retrieving revision 1.61
diff -u -r1.60 -r1.61
--- ELexer.java	2001/11/04 00:38:11	1.60
+++ ELexer.java	2001/11/04 21:26:33	1.61
@@ -447,7 +447,7 @@
                         syntaxError(key + " is a keyword");
                     }
                     myIndenter.pop('$', name);
-                    return new AstroToken(EParser.DollarIdent, name);
+                    return new AstroToken(EParser.DollarIdent, name, key);
                 }
                 return new AstroToken('$', endToken());
             } case '@': {
@@ -464,7 +464,7 @@
                     nextChar();
                     Twine name = endToken();
                     myIndenter.pop('@', name);
-                    return new AstroToken(EParser.AtIdent, name);
+                    return new AstroToken(EParser.AtIdent, name, "_");
                 } else if (myChar != EOFCHAR &&
                            isIdentifierStart((char)myChar)) {
                     //A '@<ident>' closes a '@'
@@ -479,7 +479,7 @@
                         syntaxError(key + " is a keyword");
                     }
                     myIndenter.pop('@', name);
-                    return new AstroToken(EParser.AtIdent, name);
+                    return new AstroToken(EParser.AtIdent, name, key);
                 }
                 return new AstroToken('@', endToken());
             } case '.': {
@@ -879,15 +879,19 @@
                 //'<ident>=' is a VerbAss, given that the '=' isn't
                 //part of a '==', '=>', or '=~'.
                 nextChar();
-                return new AstroToken(EParser.VerbAss, endToken());
+                Twine source = endToken();
+                String name = source.bare().substring(0, source.size() -1);
+                return new AstroToken(EParser.VerbAss, source, name);
             }
         }
         Twine source = endToken();
         int ttype = EParser.tokenType(source.bare().toLowerCase());
         if (-1 == ttype) {
-            ttype = EParser.Identifier;
+            return new AstroToken(EParser.Identifier, source, source.bare());
+        } else {
+            //keyword
+            return new AstroToken(ttype, source);
         }
-        return new AstroToken(ttype, source);
     }
 
     /** pretty self explanatory */



1.98      +5 -7      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.97
retrieving revision 1.98
diff -u -r1.97 -r1.98
--- EParser.java	2001/11/04 00:38:11	1.97
+++ EParser.java	2001/11/04 21:26:33	1.98
@@ -1310,7 +1310,6 @@
     } catch (IOException ex) {
         yyerror("io: " + ex);
     }
-    yytext = token.getText();
     yylval = token;
     return token.getType();
 }
@@ -1322,7 +1321,6 @@
     int ttype = ((AstroToken)yylval).getType();
     if (EParser.EOFTOK == ttype && "syntax error".equals(s)) {
         myLexer.needMore("Unexpected EOF");
-        
     } else {
         syntaxError(s);
     }
@@ -1708,7 +1706,7 @@
 static public boolean isContinuer(int tokenType) {
     return TheContinuers[tokenType];
 }
-//#line 5627 "EParser.java"
+//#line 5625 "EParser.java"
 //###############################################################
 // method: yylexdebug : check lexer state
 //###############################################################
@@ -2685,13 +2683,13 @@
 break;
 case 260:
 //#line 973 "e.y"
-{ yyval = ((AstroToken)val_peek(0)).getText(); }
+{ yyval = ((AstroToken)val_peek(0)).getOptValue(); }
 break;
 case 261:
 //#line 974 "e.y"
 { reserved("keyword \"" +
-                                                   ((AstroToken)val_peek(0)).getText() +
-                                                   "\""); }
+                                           ((AstroToken)val_peek(0)).getText() +
+                                           "\""); }
 break;
 case 262:
 //#line 990 "e.y"
@@ -2875,7 +2873,7 @@
 //#line 1155 "e.y"
 { end(); }
 break;
-//#line 6791 "EParser.java"
+//#line 6789 "EParser.java"
 //########## END OF USER-SUPPLIED ACTIONS ##########
     }//switch
     //#### Now let's reduce... ####



1.92      +4 -5      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.91
retrieving revision 1.92
diff -u -r1.91 -r1.92
--- e.y	2001/11/04 03:12:28	1.91
+++ e.y	2001/11/04 21:26:34	1.92
@@ -970,10 +970,10 @@
  * A non-reserved Identifier (as a String)
  */
 ident:
-        Identifier                      { $$ = ((AstroToken)$1).getText(); }
- |      reserved                        { reserved("keyword \"" +
-                                                   ((AstroToken)$1).getText() +
-                                                   "\""); }
+        Identifier              { $$ = ((AstroToken)$1).getOptValue(); }
+ |      reserved                { reserved("keyword \"" +
+                                           ((AstroToken)$1).getText() +
+                                           "\""); }
  ;
 
 
@@ -1355,7 +1355,6 @@
     } catch (IOException ex) {
         yyerror("io: " + ex);
     }
-    yytext = token.getText();
     yylval = token;
     return token.getType();
 }



1.4       +28 -25    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.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- Functor.java	2001/11/04 03:12:28	1.3
+++ Functor.java	2001/11/04 21:26:34	1.4
@@ -28,10 +28,12 @@
  *     preserves the semantics of vanilla Tokens.
  * <li>It's PassByCopy, necessitating it be Immutable.</li>
  * <li>The token-type is identified by a string instead of a number,
- *     enabling it to make some sense without reference to a specific
+ *     enabling it to make sense wrt a source grammar instead of a compiled
  *     grammar.</li>
  * <li>The token-text is a {@link Twine} instead of a string, and can
  *     therefore remember its source positions.</li>
+ * <li>The semantically significant value is separate from the source
+ *     text.</li>
  * <li>It has a convenient printed form.</li>
  * </ul>
  *
@@ -66,17 +68,18 @@
 
     /**
      * @param tokenType The name of an Antlr token type int in a particular
-     *                  grammar.
+     *                  grammar.  Printed only if not implied by optValue.
      * @param source The source text corresponding to the original source of
      *               the token, although it isn't necessarily the same as the
      *               original source text.  In any case, its source span
      *               information says what positions in the original source
-     *               it corresponds to. The source position info is not part
+     *               it corresponds to. This is not part
      *               of the normal printed form.
      * @param optValue An optional {@link Character},
      *                 {@link BigInteger}, {@link Double},
      *                 {@link String}, or {@link Twine} calculated from the
-     *                 source text.
+     *                 source text.  If present, is always part of the
+     *                 normal printed form.
      */
     public Functor(String tokenType, Twine source, Object optValue) {
         myTokenType = tokenType;
@@ -166,31 +169,31 @@
     }
 
     /**
-     *
+     * XXX doesn't yet deal with LiteralTwine
      */
     public String toString(boolean quasiFlag) {
-        //XXX If the token type and source are implied by the printed
-        //form of the value, then only the value should be printed.
-        String result = myTokenType;
-        String bareSource = mySource.bare();
-        if (! myTokenType.equals(bareSource)) {
-            result += ":" + StringHelper.quote(bareSource);
-        }
-        if (null != myOptValue) {
-            //XXX If the value is a String or a Twine, then
-            //       if the token type is LiteralTwine, then
-            //          the token should be printed as a literal twine
-            //       else
-            //          the token should be printed as a literal string
-            //    else
-            //       the token should be printed according to its type
-            result += "=" + E.toQuote(myOptValue).bare();
+        if (null == myOptValue) {
+            return myTokenType;
         }
+        String valueStr = E.toQuote(myOptValue).bare();
         if (quasiFlag) {
-            result = StringHelper.replaceAll(result, "$", "$$");
-            result = StringHelper.replaceAll(result, "@", "@@");
-            result = StringHelper.replaceAll(result, "`", "``");
+            valueStr = StringHelper.replaceAll(valueStr, "$", "$$");
+            valueStr = StringHelper.replaceAll(valueStr, "@", "@@");
+            valueStr = StringHelper.replaceAll(valueStr, "`", "``");
         }
-        return result;
+        if ((myOptValue instanceof Character &&
+             "LiteralChar".equals(myTokenType)) ||
+            (myOptValue instanceof BigInteger &&
+             "LiteralInteger".equals(myTokenType)) ||
+            (myOptValue instanceof Double &&
+             "LiteralFloat64".equals(myTokenType)) ||
+            (myOptValue instanceof String &&
+             "LiteralString".equals(myTokenType)) ||
+            (myOptValue instanceof Twine &&
+             "LiteralString".equals(myTokenType))) {
+
+            return valueStr;
+        }
+        return myTokenType + ":" + valueStr;
     }
 }



1.2       +70 -90    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.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- SimpleTermBuilder.java	2001/11/04 03:12:59	1.1
+++ SimpleTermBuilder.java	2001/11/04 21:26:34	1.2
@@ -5,10 +5,14 @@
 import org.quasiliteral.astro.AstroToken;
 
 /**
- * Used by the actions of term.y / TermParser.
+ * For building a actual (not quasiliteral) Term/Functor tree directly.
  * <p>
- * XXX TermBuilder, TermParser, term.y, and TermLexer are all to be replaced
- * with Antlr-based equivalents.
+ * The parameterization of types from TermBuilder are:<ul>
+ * <li>PDollarHole, PAtHole, PHole, PDollarRepr -- not applicable.</li>
+ * <li>PFunctor -- {@link Functor}</li>
+ * <li>PTerm -- {@link Term}</li>
+ * <li>PTerms, PArgs -- a {@link ConstList} of {@link Term}</li>
+ * </ul>
  *
  * @author <a href="mailto:markm@caplet.com">Mark S Miller</a>
  */
@@ -22,137 +26,113 @@
     private SimpleTermBuilder() {}
 
     /**
-     *
+     * @return :ConstList(Term)
      */
-    public Object list() {
+    public Object terms() {
         return ConstList.EmptyList;
     }
 
     /**
-     *
+     * @param first :Term
+     * @return :ConstList(Term)
      */
-    public Object list(Object elem0) {
-        return ConstList.EmptyList.with(elem0);
+    public Object terms(Object first) {
+        return ConstList.EmptyList.with(first);
     }
 
     /**
-     *
+     * @param list :ConstList(Term)
+     * @param next :Term
+     * @return :ConstList(Term)
      */
-    public Object with(Object sofar, Object next) {
-        return ((ConstList)sofar).with(next);
+    public Object terms(Object list, Object next) {
+        return ((ConstList)list).with(next);
     }
 
     /**
-     *
+     * @param fnctr :Functor
+     * @param args :ConstList(Term)
+     * @return :Term
      */
     public Object term(Object fnctr, Object args) {
-        return new Term(asFunctor(fnctr), (ConstList)args);
+        return new Term((Functor)fnctr, (ConstList)args);
     }
 
     /**
-     *
+     * @param ident :AstroToken(Identifier)
+     * @return :Functor
      */
-    public Object functor(Object ttype, Object src, Object optValue) {
-        return new Functor(asString(ttype),
-                           asTwine(src),
-                           asOptValue(optValue));
+    public Object tag(Object ident) {
+        AstroToken tok = (AstroToken)ident;
+        if (TermParser.Identifier != tok.getType()) {
+            throw new RuntimeException("Must be Identifier: " + ident);
+        }
+        String name = (String)tok.getOptValue();
+        if (null == name) {
+            throw new RuntimeException("Must have value: " + ident);
+        }
+        return new Functor(name, tok.getSource(), null);
     }
 
     /**
-     *
+     * @param lit :AstroToken(Literal*)
+     * @return :Functor
      */
-    public Object dollarHole(Object index) {
-        throw new RuntimeException("SimpleTermBuilder doesn't allow holes");
+    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(Identifier)
+     * @param colon :AstroToken(':')
+     * @param lit :AstroToken(Literal*)
+     * @return :Functor
      */
-    public Object atHole(Object index) {
-        throw new RuntimeException("SimpleTermBuilder doesn't allow holes");
-    }
+    public Object compound(Object ident, Object colon, Object lit) {
+        AstroToken idTok = (AstroToken)ident;
+        AstroToken colonTok = (AstroToken)colon;
+        AstroToken litTok = (AstroToken)lit;
 
-    /**
-     *
-     */
-    public Object repr(Object hole, Object howMany) {
-        throw new RuntimeException("SimpleTermBuilder doesn't allow holes");
-    }
-
-    /**
-     *
-     */
-    private Functor asFunctor(Object f) {
-        if (f instanceof Functor) {
-            return (Functor)f;
-        } else if (f instanceof String) {
-            //XXX should check that it's a valid identifier
-            String str = (String)f;
-            return new Functor(str, Twine.fromString(str), null);
-        } else if (f instanceof Twine) {
-            //XXX should check that it's a valid identifier
-            Twine twine = (Twine)f;
-            return new Functor(twine.bare(), twine, null);
-        } else if (f instanceof AstroToken) {
-            AstroToken tok = (AstroToken)f;
-            return tok.asFunctor(TermParser.getTokenNames());
-        } else {
-            throw new RuntimeException("isn't like a Functor: " + f);
+        if (TermParser.Identifier != idTok.getType()) {
+            throw new RuntimeException("Must be Identifier: " + ident);
         }
+        String name = (String)idTok.getOptValue();
+        if (null == name) {
+            throw new RuntimeException("Must have value: " + ident);
+        }
+        Twine source = (Twine)idTok.getSource()
+          .add(colonTok.getSource())
+          .add(litTok.getSource());
+        return new Functor(name, source, litTok.getOptValue());
     }
 
     /**
-     *
+     * Not applicable
      */
-    private Object extract(AstroToken tok) {
-        Object result = tok.getOptValue();
-        if (result != null) {
-            return result;
-        } else {
-            return tok.getSource();
-        }
+    public Object dollarHole(Object index) {
+        throw new RuntimeException("No holes, not quasi parsing");
     }
 
     /**
-     *
+     * Not applicable
      */
-    private String asString(Object s) {
-        if (s instanceof String) {
-            return (String)s;
-        } else if (s instanceof Twine) {
-            return ((Twine)s).bare();
-        } else if (s instanceof AstroToken) {
-            return asString(extract((AstroToken)s));
-        } else {
-            throw new RuntimeException("isn't like a String: " + s);
-        }
+    public Object atHole(Object index) {
+        throw new RuntimeException("No holes, not quasi parsing");
     }
 
     /**
-     *
+     * Not applicable
      */
-    private Twine asTwine(Object t) {
-        if (t instanceof Twine) {
-            return (Twine)t;
-        } else if (t instanceof String) {
-            return Twine.fromString((String)t);
-        } else if (t instanceof AstroToken) {
-            return asTwine(extract((AstroToken)t));
-        } else {
-            throw new RuntimeException("isn't like a Twine: " + t);
-        }
+    public Object dollarRepr(Object dHole, Object repr) {
+        throw new RuntimeException("No holes, not quasi parsing");
     }
 
     /**
-     *
+     * Not applicable
      */
-    private Object asOptValue(Object v) {
-        if (null == v) {
-            return null;
-        } else if (v instanceof AstroToken) {
-            return extract((AstroToken)v);
-        } else {
-            throw new RuntimeException("can't extract value from: " + v);
-        }
+    public Object atRepr(Object terms, Object atHole, Object repr) {
+        throw new RuntimeException("No holes, not quasi parsing");
     }
 }



1.3       +3 -4      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.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Term.updoc	2001/11/04 03:12:28	1.2
+++ Term.updoc	2001/11/04 21:26:34	1.3
@@ -4,13 +4,12 @@
     ? def TermParserMaker := <term:TermParser>
     # value: <unsafe:org.quasiliteral.term.TermParser>
     
-    ? TermParserMaker(`foo(3, "bar"(3, 'x'), baz)`)
-    # value: term`foo(LiteralInteger:"3"=3,
-    #                 LiteralString:"\"bar\""="bar"(LiteralInteger:"3"=3, LiteralChar:"\'x\'"='x'),
+    ? TermParserMaker(`foo(3, x:"bar"(3, 'x'), baz)`)
+    # value: term`foo(3,
+    #                 x:"bar"(3, 'x'),
     #                 baz)`
     
     ? 
-
 
 
     ? def astro__uriGetter := <unsafe:org.quasiliteral.astro.*>



1.2       +99 -7     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.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TermBuilder.java	2001/11/04 03:12:28	1.1
+++ TermBuilder.java	2001/11/04 21:26:34	1.2
@@ -1,52 +1,144 @@
 package org.quasiliteral.term;
 
+import org.quasiliteral.astro.AstroToken;
+
 /**
  * Used by the actions of term.y / TermParser.
  * <p>
  * XXX TermBuilder, TermParser, term.y, and TermLexer are all to be replaced
- * with Antlr-based equivalents.
+ * with Antlr-based equivalents.  We hope that the abstraction provided by
+ * TermBuilder may allow it (and its subclasses) to survive this transition
+ * without great change.
+ * <p>
+ * The arguments and return types are all 'Object' below, because the actual
+ * types are to be determined by the subclasses.  However, these choices
+ * need to be consistent.  We express the required consistency using pretend
+ * parameterized types encoded in the javadoc comments.  The types names are
+ * 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>
+ * <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>PFunctor -- a PHole or as returned by tag/1, compound/3, or
+ *     literal/1.</li>
+ * <li>PTerm -- as returned by term/2.</li>
+ * <li>PDollarRepr -- as returned by dollarRepr/2.</li>
+ * <li>PTerms -- a list of PTerm and PDollarRepss, as returned by
+ *     terms/0, terms/1, dollarRepr/2, and terms/2.</li>
+ * <li>PArgs -- PTerms or as returned by atRepr/3.</li>
+ * </ul>
  *
  * @author <a href="mailto:markm@caplet.com">Mark S Miller</a>
  */
 public interface TermBuilder {
 
     /**
+     * The empty terms list
      *
+     * @return :PTerms
      */
-    Object list();
+    Object terms();
 
     /**
+     * The terms list of one element.
      *
+     * @param first :PTerm
+     * @return :PTerms
      */
-    Object list(Object elem0);
+    Object terms(Object first);
 
     /**
+     * Extend terms list with an additional term, like a backwards cons.
      *
+     * @param list :PTerms
+     * @param next :(PTerm | PDollarRepr)
+     * @return :PTerms
      */
-    Object with(Object sofar, Object next);
+    Object terms(Object list, Object next);
 
     /**
+     * The term 'fnctr(terms...)'
      *
+     * @param fnctr :PFunctor
+     * @param args :PArgs
+     * @return :PTerm
      */
     Object term(Object fnctr, Object args);
 
     /**
+     * The functor whose type name is ident's value.
+     *
+     * @param ident :AstroToken(Identifier)
+     * @return :PFunctor
+     */
+    Object tag(Object ident);
+
+    /**
+     * The functor representing this literal
+     *
+     * @param lit :AstroToken(Literal*)
+     * @return :PFunctor
+     */
+    Object literal(Object lit);
+
+    /**
+     * The functor whose type name is ident's value, and whose value is
+     * lit's value.
      *
+     * @param ident :AstroToken(Identifier)
+     * @param colon :AstroToken(':')
+     * @param lit :AstroToken(Literal*)
+     * @return :PFunctor
      */
-    Object functor(Object ttype, Object src, Object optValue);
+    Object compound(Object ident, Object colon, Object lit);
 
     /**
+     * A dollar-hole corresponds to an extracted expression whose value
+     * should be substituted in at runtime.
      *
+     * @param index :AstroToken(LiteralInteger)
+     * @return :PDollarHole
      */
     Object dollarHole(Object index);
 
     /**
+     * An at-hole corresponds to an extracted pattern to be matched against
+     * the corresponding part of the specimen at runtime.
      *
+     * @param index :AstroToken(LiteralInteger)
+     * @return :PAtHole
      */
     Object atHole(Object index);
 
     /**
-     *
+     * A dollar-repr 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 repr :AstroToken('?', '+', or '*')
+     * @return :PDollarReps
+     */
+    Object dollarRepr(Object dHole, Object repr);
+
+    /**
+     * The last 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.
+     *
+     * @param terms :PTerms
+     * @param atHole :PAtHole
+     * @param repr :AstroToken('?', '+', or '*')
+     * @return :PArgs
      */
-    Object repr(Object hole, Object howMany);
+    Object atRepr(Object terms, Object atHole, Object repr);
 }



1.2       +5 -60     e/src/jsrc/org/quasiliteral/term/TermLexer.java

Index: TermLexer.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/term/TermLexer.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TermLexer.java	2001/11/04 03:12:28	1.1
+++ TermLexer.java	2001/11/04 21:26:34	1.2
@@ -111,12 +111,9 @@
      */
     private void reset() {
         if (null != myLTwine) {
-            myPos = myLData.length-1;
-            myChar = myLData[myPos];
-            if ('\n' != myChar) {
-                throw new RuntimeException
-                  ("internal: must end with newline");
-            }
+            //A cheat
+            myPos = myLData.length;
+            myChar = '\n';
         }
         myOptStartPos = -1;
         myOptStartText = null;
@@ -287,7 +284,6 @@
         switch(myChar) {
             case ',':
             case ':':
-            case '=':
             case '$':
             case '@':
             case '?':
@@ -306,10 +302,6 @@
                 return openBracket('}');
             } case '}': {
                 return closeBracket();
-            } case '[': {
-                return openBracket(']');
-            } case ']': {
-                return closeBracket();
             } case '#': {
                 // Skip comment to end of line (as in "//" case above).
                 skipLine();
@@ -327,8 +319,6 @@
                 return charLiteral();
             } case '"': {
                 return stringLiteral();
-            } case '`': {
-                return twineLiteral();
             }
             case '0':
             case '1':
@@ -478,7 +468,8 @@
         do {
             nextChar();
         } while (myChar != EOFCHAR && isIdentifierPart((char)myChar));
-        return new AstroToken(TermParser.Identifier, endToken());
+        Twine source = endToken();
+        return new AstroToken(TermParser.Identifier, source, source.bare());
     }
 
     /** pretty self explanatory */
@@ -592,52 +583,6 @@
             return c == myLData[myPos +1];
         } else {
             return false;
-        }
-    }
-
-    /**
-     *
-     */
-    private AstroToken twineLiteral() throws IOException, SyntaxException {
-        nextChar(); //eat initial '`'
-        Twine openner = (Twine)myLTwine.run(myOptStartPos, myPos);
-        myIndenter.push(openner, '`', 0);
-        Twine value = Twine.fromString("");
-        while (true) {
-            int startSeg = myPos;
-            while ("$@`\n".indexOf(myChar) == -1) {
-                if (myChar == EOFCHAR) {
-                    syntaxError("File end inside quasi-string literal");
-                }
-                nextChar();
-            }
-            value = (Twine)value.add(myLTwine.run(startSeg, myPos));
-            //myChar is a '$', '@', '`', or '\n'
-
-            if ('\n' == myChar) {
-                value = (Twine)value.add(myLTwine.run(myPos, myPos+1));
-
-            } else if (peekChar((char)myChar)) {
-                //A doubled $, @, or ` is uninterpreted, and turns into a
-                //single one.
-                Twine dbl = (Twine)myLTwine.run(myPos, myPos+2);
-                value = (Twine)value.add(dbl.infect(""+(char)myChar,
-                                                    false));
-                nextChar();
-                nextChar();
-
-            } else if (myChar == '`') {
-                //terminal backquote is eaten but not added to the
-                //value of the resulting QuasiClose token.
-                nextChar();
-                Twine source = endToken();
-                myIndenter.pop('`', source);
-                return new AstroToken(TermParser.LiteralTwine,
-                                      source,
-                                      value);
-            } else {
-                syntaxError("unexpected: " + (char)myChar);
-            }
         }
     }
 



1.2       +100 -90   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.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TermParser.java	2001/11/04 03:12:28	1.1
+++ TermParser.java	2001/11/04 21:26:34	1.2
@@ -153,54 +153,57 @@
 public final static short LiteralInteger=259;
 public final static short LiteralFloat64=260;
 public final static short LiteralString=261;
-public final static short LiteralTwine=262;
 public final static short YYERRCODE=256;
 final static short yylhs[] = {                           -1,
-    0,    1,    1,    1,    3,    3,    4,    4,    4,    2,
-    2,    2,    2,    2,    2,    5,    5,    6,    6,    6,
-    7,    7,    7,    7,    7,
+    0,    1,    1,    3,    3,    4,    4,    4,    5,    5,
+    5,    5,    8,    2,    2,    2,    2,   11,   11,    9,
+    6,    7,    7,    7,   10,   10,   10,   10,
 };
 final static short yylen[] = {                            2,
-    1,    1,    4,    3,    0,    1,    1,    2,    3,    1,
-    3,    3,    5,    1,    1,    4,    4,    1,    1,    1,
-    1,    1,    1,    1,    1,
+    1,    1,    4,    0,    1,    1,    2,    4,    1,    3,
+    1,    3,    2,    1,    1,    3,    1,    1,    1,    4,
+    4,    1,    1,    1,    1,    1,    1,    1,
 };
 final static short yydefred[] = {                         0,
-    0,   21,   22,   23,   24,   25,    0,    0,    0,    0,
-    1,    0,   15,   14,    0,    0,    7,    0,    0,    0,
-    0,    0,    0,    0,   12,    4,    0,   18,   19,   20,
-    8,    0,    0,    0,    0,    9,   16,   17,    3,   13,
+    0,   25,   26,   27,   28,    0,    0,    0,    1,    0,
+   19,   18,   15,   17,    0,    0,    0,    0,   16,    0,
+    0,    9,    0,    5,    0,    0,   11,    0,   20,   21,
+    3,    0,   22,   23,   24,    7,   13,   10,    0,   12,
+    8,
+};
+final static short yydgoto[] = {                          8,
+    9,   10,   23,   24,   25,   11,   36,   27,   28,   13,
+   14,
 };
-final static short yydgoto[] = {                         10,
-   17,   12,   18,   19,   13,   31,   14,
-};
 final static short yysindex[] = {                       -36,
-  -40,    0,    0,    0,    0,    0,  -36, -104, -103,    0,
-    0,  -18,    0,    0, -238, -245,    0,  -69,  -15,  -31,
- -233, -229,  -36,  -28,    0,    0,  -36,    0,    0,    0,
-    0,  -91,  -90,   -5, -245,    0,    0,    0,    0,    0,
+  -45,    0,    0,    0,    0, -108, -107,    0,    0,  -23,
+    0,    0,    0,    0, -229, -238, -237,  -36,    0, -102,
+ -100,    0,  -15,    0,  -17,  -39,    0,  -39,    0,    0,
+    0,  -36,    0,    0,    0,    0,    0,    0,  -39,    0,
+    0,
 };
 final static short yyrindex[] = {                         0,
-    1,    0,    0,    0,    0,    0,  -56,    0,    0,    0,
-    0,    5,    0,    0,    0,    0,    0,    0,  -39,  -34,
-    0,    0,   -3,    3,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    1,    0,    0,    0,    0,    0,    0,    0,    0,    2,
+    0,    0,    0,    0,    0,    0,    0,   -8,    0,    0,
+    0,    0,    0,    0,   -7,  -32,    0,  -30,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,  -32,    0,
+    0,
 };
 final static short yygindex[] = {                         0,
-    4,    0,   16,    0,    2,    0,   -8,
+  -13,    0,    0,    0,    0,  -12,  -21,    3,   36,   22,
+    0,
 };
-final static int YYTABLESIZE=226;
-final static short yytable[] = {                          8,
-   10,    6,   11,   11,    2,   15,   15,   25,   20,   15,
-   30,   29,    2,    3,    4,    5,    6,   15,   21,   22,
-   16,   23,   24,   26,   20,   32,   40,    9,   27,   33,
-   36,   28,   35,   37,   38,   39,    5,    5,   34,    0,
-   10,   10,   11,   11,   10,    2,   11,    0,    2,    0,
-    0,    0,    0,    6,    7,    0,    0,    0,   15,    0,
+final static int YYTABLESIZE=225;
+final static short yytable[] = {                          6,
+   14,    2,   35,   34,   22,   26,   37,   19,   19,   18,
+   18,   19,   15,   18,   16,   17,   18,   41,   38,   39,
+   20,   21,   29,   33,   30,   31,   32,    7,    2,    3,
+    4,    5,    4,    6,   40,   12,   19,    0,    0,    0,
+   14,   14,    2,    0,   14,    2,    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,   10,    0,   11,    0,    2,    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 +216,19 @@
     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,
-    1,    2,    3,    4,    5,    6,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    1,    2,    3,    4,    5,
 };
 final static short yycheck[] = {                         36,
-    0,   41,    0,    0,    0,   40,   41,   16,    7,   44,
-   42,   43,  258,  259,  260,  261,  262,   58,  123,  123,
-   61,   40,  261,   93,   23,  259,   35,   64,   44,  259,
-   27,   63,   61,  125,  125,   41,   93,   41,   23,   -1,
-   40,   41,   40,   41,   44,   41,   44,   -1,   44,   -1,
-   -1,   -1,   -1,   93,   91,   -1,   -1,   -1,   93,   -1,
+    0,    0,   42,   43,   18,   18,   28,   40,   41,   40,
+   41,   44,   58,   44,  123,  123,   40,   39,   32,   32,
+  259,  259,  125,   63,  125,   41,   44,   64,  258,  259,
+  260,  261,   41,   41,   32,    0,   15,   -1,   -1,   -1,
+   40,   41,   41,   -1,   44,   44,   -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,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   93,   -1,   93,   -1,   93,   -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,
@@ -238,20 +241,21 @@
    -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,  262,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  257,  258,  259,  260,  261,
 };
-final static short YYFINAL=10;
-final static short YYMAXTOKEN=262;
+final static short YYFINAL=8;
+final static short YYMAXTOKEN=261;
 final static String yyname[] = {
 "end-of-file",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,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,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,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,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,null,null,null,null,null,null,
@@ -259,28 +263,32 @@
 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,null,null,null,null,null,null,null,
-null,null,null,null,null,null,null,null,null,"Identifier","LiteralChar",
-"LiteralInteger","LiteralFloat64","LiteralString","LiteralTwine",
+null,null,null,null,null,null,null,null,"Identifier","LiteralChar",
+"LiteralInteger","LiteralFloat64","LiteralString",
 };
 final static String yyrule[] = {
 "$accept : start",
 "start : term",
 "term : functor",
 "term : functor '(' argList ')'",
-"term : '[' argList ']'",
 "argList :",
 "argList : args",
-"args : term",
-"args : hole repr",
-"args : args ',' term",
+"args : terms",
+"args : atHole repr",
+"args : terms ',' atHole repr",
+"terms : term",
+"terms : terms ',' term",
+"terms : dollarRepr",
+"terms : terms ',' dollarRepr",
+"dollarRepr : dollarHole repr",
 "functor : Identifier",
-"functor : Identifier ':' LiteralString",
-"functor : Identifier '=' literal",
-"functor : Identifier ':' LiteralString '=' literal",
 "functor : literal",
+"functor : Identifier ':' literal",
 "functor : hole",
-"hole : '$' '{' LiteralInteger '}'",
-"hole : '@' '{' LiteralInteger '}'",
+"hole : dollarHole",
+"hole : atHole",
+"dollarHole : '$' '{' LiteralInteger '}'",
+"atHole : '@' '{' LiteralInteger '}'",
 "repr : '?'",
 "repr : '+'",
 "repr : '*'",
@@ -288,10 +296,9 @@
 "literal : LiteralInteger",
 "literal : LiteralFloat64",
 "literal : LiteralString",
-"literal : LiteralTwine",
 };
 
-//#line 78 "term.y"
+//#line 92 "term.y"
 
 /**
  * contains all the tokens after yylval
@@ -356,7 +363,6 @@
     } catch (IOException ex) {
         yyerror("io: " + ex);
     }
-    yytext = token.getText();
     yylval = token;
     return token.getType();
 }
@@ -407,7 +413,7 @@
 static /*package*/ ConstList getTokenNames() {
     return ConstList.fromArray(TheTokens);
 }
-//#line 359 "TermParser.java"
+//#line 365 "TermParser.java"
 //###############################################################
 // method: yylexdebug : check lexer state
 //###############################################################
@@ -554,62 +560,66 @@
       {
 //########## USER-SUPPLIED ACTIONS ##########
 case 1:
-//#line 28 "term.y"
+//#line 27 "term.y"
 { myOptResult = val_peek(0); }
 break;
 case 2:
-//#line 32 "term.y"
-{ yyval = b.term(val_peek(0), b.list()); }
+//#line 31 "term.y"
+{ yyval = b.term(val_peek(0), b.terms()); }
 break;
 case 3:
-//#line 33 "term.y"
+//#line 32 "term.y"
 { yyval = b.term(val_peek(3), val_peek(1)); }
 break;
 case 4:
-//#line 34 "term.y"
-{ yyval = b.term("list", val_peek(1)); }
-break;
-case 5:
-//#line 38 "term.y"
-{ yyval = b.list(); }
+//#line 36 "term.y"
+{ yyval = b.terms(); }
 break;
 case 7:
-//#line 43 "term.y"
-{ yyval = b.list(val_peek(0)); }
+//#line 42 "term.y"
+{ yyval = b.atRepr(b.terms(), val_peek(1), val_peek(0)); }
 break;
 case 8:
-//#line 44 "term.y"
-{ yyval = b.repr(val_peek(1), val_peek(0)); }
+//#line 43 "term.y"
+{ yyval = b.atRepr(val_peek(3), val_peek(1), val_peek(0)); }
 break;
 case 9:
-//#line 45 "term.y"
-{ yyval = b.with(val_peek(2), val_peek(0)); }
+//#line 47 "term.y"
+{ yyval = b.terms(val_peek(0)); }
 break;
 case 10:
-//#line 49 "term.y"
-{ yyval = b.functor(val_peek(0), val_peek(0), null); }
-break;
-case 11:
-//#line 50 "term.y"
-{ yyval = b.functor(val_peek(2), val_peek(0), null); }
+//#line 48 "term.y"
+{ yyval = b.terms(val_peek(2), val_peek(0)); }
 break;
 case 12:
 //#line 51 "term.y"
-{ yyval = b.functor(val_peek(2), val_peek(2), val_peek(0)); }
+{ yyval = b.terms(val_peek(2), val_peek(0)); }
 break;
 case 13:
-//#line 53 "term.y"
-{ yyval = b.functor(val_peek(4), val_peek(3), val_peek(2)); }
+//#line 55 "term.y"
+{ yyval = b.dollarRepr(val_peek(1), val_peek(0)); }
 break;
-case 16:
+case 14:
 //#line 59 "term.y"
-{ yyval = b.dollarHole(val_peek(1)); }
+{ yyval = b.tag(val_peek(0)); }
 break;
-case 17:
+case 15:
 //#line 60 "term.y"
+{ yyval = b.literal(val_peek(0)); }
+break;
+case 16:
+//#line 61 "term.y"
+{ yyval = b.compound(val_peek(2), val_peek(1), val_peek(0)); }
+break;
+case 20:
+//#line 71 "term.y"
+{ yyval = b.dollarHole(val_peek(1)); }
+break;
+case 21:
+//#line 75 "term.y"
 { yyval = b.atHole(val_peek(1)); }
 break;
-//#line 558 "TermParser.java"
+//#line 568 "TermParser.java"
 //########## END OF USER-SUPPLIED ACTIONS ##########
     }//switch
     //#### Now let's reduce... ####



1.2       +30 -16    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.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- term.y	2001/11/04 03:12:28	1.1
+++ term.y	2001/11/04 21:26:34	1.2
@@ -20,7 +20,7 @@
 %token LiteralInteger   //like Java & E: precision unlimited
 %token LiteralFloat64   //like Java & E: IEEE double precision
 %token LiteralString    //like Java & E: double quoted
-%token LiteralTwine     //like E: quasi-quoted without holes
+//XXX doesn't yet deal with LiteralTwine
 
 %%
 
@@ -29,35 +29,51 @@
 ;
 
 term:
-        functor                         { $$ = b.term($1, b.list()); }
+        functor                         { $$ = b.term($1, b.terms()); }
  |      functor '(' argList ')'         { $$ = b.term($1, $3); }
- |      '[' argList ']'                 { $$ = b.term("list", $2); }
  ;
 
 argList:
-        /* empty */                     { $$ = b.list(); }
+        /* empty */                     { $$ = b.terms(); }
  |      args
  ;
 
 args:
-        term                            { $$ = b.list($1); }
- |      hole repr                       { $$ = b.repr($1, $2); }
- |      args ',' term                   { $$ = b.with($1, $3); }
+        terms
+ |      atHole repr                     { $$ = b.atRepr(b.terms(), $1, $2); }
+ |      terms ',' atHole repr           { $$ = b.atRepr($1, $3, $4); }
  ;
 
+terms:
+        term                            { $$ = b.terms($1); }
+ |      terms ',' term                  { $$ = b.terms($1, $3); }
+
+ |      dollarRepr
+ |      terms ',' dollarRepr            { $$ = b.terms($1, $3); }
+ ;
+
+dollarRepr:
+        dollarHole repr                 { $$ = b.dollarRepr($1, $2); }
+ ;
+
 functor:
-        Identifier                      { $$ = b.functor($1, $1, null); }
- |      Identifier ':' LiteralString    { $$ = b.functor($1, $3, null); }
- |      Identifier '=' literal          { $$ = b.functor($1, $1, $3); }
- |      Identifier ':' LiteralString '=' literal
-                                        { $$ = b.functor($1, $2, $3); }
- |      literal
+        Identifier                      { $$ = b.tag($1); }
+ |      literal                         { $$ = b.literal($1); }
+ |      Identifier ':' literal          { $$ = b.compound($1, $2, $3); }
  |      hole
  ;
 
 hole:
+        dollarHole
+ |      atHole
+ ;
+
+dollarHole:
         '$' '{' LiteralInteger '}'      { $$ = b.dollarHole($3); }
- |      '@' '{' LiteralInteger '}'      { $$ = b.atHole($3); }
+ ;
+
+atHole:
+        '@' '{' LiteralInteger '}'      { $$ = b.atHole($3); }
  ;
 
 repr:
@@ -71,7 +87,6 @@
  |      LiteralInteger
  |      LiteralFloat64
  |      LiteralString
- |      LiteralTwine
  ;
 
 %%
@@ -139,7 +154,6 @@
     } catch (IOException ex) {
         yyerror("io: " + ex);
     }
-    yytext = token.getText();
     yylval = token;
     return token.getType();
 }