[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 < and the colon.
+ * The identifier between the < 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 <=> 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>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 <=> 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.
*/
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>
+ * (<, <=, <=>, >=, >) 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 >= 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.
+ * (<, <=, <=>, >=, >) 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) <=> 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 <=>.
+ * <=> (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 <=>.
* <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) <=> 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 <=> 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); }
;
%%