[e-cvs] cvs commit: e/src/jsrc/org/quasiliteral/term Term.java TermBuilder.java TermLexer.java TermParser.java term.y Functor.java
markm@eros.cs.jhu.edu
markm@eros.cs.jhu.edu
Thu, 6 Dec 2001 01:25:10 -0500
markm 01/12/06 01:25:10
Modified: src/jsrc/org/capml/dom Element.java Node.java Text.java
src/jsrc/org/erights/e/elang/syntax EBuilder.java
ELexer.java EParser.java
src/jsrc/org/erights/e/elib/prim E.java
src/jsrc/org/erights/e/elib/tables FlexMap.java
src/jsrc/org/quasiliteral/astro ASTBuilder.java Astro.java
AstroBuilder.java AstroLexerSharedInputState.java
AstroSchema.java AstroTag.java AstroToken.java
BaseSchema.java
src/jsrc/org/quasiliteral/syntax BaseLexer.java
src/jsrc/org/quasiliteral/term Term.java TermBuilder.java
TermLexer.java TermParser.java term.y
Added: src/jsrc/org/quasiliteral/astro AstroAST.java AstroArg.java
src/jsrc/org/quasiliteral/quasiterm QuasiBuilder.java
QuasiBuilderAdaptor.java
Removed: src/jsrc/org/quasiliteral/term Functor.java
Log:
It all compiles again. Functors are gone. Long live flat Terms.
Revision Changes Path
1.7 +4 -4 e/src/jsrc/org/capml/dom/Element.java
Index: Element.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/capml/dom/Element.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- Element.java 2001/12/03 03:30:54 1.6
+++ Element.java 2001/12/06 06:25:07 1.7
@@ -23,6 +23,7 @@
import org.erights.e.elib.tables.EmptyTwine;
import org.quasiliteral.astro.AstroBuilder;
import org.quasiliteral.astro.AstroTag;
+import org.quasiliteral.astro.Astro;
import java.io.IOException;
@@ -155,15 +156,14 @@
*
* @return :Node (see {@link AstroBuilder})
*/
- public Object build(AstroBuilder builder) {
+ public Astro build(AstroBuilder builder) {
AstroTag tag = builder.getSchema().getTagForName(myTagName);
- Object func = builder.leafTag(tag.getOptTypeCode(),
- EmptyTwine.THE_ONE);
+ Astro func = builder.leafTag(tag, EmptyTwine.THE_ONE);
Object args = builder.argList();
int len = myChildren.size();
for (int i = 0; i < len; i++) {
Node child = (Node)myChildren.get(i);
- args = builder.argList(args, child.build(builder));
+ args = builder.argList(args, builder.arg(child.build(builder)));
}
return builder.node(func, args);
}
1.9 +2 -1 e/src/jsrc/org/capml/dom/Node.java
Index: Node.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/capml/dom/Node.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- Node.java 2001/12/03 03:30:54 1.8
+++ Node.java 2001/12/06 06:25:07 1.9
@@ -24,6 +24,7 @@
import org.erights.e.elib.tables.Iteratable;
import org.erights.e.elib.tables.Selfless;
import org.quasiliteral.astro.AstroBuilder;
+import org.quasiliteral.astro.Astro;
import java.io.IOException;
@@ -156,6 +157,6 @@
*
* @return :Node (see {@link AstroBuilder})
*/
- public abstract Object build(AstroBuilder builder);
+ public abstract Astro build(AstroBuilder builder);
}
1.7 +2 -1 e/src/jsrc/org/capml/dom/Text.java
Index: Text.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/capml/dom/Text.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- Text.java 2001/12/03 03:30:54 1.6
+++ Text.java 2001/12/06 06:25:07 1.7
@@ -22,6 +22,7 @@
import org.erights.e.elib.tables.ConstList;
import org.erights.e.elib.tables.EmptyTwine;
import org.quasiliteral.astro.AstroBuilder;
+import org.quasiliteral.astro.Astro;
import java.io.IOException;
@@ -155,7 +156,7 @@
*
* @return :Node (see {@link AstroBuilder})
*/
- public Object build(AstroBuilder builder) {
+ public Astro build(AstroBuilder builder) {
return builder.node(builder.leafData(myData, EmptyTwine.THE_ONE),
builder.argList());
}
1.89 +12 -12 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.88
retrieving revision 1.89
diff -u -r1.88 -r1.89
--- EBuilder.java 2001/12/02 18:42:01 1.88
+++ EBuilder.java 2001/12/06 06:25:07 1.89
@@ -262,7 +262,7 @@
String verbName;
if (verb instanceof AstroToken) {
- verbName = (String)((AstroToken)verb).getData();
+ verbName = (String)((AstroToken)verb).getOptTokenData();
} else {
verbName = (String)verb;
}
@@ -636,7 +636,7 @@
*/
/*package*/
Pattern atNoun(Object token) {
- String str = (String)((AstroToken)token).getData();
+ String str = (String)((AstroToken)token).getOptTokenData();
str = hilbert(str);
if ("_".equals(str)) {
return ignore();
@@ -694,7 +694,7 @@
*/
/*package*/
EExpr dollarNoun(Object token) {
- String str = (String)((AstroToken)token).getData();
+ String str = (String)((AstroToken)token).getOptTokenData();
str = hilbert(str);
return noun(str);
}
@@ -1018,7 +1018,7 @@
/*package*/
LiteralExpr literal(Object token) {
AstroToken tokn = (AstroToken)token;
- return new LiteralExpr(tokn.getData());
+ return new LiteralExpr(tokn.getOptTokenData());
}
/**
@@ -1203,7 +1203,7 @@
eScript);
} else if (isLiteralToken(optOName)) {
return object(docComment,
- ((AstroToken)optOName).getData(),
+ ((AstroToken)optOName).getOptTokenData(),
auditors,
eScript);
@@ -1270,7 +1270,7 @@
for (int i = 0; i < qList.length; i++) {
if (isQuasiPart(qList[i])) {
- buf.append(((AstroToken)qList[i]).getData());
+ buf.append(((AstroToken)qList[i]).getOptTokenData());
} else {
EExpr eExpr = (EExpr)qList[i];
@@ -1298,7 +1298,7 @@
/*package*/
QuasiLiteralExpr quasiLiteralExpr(Object litIndex) {
AstroToken lit = (AstroToken)litIndex;
- int index = ((Number)lit.getData()).intValue();
+ int index = ((Number)lit.getOptTokenData()).intValue();
return new QuasiLiteralExpr(index);
}
@@ -1308,7 +1308,7 @@
/*package*/
QuasiLiteralPatt quasiLiteralPatt(Object litIndex) {
AstroToken lit = (AstroToken)litIndex;
- int index = ((Number)lit.getData()).intValue();
+ int index = ((Number)lit.getOptTokenData()).intValue();
return new QuasiLiteralPatt(index);
}
@@ -1329,7 +1329,7 @@
for (int i = 0; i < qList.length; i++) {
if (isQuasiPart(qList[i])) {
- buf.append(((AstroToken)qList[i]).getData());
+ buf.append(((AstroToken)qList[i]).getOptTokenData());
} else if (qList[i] instanceof EExpr) {
EExpr eExpr = (EExpr)qList[i];
@@ -1359,7 +1359,7 @@
/*package*/
QuasiPatternExpr quasiPatternExpr(Object litIndex) {
AstroToken lit = (AstroToken)litIndex;
- int index = ((Number)lit.getData()).intValue();
+ int index = ((Number)lit.getOptTokenData()).intValue();
return new QuasiPatternExpr(index);
}
@@ -1369,7 +1369,7 @@
/*package*/
QuasiPatternPatt quasiPatternPatt(Object litIndex) {
AstroToken lit = (AstroToken)litIndex;
- int index = ((Number)lit.getData()).intValue();
+ int index = ((Number)lit.getOptTokenData()).intValue();
return new QuasiPatternPatt(index);
}
@@ -1845,7 +1845,7 @@
} else if (isLiteralToken(optOName)) {
return oType(docComment,
- ((AstroToken)optOName).getData(),
+ ((AstroToken)optOName).getOptTokenData(),
auditors,
mTypes);
1.72 +34 -33 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.71
retrieving revision 1.72
diff -u -r1.71 -r1.72
--- ELexer.java 2001/12/05 00:46:09 1.71
+++ ELexer.java 2001/12/06 06:25:07 1.72
@@ -28,6 +28,7 @@
import org.quasiliteral.astro.AstroTag;
import org.quasiliteral.astro.AstroBuilder;
import org.quasiliteral.astro.ASTBuilder;
+import org.quasiliteral.astro.Astro;
import org.quasiliteral.syntax.BaseLexer;
import org.quasiliteral.syntax.FileFeeder;
import org.quasiliteral.syntax.LineFeeder;
@@ -99,15 +100,15 @@
/**
* @return :Leaf (see {@link AstroBuilder}
*/
- public Object nextToken() throws IOException, SyntaxException {
- Object result;
+ public Astro nextToken() throws IOException, SyntaxException {
+ Astro result;
try {
result = getNextToken();
} finally {
myOptStartPos = -1;
myOptStartText = null;
}
- if (EParser.isContinuer(myBuilder.getCodeOfLeaf(result))) {
+ if (EParser.isContinuer(result.getOptTagCode())) {
return continuer(result);
} else {
return result;
@@ -117,7 +118,7 @@
/**
* Separated out for use by '>'
*/
- protected Object continuer(Object result) throws IOException {
+ private Astro continuer(Astro result) throws IOException {
if (isWhite(myPos, myLData.length)) {
myContinueFlag = true;
skipLine();
@@ -128,7 +129,7 @@
/**
*
*/
- protected Object getNextToken() throws IOException, SyntaxException {
+ protected Astro getNextToken() throws IOException, SyntaxException {
if (myDelayedNextChar) {
nextChar();
myDelayedNextChar = false;
@@ -150,7 +151,7 @@
{
char c = (char)myChar;
nextChar();
- return leafTag(c, endToken());
+ return leafTag((short)c, endToken());
}
case EOFCHAR:
{
@@ -210,7 +211,7 @@
myIndenter.pop('$', name);
return composite(EParser.DollarIdent, key, name);
}
- return leafTag('$', endToken());
+ return leafTag((short)'$', endToken());
}
case '@':
{
@@ -244,7 +245,7 @@
myIndenter.pop('@', name);
return composite(EParser.AtIdent, key, name);
}
- return leafTag('@', endToken());
+ return leafTag((short)'@', endToken());
}
case '.':
{
@@ -257,7 +258,7 @@
}
return leafTag(EParser.OpThru, endToken());
}
- return leafTag('.', endToken());
+ return leafTag((short)'.', endToken());
}
case '^':
{
@@ -266,7 +267,7 @@
nextChar();
return leafTag(EParser.OpAssXor, endToken());
}
- return leafTag('^', endToken());
+ return leafTag((short)'^', endToken());
}
case '+':
{
@@ -279,7 +280,7 @@
syntaxError("token \"++\" is reserved");
return null; //keep compiler happy
}
- return leafTag('+', endToken());
+ return leafTag((short)'+', endToken());
}
case '-':
{
@@ -295,7 +296,7 @@
syntaxError("token \"--\" is reserved");
return null; //keep compiler happy
}
- return leafTag('-', endToken());
+ return leafTag((short)'-', endToken());
}
case ':':
{
@@ -307,7 +308,7 @@
nextChar();
return leafTag(EParser.Audit, endToken());
}
- return leafTag(':', endToken());
+ return leafTag((short)':', endToken());
}
case '<':
{
@@ -335,12 +336,12 @@
}
return leafTag(EParser.OpAsl, endToken());
} else if (isIdentifierStart((char)myChar)) {
- Object optResult = optUri();
+ Astro optResult = optUri();
if (null != optResult) {
return optResult;
}
}
- return leafTag('<', endToken());
+ return leafTag((short)'<', endToken());
}
case '>':
{
@@ -357,7 +358,7 @@
return leafTag(EParser.OpAsr, endToken());
}
Twine closer = endToken();
- Object result = leafTag('>', closer);
+ Astro result = leafTag((short)'>', closer);
if (myIndenter.getCloser() == '>') {
myIndenter.pop('>', closer);
return result;
@@ -388,7 +389,7 @@
syntaxError("'/*..*/' comments are reserved. " +
"Use '#' or '//' on each line instead");
}
- return leafTag('*', endToken());
+ return leafTag((short)'*', endToken());
}
case '/':
{
@@ -405,7 +406,7 @@
syntaxError("'/*..*/' comments are reserved. " +
"Use '#' or '//' on each line instead");
}
- return leafTag('/', endToken());
+ return leafTag((short)'/', endToken());
}
case '#':
{
@@ -427,8 +428,8 @@
myContinueFlag = true;
skipLine();
stopToken();
- Object result = getNextToken();
- if (myBuilder.getCodeOfLeaf(result) ==
+ Astro result = getNextToken();
+ if (result.getOptTagCode() ==
EParser.EOFTOK) {
needMore("continued line");
return null; //make compiler happy
@@ -455,7 +456,7 @@
nextChar();
return leafTag(EParser.OpAssRemdr, endToken());
}
- return leafTag('%', endToken());
+ return leafTag((short)'%', endToken());
}
case '!':
{
@@ -467,7 +468,7 @@
nextChar();
return leafTag(EParser.MisMatch, endToken());
}
- return leafTag('!', endToken());
+ return leafTag((short)'!', endToken());
}
case '=':
{
@@ -499,7 +500,7 @@
nextChar();
return leafTag(EParser.OpButNot, endToken());
}
- return leafTag('&', endToken());
+ return leafTag((short)'&', endToken());
}
case '|':
{
@@ -511,7 +512,7 @@
nextChar();
return leafTag(EParser.OpAssOr, endToken());
}
- return leafTag('|', endToken());
+ return leafTag((short)'|', endToken());
}
case '\'':
{
@@ -580,20 +581,20 @@
* Note that E keywords are case insensitive, so 'name' is first
* toLowerCase()d.
*/
- private int optKeywordType(String name) {
+ private short optKeywordType(String name) {
name = name.toLowerCase();
AstroTag optTag = myBuilder.getSchema().getOptTagForName(name);
if (null == optTag) {
return -1;
} else {
- return optTag.getOptTypeCode();
+ return optTag.getOptTagCode();
}
}
/**
* Called with myChar as the first character of the identifier.
*/
- protected Object identifier() throws IOException, SyntaxException {
+ protected Astro identifier() throws IOException, SyntaxException {
do {
nextChar();
} while (myChar != EOFCHAR && isIdentifierPart((char)myChar));
@@ -614,7 +615,7 @@
}
}
Twine source = endToken();
- int ttype = optKeywordType(source.bare());
+ short ttype = optKeywordType(source.bare());
if (-1 == ttype) {
return composite(EParser.ID, source.bare(), source);
} else {
@@ -628,7 +629,7 @@
* source, we need four ttypes rather than the current two: QuasiOpen
* and QuasiClose.
*/
- private Object quasiPart() throws IOException, SyntaxException {
+ private Astro quasiPart() throws IOException, SyntaxException {
StringBuffer buf = new StringBuffer();
while (true) {
while (QUASI_ENDER.indexOf(myChar) == -1) {
@@ -696,7 +697,7 @@
* is not immediately followed by a ":", return null and cause no side
* effects -- in particular, do not effect the current position.
*/
- private Object optUri() throws IOException, SyntaxException {
+ private Astro optUri() throws IOException, SyntaxException {
int len = myLData.length;
int pos = myPos + 1;
while (pos < len && isIdentifierPart(myLData[pos])) {
@@ -763,17 +764,17 @@
ELexer lex = new ELexer(lr, false, false);
while (true) {
try {
- Object t;
+ Astro t;
do {
t = lex.nextToken();
//XXX should print t as a Functor.
stdout.println(t);
- if (lex.getCodeOfLeaf(t) == EParser.EOL) {
+ if (t.getOptTagCode() == EParser.EOL) {
stdout.print("stack: ",
lex.myIndenter.toString(),
"\n");
}
- } while (lex.getCodeOfLeaf(t) != EParser.EOFTOK);
+ } while (t.getOptTagCode() != EParser.EOFTOK);
return;
} catch (SyntaxException sex) {
TextWriter err = new TextWriter(PrintStreamWriter.err(),
1.109 +8 -8 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.108
retrieving revision 1.109
diff -u -r1.108 -r1.109
--- EParser.java 2001/12/05 00:46:09 1.108
+++ EParser.java 2001/12/06 06:25:07 1.109
@@ -1146,7 +1146,7 @@
static public final StaticMaker EParserMaker =
StaticMaker.make(EParser.class);
-/**
+/**
* caches previous simple parses (as is used for quasi-parsing)
*/
static private IdentityCacheTable OurCache =
@@ -1155,7 +1155,7 @@
/**
*
*/
-static private final ConstMap DefaultProps =
+static private final ConstMap DefaultProps =
ConstMap.fromProperties(System.getProperties());
@@ -1163,7 +1163,7 @@
/** contains all the tokens after yylval */
private ELexer myLexer;
-/**
+/**
* Do we escape after parsing only one expression, or do we parse the
* entire input?
*/
@@ -1265,7 +1265,7 @@
/**
* If the input is empty, returns the null expression e`null`, rather
- * than null.
+ * than null.
*/
public ENode parse() {
ENode result = optParse();
@@ -1605,7 +1605,7 @@
/**
* These are the tokens that may appear at the end of a line, in which
* case the next line is a (to be indented) continuation of the
- * expression.
+ * expression.
* <p>
* Note that > isn't on the list because of its role in closing a
* calculated URI expression.
@@ -1703,7 +1703,7 @@
//###############################################################
// method: yyparse : parse input and execute indicated items
//###############################################################
-int yyparse()
+int yyparse()
{
int yyn; //next next thing to do
int yym; //
@@ -1719,7 +1719,7 @@
while (true) //until parsing is done, either correctly, or w/error
{
doaction=true;
- if (yydebug) debug("loop");
+ if (yydebug) debug("loop");
//#### NEXT ACTION (from reduction table)
for (yyn=yydefred[yystate];yyn==0;yyn=yydefred[yystate])
{
@@ -2660,7 +2660,7 @@
break;
case 260:
//#line 977 "e.y"
-{ yyval = ((AstroToken)val_peek(0)).getData(); }
+{ yyval = ((AstroToken)val_peek(0)).getOptTokenData(); }
break;
case 261:
//#line 978 "e.y"
1.63 +19 -0 e/src/jsrc/org/erights/e/elib/prim/E.java
Index: E.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/prim/E.java,v
retrieving revision 1.62
retrieving revision 1.63
diff -u -r1.62 -r1.63
--- E.java 2001/12/02 06:01:45 1.62
+++ E.java 2001/12/06 06:25:08 1.63
@@ -589,6 +589,7 @@
if (cond) {
return;
}
+ //****** This is a good place to breakpoint *******
Thunk optThunk = null;
Ejector ej = new Ejector();
try {
@@ -642,5 +643,23 @@
require(false, E.call(E.call(prob0, "add", prob1),
"add",
prob2));
+ }
+
+ /**
+ * If cond isn't true, then 'require(false, prob0 + prob1 + prob2)'
+ */
+ static public void require(boolean cond,
+ Object prob0,
+ Object prob1,
+ Object prob2,
+ Object prob3) {
+ if (cond) {
+ return;
+ }
+ require(false, E.call(E.call(E.call(prob0, "add", prob1),
+ "add",
+ prob2),
+ "add",
+ prob3));
}
}
1.30 +12 -4 e/src/jsrc/org/erights/e/elib/tables/FlexMap.java
Index: FlexMap.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/tables/FlexMap.java,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -r1.29 -r1.30
--- FlexMap.java 2001/12/02 06:01:47 1.29
+++ FlexMap.java 2001/12/06 06:25:08 1.30
@@ -224,18 +224,26 @@
}
/**
- *
+ * @see #interning(Class, int)
*/
static public FlexMap interning(Class valType) {
- //XXX should use an interning column
return new FlexMapImpl(String.class, valType);
}
/**
- *
+ * The resulting table should optimize for the assumption that keys are
+ * typically interned, but should work regardless.
+ * <p>
+ * A good strategy would be to use an IdentityKeyColumn internally, and
+ * first try looking up the presented key by identity. If this fails,
+ * intern the key and try again. Only interned keys would be stored.
+ * XXX We currently don't do any such optimization.
+ * <p>
+ * Were we to do this optimization, the interned keys may not ever be
+ * garbage collected. One would hope that Java's interning table were
+ * weak, but no where does it state this in the spec.
*/
static public FlexMap interning(Class valType, int capacity) {
- //XXX should use an interning column
return new FlexMapImpl(String.class, valType, capacity);
}
1.2 +49 -44 e/src/jsrc/org/quasiliteral/astro/ASTBuilder.java
Index: ASTBuilder.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/astro/ASTBuilder.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ASTBuilder.java 2001/12/05 00:46:11 1.1
+++ ASTBuilder.java 2001/12/06 06:25:08 1.2
@@ -7,13 +7,13 @@
/**
* The default implementation (and default superclass) for implementing
- * AstroBuilder simply, for building Astro-trees with AstroToken leaves.
+ * AstroBuilder simply, for building AstroAST-trees with AstroToken leaves.
* <p>
* The type parameterization of AstroBuilder is: <pre>
* Leaf is AstroToken
- * Node is Astro
- * Arg is Astro
- * Args is null (for empty list) or Astro (for it and its siblings).
+ * Node is AstroAST
+ * Arg is AstroAST
+ * Args is null (for empty list) or AstroAST (for it and its siblings).
* </pre>
*
* @author <a href="mailto:markm@caplet.com">Mark Miller</a>
@@ -36,7 +36,7 @@
*
*/
public String toString() {
- return "<building ASTs for " + mySchema.getName() + ">";
+ return "<building ASTs for " + mySchema.getSchemaName() + ">";
}
/**
@@ -49,8 +49,8 @@
/**
* @return :AstroToken
*/
- public Object leafTag(int typeCode, Twine source) {
- return new AstroToken(mySchema.getTagForCode(typeCode), null, source);
+ public Astro leafTag(AstroTag tag, Twine source) {
+ return new AstroToken(tag, null, source);
}
/**
@@ -58,8 +58,10 @@
* @param source
* @return :AstroToken
*/
- public Object leafData(Object data, Twine source) {
- return new AstroToken(mySchema.getLiteralDataTag(data), data, source);
+ public Astro leafData(Object data, Twine source) {
+ return new AstroToken(mySchema.getTypeTag(data.getClass()),
+ data,
+ source);
}
/**
@@ -68,38 +70,31 @@
* @param data Nust not be null
* @return :AstroToken
*/
- public Object composite(int typeCode, Object data, Twine source) {
- return new AstroToken(mySchema.getTagForCode(typeCode), data, source);
+ public Astro composite(AstroTag tag, Object data, Twine source) {
+ return new AstroToken(tag, data, source);
}
/**
- * @param leaf :AstroToken
+ * @param func :(AstroToken | AstroAST)
+ * @return :AstroAST
*/
- public int getCodeOfLeaf(Object leaf) {
- return ((AstroToken)leaf).getType();
- }
-
- /**
- * @param func :(AstroToken | Astro)
- * @return :Astro
- */
- public Object node(Object func) {
- if (func instanceof Astro) {
- return func;
+ public Astro node(Astro leaf) {
+ if (leaf instanceof AstroAST) {
+ return leaf;
}
- return new Astro((AstroToken)func);
+ return new AstroAST((AstroToken)leaf);
}
/**
* @param func :AstroToken
- * @param args :(Astro | null)
- * @return :Astro
+ * @param args :(AstroAST | null)
+ * @return :AstroAST
*/
- public Object node(Object func, Object args) {
- AstroToken funcToken = (AstroToken)func;
- Astro optArgs = (Astro)args;
- Astro result = new Astro(funcToken);
- for (; null != optArgs; optArgs = (Astro)optArgs.getNextSibling()) {
+ public Astro node(Astro leaf, Object args) {
+ AstroToken funcToken = (AstroToken)leaf;
+ AstroAST optArgs = (AstroAST)args;
+ AstroAST result = new AstroAST(funcToken);
+ for (; null != optArgs; optArgs = (AstroAST)optArgs.getNextSibling()) {
result.addChild(optArgs);
}
return result;
@@ -115,11 +110,11 @@
/**
* Returns 'first' after severing its nest sibling pointer
*
- * @param first :Astro
- * @return :Astro
+ * @param first :AstroAST
+ * @return :AstroAST
*/
- public Object argList(Object first) {
- Astro result = (Astro)first;
+ public Object argList(AstroArg first) {
+ AstroAST result = (AstroAST)first;
result.setNextSibling(null);
return result;
}
@@ -128,25 +123,35 @@
* Modifies the last sibling in 'list' to be 'next', which is modified to
* not have any further siblings.
*
- * @param list :(Astro | null)
- * @param next :Astro
- * @return :Astro
- */
- public Object argList(Object list, Object next) {
- Astro optList = (Astro)list;
- Astro nextNode = (Astro)next;
+ * @param list :(AstroAST | null)
+ * @param next :AstroAST
+ * @return :AstroAST
+ */
+ public Object argList(Object list, AstroArg next) {
+ AstroAST optList = (AstroAST)list;
+ AstroAST nextNode = (AstroAST)next;
nextNode.setNextSibling(null);
if (null == optList) {
return next;
}
- Astro sib = optList;
+ AstroAST sib = optList;
while (true) {
- Astro optNextSib = (Astro)sib.getNextSibling();
+ AstroAST optNextSib = (AstroAST)sib.getNextSibling();
if (null == optNextSib) {
sib.setNextSibling(nextNode);
return optList;
}
sib = optNextSib;
}
+ }
+
+ /**
+ * Just an identity function on AstroASTs
+ *
+ * @param node :AstroAST
+ * @return :AstroAST
+ */
+ public AstroArg arg(Astro node) {
+ return (AstroAST)node;
}
}
1.7 +82 -216 e/src/jsrc/org/quasiliteral/astro/Astro.java
Index: Astro.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/astro/Astro.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- Astro.java 2001/12/05 00:46:11 1.6
+++ Astro.java 2001/12/06 06:25:08 1.7
@@ -1,231 +1,97 @@
package org.quasiliteral.astro;
-import antlr.BaseAST;
-import antlr.CommonToken;
-import antlr.Token;
-import antlr.collections.AST;
+import org.erights.e.elib.tables.ConstList;
import org.erights.e.elib.tables.Twine;
+//This file is hereby placed in the public domain
+
/**
- * AST node implementation which stores tokens explicitly.
+ * The nodes of the kind of tree made by an {@link AstroBuilder}.
* <p>
- * This is handy if you'd rather derive information from tokens on an
- * as-needed basis instead of snarfing data from a token as an AST
- * is being built.
+ * A leaf node is simply an Astro with no arguments.
* <p>
- * In keeping with the nature of Antlr ASTs, Astros are mutable. The
- * corresponding immutable, Persistent, & PassByCopy type is the
- * {@link org.quasiliteral.term.Term}.
+ * A particular AstroBuilder will make Astros of some particular kind. For
+ * example, an {@link ASTBuilder} makes Antlr ASTs, a TermBuilder builds a
+ * Term tree, and a QuasiTermBuilder builds a QuasiTerm tree.
*
- * @author <a href="mailto:markm@caplet.com">Mark S Miller</a>
- * @author Based on Danfuzz Bornstein's TokenAST
+ * @author <a href="mailto:markm@caplet.com">Mark Miller</a>
*/
-public class Astro extends BaseAST {
+public interface Astro {
+
+ /**
+ * Builds an Astro tree like this one, but the kind of Astro that's made
+ * by this builder.
+ * <p>
+ * Pattern-wise, the builder functions here as both as a factory, and
+ * sort-of as a visitor. It's not quite a visitor, in that it only sees
+ * the tree in bottom-up order.
+ */
+ Astro build(AstroBuilder builder);
+
+ /**
+ * Represents the token-type of the functor.
+ */
+ AstroTag getTag();
+
+ /**
+ * Equivalent to 'getTag().getOptTypeCode()'
+ */
+ short getOptTagCode();
+
+ /**
+ * If this Astro represents a literal-data token, then this is
+ * the data, and getTag() must represent the canonical corresponding
+ * token-type for this kind of data in this schema.
+ * <p>
+ * If the getTag() has no schema, then its getTagName() must be the
+ * corresponding token-type name.
+ */
+ Object getOptData();
/**
- *
+ * Equivalent to either 'getOptData()' or, if that's null, to
+ * 'getArgs()[0] getOptData()'.
+ * <p>
+ * This exists as an optimization for composite Tokens, which act like
+ * 1-argument Astros, where the 1-argument is a data argument. This
+ * operation allows us to avoid creating a singleton argument list just
+ * to access this data.
+ */
+ Object getOptTokenData();
+
+ /**
+ * What source text was originally lexed or parsed to produce this token?
+ * <p>
+ * The source-span annotations on the text are normally the significant
+ * part, not the text itself. Absence of source information is indicated
+ * with an empty string, rather than null.
+ */
+ Twine getSource();
+
+ /**
+ * @return :(ConstList of(AstroArg)); In most domains, AstroArg is the
+ * same as Astro, so this usually returns (ConstList of(Astro)).
*/
- private Token myOptToken;
+ ConstList getArgs();
/**
- * Construct an instance which (at least initially) is not associated
- * with a token.
- */
- public Astro() {
- myOptToken = null;
- }
-
- /**
- * Construct an instance which is associated with the given token.
- *
- * @param optToken The (optional) token to associate this instance with
- */
- public Astro(Token optToken) {
- initialize(optToken);
- }
-
- /**
- *
- */
- public String toString() {
- return "" + myOptToken;
- }
-
- /**
- * Builds an equivalent of this AST using the building methods of
- * 'builder'.
- * <p>
- * Pattern-wise, the schema functions here as both a visitor and as a
- * factory.
- *
- * @return :Node
- */
- public Object build(AstroBuilder builder) {
- Object func = AstroToken.build(myOptToken, builder);
- Astro optSub = (Astro)getFirstChild();
- if (null == optSub) {
- //This case is broken out in order to allow 'func' to be a Node
- //rather than a Leaf. This would happen is myOptToken is
- //a composite.
- return builder.node(func);
- }
- Object args = builder.argList();
- for (; null != optSub; optSub = (Astro)optSub.getNextSibling()) {
- args = builder.argList(args, optSub.build(builder));
- }
- return builder.node(func, args);
- }
-
- /**
- * Since not all {@link AST}s are Astros, this static method
- * provides the equivalent of the build/1 instance method for ASTs in
- * general.
- * <p>
- * In the understanding of non-Astro ASTs used here, their functor is
- * only according to the AST's type code, for the tag, and the AST's text,
- * for the source.
- * <p>
- * XXX This should probably be made into a sugar-instance-method of AST.
- */
- static public Object build(AST self, AstroBuilder builder) {
- if (self instanceof Astro) {
- return ((Astro)self).build(builder);
- } else {
- Object func = builder.leafTag(self.getType(),
- Twine.fromString(self.getText()));
- AST optSub = self.getFirstChild();
- if (null == optSub) {
- //See comment in build/1 above
- return builder.node(func);
- }
- Object args = builder.argList();
- for (; null != optSub; optSub = optSub.getNextSibling()) {
-
- args = builder.argList(args, build(optSub, builder));
- }
- return builder.node(func, args);
- }
- }
-
- /**
- * Get the token text for this instance. If there is no token associated
- * with this instance, then this returns the empty string
- * (<code>""</code>), not <code>null</code>.
- *
- * @return non-null; the token text
- */
- public String getText() {
- if (myOptToken == null) {
- return "";
- } else {
- return myOptToken.getText();
- }
- }
-
- /**
- * Get the token type for this instance. If there is no token associated
- * with this instance, then this returns {@link Token#INVALID_TYPE}.
- *
- * @return the token type
- */
- public int getType() {
- if (myOptToken == null) {
- return Token.INVALID_TYPE;
- } else {
- return myOptToken.getType();
- }
- }
-
- /**
- * Get the token associated with this instance. If there is no token
- * associated with this instance, then this returns <code>null</code>.
- *
- * @return The token associated with this instance, or <code>mull</code>
- * if there is no associated token
- */
- public Token getOptToken() {
- return myOptToken;
- }
-
- /**
- * Set the token associated with this instance.
- *
- * @param optToken The new token (or null) to associate with this
- * instance.
- */
- public void setOptToken(Token optToken) {
- myOptToken = optToken;
- }
-
- /**
- * Initialize this instance with the given token.
- *
- * @param optToken the token to associate with this instance
- */
- public void initialize(Token optToken) {
- myOptToken = optToken;
- }
-
- /**
- * Initialize this instance with the given token type and text.
- * This will construct a new {@link CommonToken} with the given
- * parameters and associate this instance with it.
- *
- * @param type the token type
- * @param optText The token text, or null
- */
- public void initialize(int type, String optText) {
- initialize(new CommonToken(type, optText));
- }
-
- /**
- * Initialize this instance based on the given {@link AST}.
- * If the given <code>AST</code> is in fact an instance of
- * <code>Astro</code>, then this instance will be initialized
- * to point at the same token as the given one. If not, then this
- * instance will be initialized with the same token type and text
- * as the given one.
- *
- * @param ast non-null; the <code>AST</code> to base this instance on
- */
- public void initialize(AST ast) {
- if (ast instanceof Astro) {
- initialize(((Astro)ast).getOptToken());
- } else {
- initialize(ast.getType(), ast.getText());
- }
- }
-
- /**
- * Set the token text for this node. If this instance is already
- * associated with a token, then that token is destructively modified
- * by this operation. If not, then a new token is constructed with
- * the type {@link Token#INVALID_TYPE} and the given text.
- *
- * @param text the new token text
- */
- public void setText(String text) {
- if (myOptToken == null) {
- initialize(Token.INVALID_TYPE, text);
- } else {
- myOptToken.setText(text);
- }
- }
-
- /**
- * Set the token type for this node. If this instance is already
- * associated with a token, then that token is destructively modified
- * by this operation. If not, then a new token is constructed with
- * the given type and an empty (<code>""</code>, not <code>null</code>)
- * text string.
- *
- * @param type the new token type
- */
- public void setType(int type) {
- if (myOptToken == null) {
- initialize(type, "");
- } else {
- myOptToken.setType(type);
- }
- }
+ * An Astro just like this one, but without any arguments, which is
+ * therefore a leaf (and so may be a Token).
+ * <p>
+ * Even in the mutable AST domain, if this Astro has arguments,
+ * 'withoutArgs()' makes a copy rather than modifying this Astro in place.
+ */
+ Astro withoutArgs();
+
+ /**
+ * Given that this Astro is a leaf (has no arguments), this returns an
+ * Astro just like it but with these arguments.
+ * <p>
+ * Even in the mutable AST domain, if 'args' is non-empty,
+ * 'withArgs(..)' makes a copy rather than modifying this Astro in place.
+ * <p>
+ * If this Astro is not a leaf, this throws an exception even if 'args' is
+ * empty.
+ */
+ Astro withArgs(ConstList args);
}
1.2 +49 -66 e/src/jsrc/org/quasiliteral/astro/AstroBuilder.java
Index: AstroBuilder.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/astro/AstroBuilder.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- AstroBuilder.java 2001/12/05 00:46:11 1.1
+++ AstroBuilder.java 2001/12/06 06:25:08 1.2
@@ -7,24 +7,14 @@
//This file is hereby placed in the public domain
/**
- * Used to describe an Antlr grammar, and to build a tree that could represent
- * the results of parsing such a grammar.
+ * Used to build an Astro tree -- a tree that could represent the results of
+ * parsing a string according to a grammar.
* <p>
- * Several arguments and return types are 'Object' below because the actual
- * types are to be determined by the implementors of AstroBuilder. However,
- * these choices need to be consistent. We express the required consistency
- * using pretend parameterized types encoded in the javadoc comments.
- * Concrete subclasses of AstroBuilder should say what concrete types they use
- * for these parameterized types.
- * <p>
- * The pretend parameterized types are: <pre>
- * Leaf -- Leaves of the tree, representing tokens of the grammar.
- * Node -- Lnternal nodes of the tree, looks like application of a Leaf
- * as an functor to Args.
- * Arg -- An individual argument in a list of arguments. Typically the
- * same as Node, but not always. See QuasiTermBuilder.
- * Args -- Represents a list of Arg.
- * </pre>
+ * Several arguments or return values below are declared 'Object', but
+ * pseudo-declared ":Args" in the javadoc comments. For these, the concrete
+ * type represents a list of {@link AstroArg}s, but the particular type used
+ * to represent the list depends on the type of builder, and should be
+ * documented in that builder's class comment.
*
* @author <a href="mailto:markm@caplet.com">Mark Miller</a>
*/
@@ -36,71 +26,57 @@
AstroSchema getSchema();
/**
- * Makes a Leaf (eg, a Token or Functor) not representing literal data,
- * but just a type code
- *
- * @return :Leaf
+ * Makes a leaf (eg, a Token) not representing literal data, but just a
+ * token type, as identified by 'tag'.
+ * <p>
+ * The tag of the returned Astro should be according to the schema of this
+ * builder, even though the argument tag may represent a type in a
+ * different schema. In this case, the correspondence is by type name,
+ * rather than type code.
*/
- Object leafTag(int typeCode, Twine source);
+ Astro leafTag(AstroTag tag, Twine source);
/**
- * Makes a leaf (eg, a Token or Functor) representing literal data
- *
- * @return :Leaf
+ * Makes a leaf (eg, a Token) representing literal data.
*/
- Object leafData(Object data, Twine source);
+ Astro leafData(Object data, Twine source);
/**
- * Makes a Leaf or Node representing the given type code as parameterized
- * by the given data.
- * <p>
- * Exists to support legacy usage of Antlr Tokens, and in order to allow
- * lexers, which wish to emit composites, to still emit only leaves if
- * allowed by the concrete builder.
+ * Makes an Astro whose tag is according to 'tag', and whose one argument
+ * is a leaf according to 'data'.
* <p>
- * Builders that don't allow composite leaves (like TermBuilder) should
- * instead emit the equivalent of <pre>
+ * Is equivalent to:<pre>
* node(leafTag(typeCode, src),
- * argList(node(leafData(data, src), argList())))
+ * argList(node(leafData(data, src))))
* </pre>
- *
- * @return :(Leaf | Node)
- */
- Object composite(int typeCode, Object data, Twine source);
-
- /**
- * Given a Leaf that could have been produced by this builder, return its
- * type code.
- *
- * @param leaf :Leaf
- * @return The leaf's type code.
+ * Exists to support legacy usage of Antlr Tokens, and in order to allow
+ * lexers, which wish to emit composites, to still emit only Tokens if
+ * allowed by the concrete builder.
*/
- int getCodeOfLeaf(Object leaf);
+ Astro composite(AstroTag tag, Object data, Twine source);
/**
- * Names an internal node (eg, an AST or Term), for which 'func' is the
- * "label" and there are no arguments.
+ * At the Astro-level of semantics, for leaf Astros, this is an identity
+ * function.
* <p>
- * To accomodate composites, which may be Leaves in one representation and
- * Nodes in another, 'node' accepts a 'func' that's a Node, in which case
- * that Node is returned.
- *
- * @param func :(Leaf | Node)
- * @return :Node
+ * However, for kinds of trees for which there are separate types to
+ * represent leaves and internal nodes (eg, Antlr's Tokens vs ASTs), if
+ * 'leaf' is of the leaf-specific type, this will convert to the node
+ * type.
*/
- Object node(Object func);
+ Astro node(Astro leaf);
/**
- * Names an internal node (eg, an AST or Term), for which 'func' is the
- * "label" and 'args' are the arguments.
+ * Returns an internal node (eg, an AST or Term), for which 'leaf' is the
+ * functor and 'args' are the arguments.
* <p>
- * May be destructive of 'args'.
+ * 'leaf' must be a leaf (have no arguments).
+ * <p>
+ * May be destructive of 'leaf' and 'args'.
*
- * @param func :Leaf
* @param args :Args
- * @return :Node
*/
- Object node(Object func, Object args);
+ Astro node(Astro leaf, Object args);
/**
* The empty args list
@@ -116,10 +92,9 @@
* <p>
* Should be equivalent to 'argList(argList(), first)'
*
- * @param first :Arg
* @return :Args
*/
- Object argList(Object first);
+ Object argList(AstroArg first);
/**
* Extend args list with an additional term, like a backwards cons.
@@ -127,8 +102,16 @@
* May be destructive of 'list' and 'next'
*
* @param list :Args
- * @param next :Arg
* @return :Args
+ */
+ Object argList(Object list, AstroArg next);
+
+ /**
+ * Converts an Astro into a corresponding AstroArgs.
+ * <p>
+ * When an Astro and an AstroArg are the same, this is an identity
+ * function. Otherwise, this converts 'node' into an arg
+ * representing the singleton list consisting of just node.
*/
- Object argList(Object list, Object next);
+ AstroArg arg(Astro node);
}
1.5 +1 -1 e/src/jsrc/org/quasiliteral/astro/AstroLexerSharedInputState.java
Index: AstroLexerSharedInputState.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/astro/AstroLexerSharedInputState.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- AstroLexerSharedInputState.java 2001/12/05 00:46:11 1.4
+++ AstroLexerSharedInputState.java 2001/12/06 06:25:08 1.5
@@ -76,7 +76,7 @@
}
/**
- * Annotate an {@link ExtentToken} based on this instance. It sets
+ * Annotate an {@link AstroToken} based on this instance. It sets
* the end position information as well as the file name.
*
* @param token non-null; the token to annotate
1.7 +14 -11 e/src/jsrc/org/quasiliteral/astro/AstroSchema.java
Index: AstroSchema.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/astro/AstroSchema.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- AstroSchema.java 2001/12/05 00:46:11 1.6
+++ AstroSchema.java 2001/12/06 06:25:08 1.7
@@ -7,6 +7,9 @@
/**
* Used to describe an Antlr grammar.
+ * <p>
+ * Each token-type-code in an Antlr grammar corresponds to an
+ * {@link AstroTag}.
*
* @author <a href="mailto:markm@caplet.com">Mark Miller</a>
*/
@@ -16,31 +19,31 @@
* The name of the language this is a Schema for, for diagnostic purposes
* only.
*/
- String getName();
+ String getSchemaName();
/**
* Returns the tag represented by this type code in the grammar described
* by this schema, or null.
*/
- AstroTag getOptTagForCode(int typeCode);
+ AstroTag getOptTagForCode(short tagCode);
/**
* Returns the tag represented by this type code in the grammar described
* by this schema
*/
- AstroTag getTagForCode(int typeCode);
+ AstroTag getTagForCode(short tagCode);
/**
* Returns the tag represented by this type name in the grammar described
* by this schema, or null
*/
- AstroTag getOptTagForName(String typeName);
+ AstroTag getOptTagForName(String tagName);
/**
* Returns the tag represented by this type name in the grammar described
* by this schema
*/
- AstroTag getTagForName(String typeName);
+ AstroTag getTagForName(String tagName);
/**
* Gets the tag for representing character literals.
@@ -71,14 +74,14 @@
AstroTag getLiteralStringTag();
/**
- * Gets the tag for literally representing the provided data, or null if
- * data is the wrong kind.
+ * Gets the tag for literally representing instances of clazz, or
+ * null if clazz is the wrong kind.
*/
- AstroTag getOptDataTag(Object data);
+ AstroTag getOptTypeTag(Class clazz);
/**
- * Gets the tag for literally representing the provided data, or throws
- * if data is the wrong kind.
+ * Gets the tag for literally representing instances of clazz, or
+ * throws if clazz is the wrong kind.
*/
- AstroTag getLiteralDataTag(Object data);
+ AstroTag getTypeTag(Class clazz);
}
1.4 +110 -28 e/src/jsrc/org/quasiliteral/astro/AstroTag.java
Index: AstroTag.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/astro/AstroTag.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- AstroTag.java 2001/12/05 00:46:11 1.3
+++ AstroTag.java 2001/12/06 06:25:08 1.4
@@ -4,70 +4,113 @@
import org.erights.e.elib.serial.PassByConstruction;
import org.erights.e.elib.serial.Persistent;
import org.erights.e.elib.tables.Twine;
+import org.erights.e.elib.prim.E;
+import antlr.Token;
+import java.math.BigInteger;
+
//This file is hereby placed in the public domain
/**
- * Represents both an {@link AstroToken}'s token-type (and enumerated int code
- * specific to a grammar), and a Functor's type=name (the name of that
- * enumerated code in that grammar).
+ * Represents both a grammar's tag-type (corresponds to the enumerated token
+ * type code specific to an Antlr grammar), and a corresponding tag name (the
+ * name of that enumerated code in that grammar).
* <p>
* The notion of "specific to a grammar" is here abstracted into the notion
- * of an {@link AstroSchema}, within which these type-code/type-names are
+ * of an {@link AstroSchema}, within which these tag-codes/tag-names are
* defined, and that provides the means for translating between the two.
+ * <p>
+ * An AstroTag always has a tag-name, but not necessarily a tag-code or a
+ * schema.
* <p>
- * AstroTags are AstroSchemas can be used to describe Antlr grammars that use
- * only ASTs and Tokens as well.
+ * To convert between Astro tag-codes and Antlr type-codes, a type code is a
+ * tag code +1. This also results in the non-tag-code (-1) being converted
+ * to {@link Token#INVALID_TYPE}, which happens to be 0.
*
* @author <a href="mailto:markm@caplet.com">Mark Miller</a>
*/
public class AstroTag implements PassByConstruction, Persistent {
/**
- * The enumerated type code, or Token.INVALID_TYPE.
+ * The type-code for use by Antlr, which is the tag-code +1.
+ * <p>
+ * If the tag-code is -1, the returned type code will be
+ * {@link Token#INVALID_TYPE}
*/
- private final int myOptTypeCode;
+ static public int tagCode2typeCode(short tagCode) {
+ return tagCode +1;
+ }
/**
- * The name of the enumerated type code.
+ *
*/
- private final Twine myTypeName;
+ static public short typeCode2tagCode(int typeCode) {
+ return (short)(typeCode -1);
+ }
/**
- * The schema of which this tag is a member, or null.
+ * @serial The enumerated tag code, or -1.
+ */
+ private final short myOptTagCode;
+
+ /**
+ * @serial The interned name of the enumerated tag code.
+ */
+ private final String myTagName;
+
+ /**
+ * @serial The schema of which this tag is a member, or null.
*/
private final AstroSchema myOptSchema;
/**
+ * @serial If this tag is a normal symbolic tag, this is null. If it's
+ * a tag for a literal data type, this is the canonical class for that
+ * data type -- one of Character.class, BigInteger.class, Double.class,
+ * or Twine.class.
+ */
+ private final Class myOptDataType;
+
+ /**
*
- * @param optTypeCode The enumerated type code, or Token.INVALID_TYPE.
- * @param typeName The name of the enumerated type code.
+ * @param optTagCode The enumerated tag code, or -1.
+ * @param tagName The name of the enumerated type code.
* @param optSchema The schema of which this tag is a member, or null.
+ * @param optDataType Either null, or the kind of data labeled by this
+ * tag.
*/
- public AstroTag(int optTypeCode, Twine typeName, AstroSchema optSchema) {
- myOptTypeCode = optTypeCode;
- myTypeName = typeName;
+ /*package*/ AstroTag(short optTagCode,
+ String tagName,
+ AstroSchema optSchema,
+ Class optDataType) {
+ myOptTagCode = optTagCode;
+ myTagName = tagName.intern();
myOptSchema = optSchema;
+ myOptDataType = optDataType;
+ if (null != optDataType) {
+ E.require(null != optSchema,
+ "internal: Can't have a data type without a schema");
+ }
}
public String toString() {
- return "<" + myTypeName +
+ return "<" + myTagName +
(null == myOptSchema ? "" : (":" + myOptSchema)) +
">";
}
/**
- * The enumerated type code, or Token.INVALID_TYPE.
+ * The enumerated tag code, or -1.
*/
- public int getOptTypeCode() {
- return myOptTypeCode;
+ public short getOptTagCode() {
+ return myOptTagCode;
}
/**
- * The name of the enumerated type code.
+ * The interned name of the enumerated tag code.
*/
- public Twine getTypeName() {
- return myTypeName;
+ public String getTagName() {
+ return myTagName;
}
/**
@@ -78,17 +121,56 @@
}
/**
- *
+ * Indicates the type of data literally represented by this tag.
+ * <p>
+ * If this tag is a normal symbolic tag, this is null. If it's
+ * a tag for a literal data type, this is the canonical class for that
+ * data type -- one of Character.class, BigInteger.class, Double.class,
+ * or Twine.class.
+ */
+ public Class getOptDataType() {
+ return myOptDataType;
+ }
+
+ /**
+ * Is this the tag implied by the type of optData?
+ * <p>
+ * If optData is null, the answer is true.
+ */
+ public boolean isTagForData(Object optData) {
+ if (null == optData) {
+ return true;
+ }
+ if (null == myOptDataType) {
+ return false;
+ }
+ //Doesn't matter what schema we use, since we're just canonicalizing
+ //the data type.
+ AstroTag optDataTag =
+ BaseSchema.MINIMAL.getOptTypeTag(optData.getClass());
+ if (null == optDataTag) {
+ return false;
+ }
+ return myOptDataType == optDataTag.getOptDataType();
+ }
+
+ /**
+ * if they have the same schema, or if either of both has no,
+ * schema, then they are compared based on their typeNames.
+ * <p>
+ * Otherwise, they are incomparable.
*/
public double compareTo(AstroTag other) {
if (Ref.same(myOptSchema, other.myOptSchema) ||
null == myOptSchema ||
null == other.myOptSchema) {
- //if they have the same schema, or if either of both has no,
- //schema, then they are compared based on their typeNames.
- return myTypeName.compareTo(other.myTypeName);
+ if (myTagName == other.myTagName) {
+ //since we know they're interned, it's worth doing this
+ //check before the general compareTo.
+ return 0.0;
+ }
+ return (double)myTagName.compareTo(other.myTagName);
} else {
- //otherwise, they are incomparable.
return Double.NaN;
}
}
1.10 +62 -39 e/src/jsrc/org/quasiliteral/astro/AstroToken.java
Index: AstroToken.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/astro/AstroToken.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- AstroToken.java 2001/12/03 03:30:55 1.9
+++ AstroToken.java 2001/12/06 06:25:08 1.10
@@ -4,6 +4,8 @@
import org.erights.e.elib.base.SourceSpan;
import org.erights.e.elib.prim.E;
import org.erights.e.elib.tables.Twine;
+import org.erights.e.elib.tables.EmptyTwine;
+import org.erights.e.elib.tables.ConstList;
/**
* A Kind of Antlr {@link Token} that preserves all the information in a
@@ -16,7 +18,7 @@
* @author <a href="mailto:markm@caplet.com">Mark S Miller</a>
* @author Based on ValueExtentToken by Danfuzz Bornstein
*/
-public class AstroToken extends Token {
+public class AstroToken extends Token implements Astro, AstroArg {
/**
*
@@ -38,8 +40,8 @@
/**
* Construct an instance.
* <p>
- * The instance will be of type {@link #INVALID_TYPE}, and have empty
- * (<code>""</code>, not <code>null</code>) source twine.
+ * The instance will have the tag code -1, and have empty (<code>""</code>,
+ * not <code>null</code>) source twine.
*/
public AstroToken() {
super();
@@ -58,39 +60,29 @@
* provide no info, use "" rather than null.
*/
public AstroToken(AstroTag tag, Object optData, Twine source) {
- super(tag.getOptTypeCode());
+ super(AstroTag.tagCode2typeCode(tag.getOptTagCode()));
myOptTag = tag;
+ //XXX should promote optData to its canonical type if necessary
myOptData = optData;
setSource(source);
+ Class type = myOptTag.getOptDataType();
+ if (null != myOptData && null != type) {
+ E.require(myOptData.getClass() == type,
+ "Literal tag mismatch: ", tag, " vs ", optData.getClass());
+ }
}
/**
- * Builds an equivalent of this token using the building methods of
- * 'builder'.
- * <p>
- * Pattern-wise, the builder functions here as both a visitor and as a
- * factory.
*
- * @return :(Leaf | Node), because a composite token will build using
- * {@link AstroBuilder#composite(int, Object, Twine)}
*/
- public Object build(AstroBuilder builder) {
- int code;
+ public Astro build(AstroBuilder builder) {
AstroSchema schema = builder.getSchema();
- if (null == myOptTag) {
- code = getType();
- } else {
- //this case should be sped up to avoid the hash lookup in the
- //typical case.
- String name = myOptTag.getTypeName().bare();
- code = schema.getTagForName(name).getOptTypeCode();
- }
if (null == myOptData) {
- return builder.leafTag(code, myOptSource);
- } else if (schema.getOptDataTag(myOptData).getOptTypeCode() == code) {
+ return builder.leafTag(getTag(), myOptSource);
+ } else if (getTag().isTagForData(myOptData)) {
return builder.leafData(myOptData, myOptSource);
} else {
- return builder.composite(code, myOptData, myOptSource);
+ return builder.composite(getTag(), myOptData, myOptSource);
}
}
@@ -106,7 +98,7 @@
*
* @return :(Leaf | Node)
*/
- static public Object build(Token self, AstroBuilder builder) {
+ static public Astro build(Token self, AstroBuilder builder) {
if (self instanceof AstroToken) {
return ((AstroToken)self).build(builder);
} else {
@@ -116,7 +108,9 @@
self.getColumn(),
self.getLine(),
self.getColumn());
- return builder.leafTag(self.getType(),
+ short tagCode = AstroTag.typeCode2tagCode(self.getType());
+ AstroTag tag = builder.getSchema().getTagForCode(tagCode);
+ return builder.leafTag(tag,
Twine.fromString(self.getText(), span));
}
}
@@ -124,18 +118,12 @@
/**
*
*/
- public AstroTag getOptTag() {
+ public AstroTag getTag() {
+ E.require(null != myOptTag, "Tag must first be set: ", this);
return myOptTag;
}
/**
- *
- */
- public AstroSchema getOptSchema() {
- return myOptTag.getOptSchema();
- }
-
- /**
* For when the type-code is already set by generic Antlr code, while
* Astro-specific knowledge of the schema comes along later.
* <p>
@@ -145,7 +133,7 @@
public void setSchema(AstroSchema schema) {
E.require(null == myOptTag, "Tag already set");
E.require(INVALID_TYPE != getType(), "Type-code not yet set");
- myOptTag = schema.getTagForCode(getType());
+ myOptTag = schema.getTagForCode(getOptTagCode());
}
/**
@@ -156,18 +144,28 @@
super.setType(t);
}
+ public short getOptTagCode() {
+ return AstroTag.typeCode2tagCode(getType());
+ }
+
/**
* If this token represents literal data, return that data,
* else null.
*/
public Object getOptData() {
- return myOptData;
+ if (getTag().isTagForData(myOptData)) {
+ return myOptData;
+ } else {
+ //the data will be in args[0]. Or it can be directly accessed
+ //with getArgData()
+ return null;
+ }
}
/**
*
*/
- public Object getData() {
+ public Object getOptTokenData() {
E.require(null != myOptData, "No data");
return myOptData;
}
@@ -175,8 +173,12 @@
/**
*
*/
- public Twine getOptSource() {
- return myOptSource;
+ public Twine getSource() {
+ if (null == myOptSource) {
+ return EmptyTwine.THE_ONE;
+ } else {
+ return myOptSource;
+ }
}
/**
@@ -257,5 +259,26 @@
public void setText(String s) {
E.require(null == myOptSource, "Source already set");
setSource(Twine.fromString(s));
+ }
+
+ /**
+ *
+ */
+ public ConstList getArgs() {
+ throw new RuntimeException("XXX not yet implemented");
+ }
+
+ /**
+ *
+ */
+ public Astro withoutArgs() {
+ throw new RuntimeException("XXX not yet implemented");
+ }
+
+ /**
+ *
+ */
+ public Astro withArgs(ConstList args) {
+ throw new RuntimeException("XXX not yet implemented");
}
}
1.7 +143 -92 e/src/jsrc/org/quasiliteral/astro/BaseSchema.java
Index: BaseSchema.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/astro/BaseSchema.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- BaseSchema.java 2001/12/05 00:46:11 1.6
+++ BaseSchema.java 2001/12/06 06:25:08 1.7
@@ -13,202 +13,253 @@
/**
* The default implementation (and default superclass) for implementing
- * AstroSchema simply, starting with an array of type names.
+ * AstroSchema simply, starting with an array of tag names.
*
* @author <a href="mailto:markm@caplet.com">Mark Miller</a>
*/
public class BaseSchema implements AstroSchema {
+ static private final String[] MinimalTagNames = {
+ "LiteralChar",
+ "LiteralInteger",
+ "LiteralFloat64",
+ "LiteralString"
+ };
+
/**
+ *
+ */
+ static public final AstroSchema MINIMAL =
+ new BaseSchema("Minimal", ConstList.fromArray(MinimalTagNames));
+
+ /**
* For diagnostic purposes only.
*/
- private final String myName;
+ private final String mySchemaName;
/**
- *
+ * Indexed by tag (a short)
*/
- private final AstroTag[] myByTypeCodes;
+ private final AstroTag[] myByTagCode;
/**
* String (not Twine) => AstroTag
*/
- private final ConstMap myByTypeName;
+ private final ConstMap myByTagName;
/**
*
*/
- private transient AstroTag myOptLiteralCharTag = null;
+ private AstroTag myLiteralCharTag;
/**
*
*/
- private transient AstroTag myOptLiteralIntegerTag = null;
+ private AstroTag myLiteralIntegerTag;
/**
*
*/
- private transient AstroTag myOptLiteralFloat64Tag = null;
+ private AstroTag myLiteralFloat64Tag;
/**
*
*/
- private transient AstroTag myOptLiteralStringTag = null;
+ private AstroTag myLiteralStringTag;
/**
+ * The literal tag names default to their canonical names
+ */
+ public BaseSchema(String schemaName, ConstList tagNames) {
+ this(schemaName,
+ tagNames,
+ "LiteralChar",
+ "LiteralInteger",
+ "LiteralFloat64",
+ "LiteralString");
+ }
+
+ /**
*
*/
- public BaseSchema(String name, ConstList typeNames) {
- myName = name;
+ public BaseSchema(String schemaName,
+ ConstList tagNames,
+ String literalCharTagName,
+ String literalIntegerTagName,
+ String literalFloat64TagName,
+ String literalStringTagName) {
+ mySchemaName = schemaName.intern();
FlexList byCodes = FlexList.fromType(AstroTag.class,
- typeNames.size());
- FlexMap byNames = FlexMap.fromTypes(String.class,
- AstroTag.class,
- typeNames.size());
- for (int code = 0; code < typeNames.size(); code++) {
- Twine optTypeName = (Twine)E.as(typeNames.get(code), Twine.class);
- if (null != optTypeName) {
- AstroTag tag = new AstroTag(code, optTypeName, this);
- byCodes.ensureSize(code);
- byCodes.put(code, tag);
- byNames.put(optTypeName.bare(), tag, true);
+ tagNames.size());
+ FlexMap byNames = FlexMap.interning(AstroTag.class,
+ tagNames.size());
+
+ literalCharTagName = literalCharTagName.intern();
+ literalIntegerTagName = literalIntegerTagName.intern();
+ literalFloat64TagName = literalFloat64TagName.intern();
+ literalStringTagName = literalStringTagName.intern();
+
+ for (short tagCode = 0; tagCode < tagNames.size(); tagCode++) {
+ String optTagName = (String)E.as(tagNames.get(tagCode),
+ String.class);
+ if (null != optTagName) {
+ optTagName = optTagName.intern();
+ AstroTag tag;
+
+ if (optTagName == literalCharTagName) {
+ tag = new AstroTag(tagCode, optTagName, this,
+ Character.class);
+ myLiteralCharTag = tag;
+ literalCharTagName = null;
+
+ } else if (optTagName == literalIntegerTagName) {
+ tag = new AstroTag(tagCode, optTagName, this,
+ BigInteger.class);
+ myLiteralIntegerTag = tag;
+ literalIntegerTagName = null;
+
+ } else if (optTagName == literalFloat64TagName) {
+ tag = new AstroTag(tagCode, optTagName, this,
+ Double.class);
+ myLiteralFloat64Tag = tag;
+ literalFloat64TagName = null;
+
+ } else if (optTagName == literalStringTagName) {
+ tag = new AstroTag(tagCode, optTagName, this,
+ Twine.class);
+ myLiteralStringTag = tag;
+ literalStringTagName = null;
+
+ } else {
+ tag = new AstroTag(tagCode, optTagName, this,
+ null);
+ }
+ byCodes.ensureSize(tagCode);
+ byCodes.put(tagCode, tag);
+ byNames.put(optTagName, tag, true);
}
}
- myByTypeCodes = (AstroTag[])byCodes.getArray(AstroTag.class);
- myByTypeName = byNames.snapshot();
+ E.require(null == literalCharTagName &&
+ null == literalIntegerTagName &&
+ null == literalIntegerTagName &&
+ null == literalIntegerTagName,
+ "Unmatched literal name for: ", mySchemaName);
+ myByTagCode = (AstroTag[])byCodes.getArray(AstroTag.class);
+ myByTagName = byNames.snapshot();
}
/**
*
*/
public String toString() {
- return "<Schema for " + myName + ">";
+ return "<Schema for " + mySchemaName + ">";
}
/**
*
*/
- public String getName() {
- return myName;
+ public String getSchemaName() {
+ return mySchemaName;
}
/**
*
*/
- public AstroTag getOptTagForCode(int typeCode) {
- AstroTag optResult = myByTypeCodes[typeCode];
- return optResult;
+ public AstroTag getOptTagForCode(short optTagCode) {
+ if (-1 == optTagCode) {
+ return null;
+ } else {
+ return myByTagCode[optTagCode];
+ }
}
/**
*
*/
- public AstroTag getTagForCode(int typeCode) {
- AstroTag optResult = myByTypeCodes[typeCode];
- E.requireSI(null != optResult, "No tag for type code: ", typeCode);
+ public AstroTag getTagForCode(short tagCode) {
+ AstroTag optResult = getOptTagForCode(tagCode);
+ E.requireSI(null != optResult, "No tag for type code: ", tagCode);
return optResult;
}
/**
*
*/
- public AstroTag getOptTagForName(String typeName) {
- AstroTag optResult = (AstroTag)myByTypeName.get(typeName, null);
- return optResult;
+ public AstroTag getOptTagForName(String tagName) {
+ return (AstroTag)myByTagName.get(tagName, null);
}
/**
*
*/
- public AstroTag getTagForName(String typeName) {
- AstroTag optResult = (AstroTag)myByTypeName.get(typeName, null);
- E.require(null != optResult, "No tag named: ", typeName);
+ public AstroTag getTagForName(String tagName) {
+ AstroTag optResult = getOptTagForName(tagName);
+ E.require(null != optResult, "No tag named: ", tagName);
return optResult;
}
/**
- * The default implementation provided here just gets the tag whose name
- * is "LiteralChar".
- * <p>
- * May be overridden to describe a grammar with different conventions.
+ *
*/
public AstroTag getLiteralCharTag() {
- if (null == myOptLiteralCharTag) {
- myOptLiteralCharTag = getTagForName("LiteralChar");
- }
- return myOptLiteralCharTag;
+ return myLiteralCharTag;
}
/**
- * The default implementation provided here just gets the tag whose name
- * is "LiteralInteger".
- * <p>
- * May be overridden to describe a grammar with different conventions.
+ *
*/
public AstroTag getLiteralIntegerTag() {
- if (null == myOptLiteralIntegerTag) {
- myOptLiteralIntegerTag = getTagForName("LiteralInteger");
- }
- return myOptLiteralIntegerTag;
+ return myLiteralIntegerTag;
}
/**
- * The default implementation provided here just gets the tag whose name
- * is "LiteralFloat64".
- * <p>
- * May be overridden to describe a grammar with different conventions.
+ *
*/
public AstroTag getLiteralFloat64Tag() {
- if (null == myOptLiteralFloat64Tag) {
- myOptLiteralFloat64Tag = getTagForName("LiteralFloat64");
- }
- return myOptLiteralFloat64Tag;
+ return myLiteralFloat64Tag;
}
/**
- * The default implementation provided here just gets the tag whose name
- * is "LiteralString".
- * <p>
- * May be overridden to describe a grammar with different conventions.
+ *
*/
public AstroTag getLiteralStringTag() {
- if (null == myOptLiteralStringTag) {
- myOptLiteralStringTag = getTagForName("LiteralString");
- }
- return myOptLiteralStringTag;
+ return myLiteralStringTag;
}
/**
*
*/
- public AstroTag getOptDataTag(Object data) {
- if (data instanceof Character) {
- return getLiteralCharTag();
-
- } else if (data instanceof Number) {
- if (data instanceof Byte ||
- data instanceof Short ||
- data instanceof Integer ||
- data instanceof Long ||
- data instanceof BigInteger) {
- return getLiteralIntegerTag();
- } else if (data instanceof Float || data instanceof Double) {
- return getLiteralFloat64Tag();
+ public AstroTag getOptTypeTag(Class clazz) {
+ if (Character.class == clazz) {
+ return myLiteralCharTag;
+ }
+ if (Number.class.isAssignableFrom(clazz)) {
+ if (Double.class == clazz || Float.class == clazz) {
+ return myLiteralFloat64Tag;
+ } else if (BigInteger.class == clazz ||
+ Byte.class == clazz ||
+ Short.class == clazz ||
+ Integer.class == clazz ||
+ Long.class == clazz) {
+ return myLiteralIntegerTag;
+ } else {
+ throw new RuntimeException("Unrecognized number type: " +
+ clazz);
}
-
- } else if (data instanceof String || data instanceof Twine) {
- return getLiteralStringTag();
+ }
+ if (Twine.class == clazz || String.class == clazz) {
+ return myLiteralStringTag;
}
- //not representable as a literal
return null;
}
/**
*
*/
- public AstroTag getLiteralDataTag(Object data) {
- AstroTag result = getOptDataTag(data);
- E.require(null != result, "Not a literal type: ", data.getClass());
- return result;
+ public AstroTag getTypeTag(Class clazz) {
+ AstroTag optResult = getOptTypeTag(clazz);
+ E.require(null != optResult, "Unrecognized type: ", clazz);
+ return optResult;
}
}
1.1 e/src/jsrc/org/quasiliteral/astro/AstroAST.java
Index: AstroAST.java
===================================================================
package org.quasiliteral.astro;
import antlr.BaseAST;
import antlr.CommonToken;
import antlr.Token;
import antlr.collections.AST;
import org.erights.e.elib.tables.Twine;
import org.erights.e.elib.tables.ConstList;
/**
* AST node implementation which stores tokens explicitly.
* <p>
* This is handy if you'd rather derive information from tokens on an
* as-needed basis instead of snarfing data from a token as an AST
* is being built.
* <p>
* In keeping with the nature of Antlr ASTs, Astros are mutable. The
* corresponding immutable, Persistent, & PassByCopy type is the
* {@link org.quasiliteral.term.Term}.
*
* @author <a href="mailto:markm@caplet.com">Mark S Miller</a>
* @author Based on Danfuzz Bornstein's TokenAST
*/
public class AstroAST extends BaseAST implements Astro, AstroArg {
/**
*
*/
private AstroToken myOptToken;
/**
* Construct an instance which (at least initially) is not associated
* with a token.
*/
public AstroAST() {
myOptToken = null;
}
/**
* Construct an instance which is associated with the given token.
*
* @param optToken :AstroToken The (optional) token to associate this
* instance with
*/
public AstroAST(Token optToken) {
initialize(optToken);
}
/**
*
*/
public String toString() {
return "" + myOptToken;
}
/**
* Builds an equivalent of this AST using the building methods of
* 'builder'.
* <p>
* Pattern-wise, the schema functions here as both a visitor and as a
* factory.
*
* @return :Node
*/
public Astro build(AstroBuilder builder) {
Astro func = myOptToken.build(builder);
AstroAST optSub = (AstroAST)getFirstChild();
if (null == optSub) {
//This case is broken out in order to allow 'func' to be a Node
//rather than a Leaf. This would happen is myOptToken is
//a composite.
return builder.node(func);
}
Object args = builder.argList();
for (; null != optSub; optSub = (AstroAST)optSub.getNextSibling()) {
args = builder.argList(args,
builder.arg(optSub.build(builder)));
}
return builder.node(func, args);
}
/**
* Since not all {@link AST}s are Astros, this static method
* provides the equivalent of the build/1 instance method for ASTs in
* general.
* <p>
* In the understanding of non-Astro ASTs used here, their functor is
* only according to the AST's type code, for the tag, and the AST's text,
* for the source.
* <p>
* XXX This should probably be made into a sugar-instance-method of AST.
*/
static public Astro build(AST self, AstroBuilder builder) {
if (self instanceof AstroAST) {
return ((AstroAST)self).build(builder);
} else {
AstroSchema schema = builder.getSchema();
short tagCode = AstroTag.typeCode2tagCode(self.getType());
Astro func = builder.leafTag(schema.getOptTagForCode(tagCode),
Twine.fromString(self.getText()));
AST optSub = self.getFirstChild();
if (null == optSub) {
//See comment in build/1 above
return builder.node(func);
}
Object args = builder.argList();
for (; null != optSub; optSub = optSub.getNextSibling()) {
args = builder.argList(args,
builder.arg(build(optSub, builder)));
}
return builder.node(func, args);
}
}
/**
* Get the token text for this instance. If there is no token associated
* with this instance, then this returns the empty string
* (<code>""</code>), not <code>null</code>.
*
* @return non-null; the token text
*/
public String getText() {
if (myOptToken == null) {
return "";
} else {
return myOptToken.getText();
}
}
/**
* Get the token type for this instance. If there is no token associated
* with this instance, then this returns {@link Token#INVALID_TYPE}.
*
* @return the token type
*/
public int getType() {
if (myOptToken == null) {
return Token.INVALID_TYPE;
} else {
return myOptToken.getType();
}
}
/**
* Get the token associated with this instance. If there is no token
* associated with this instance, then this returns <code>null</code>.
*
* @return The token associated with this instance, or <code>mull</code>
* if there is no associated token
*/
public AstroToken getOptToken() {
return myOptToken;
}
/**
* Set the token associated with this instance.
*
* @param optToken The new token (or null) to associate with this
* instance.
*/
public void setOptToken(AstroToken optToken) {
myOptToken = optToken;
}
/**
* Initialize this instance with the given token.
*
* @param optToken :AstroToken the token to associate with this instance
*/
public void initialize(Token optToken) {
myOptToken = (AstroToken)optToken;
}
/**
* Initialize this instance with the given token type and text.
* This will construct a new {@link CommonToken} with the given
* parameters and associate this instance with it.
*
* @param type the token type
* @param optText The token text, or null
*/
public void initialize(int type, String optText) {
initialize(new CommonToken(type, optText));
}
/**
* Initialize this instance based on the given {@link AST}.
* If the given <code>AST</code> is in fact an instance of
* <code>AstroAST</code>, then this instance will be initialized
* to point at the same token as the given one. If not, then this
* instance will be initialized with the same token type and text
* as the given one.
*
* @param ast non-null; the <code>AST</code> to base this instance on
*/
public void initialize(AST ast) {
if (ast instanceof AstroAST) {
initialize(((AstroAST)ast).getOptToken());
} else {
initialize(ast.getType(), ast.getText());
}
}
/**
* Set the token text for this node. If this instance is already
* associated with a token, then that token is destructively modified
* by this operation. If not, then a new token is constructed with
* the type {@link Token#INVALID_TYPE} and the given text.
*
* @param text the new token text
*/
public void setText(String text) {
if (myOptToken == null) {
initialize(Token.INVALID_TYPE, text);
} else {
myOptToken.setText(text);
}
}
/**
* Set the token type for this node. If this instance is already
* associated with a token, then that token is destructively modified
* by this operation. If not, then a new token is constructed with
* the given type and an empty (<code>""</code>, not <code>null</code>)
* text string.
*
* @param type the new token type
*/
public void setType(int type) {
if (myOptToken == null) {
initialize(type, "");
} else {
myOptToken.setType(type);
}
}
public AstroTag getTag() {
return myOptToken.getTag();
}
public short getOptTagCode() {
return myOptToken.getOptTagCode();
}
public Object getOptData() {
return myOptToken.getOptData();
}
public Object getOptTokenData() {
return myOptToken.getOptTokenData();
}
public Twine getSource() {
return myOptToken.getSource();
}
public ConstList getArgs() {
return myOptToken.getArgs();
}
public Astro withoutArgs() {
throw new RuntimeException("XXX not yet implemented");
}
public Astro withArgs(ConstList args) {
throw new RuntimeException("XXX not yet implemented");
}
}
1.1 e/src/jsrc/org/quasiliteral/astro/AstroArg.java
Index: AstroArg.java
===================================================================
package org.quasiliteral.astro;
//This file is hereby placed in the public domain
/**
* An element of an {@link Astro} argument list.
* <p>
* Normally this is the same type as {@link Astro} (as in the AST and Term
* trees). But this is made a separate type for QuasiTerm trees, where they
* can represent a pattern or generator for some number of Astros.
*
* @author <a href="mailto:markm@caplet.com">Mark Miller</a>
*/
public interface AstroArg {
}
1.1 e/src/jsrc/org/quasiliteral/quasiterm/QuasiBuilder.java
Index: QuasiBuilder.java
===================================================================
package org.quasiliteral.quasiterm;
import org.quasiliteral.astro.AstroBuilder;
import org.quasiliteral.astro.Astro;
import org.quasiliteral.astro.AstroArg;
//This file is hereby placed in the public domain
/**
* AstroBuilder extended with additional building methods for the expression
* of quasi-literal tree expressions and patterns.
* <p>
* These additional methods correspond to the quasi-oriented productions of
* term.y. XXX Once this is converted to an Antlr-based term.g, then we
* should use Antlr's support for grammar inheritance to split it up into
* the base term.y and the derived quasiterm.y. The former can then use only
* an AstroBuilder for building, and only the latter would require a
* QuasiBuilder. At such a time, the org.quasiliteral.term package can
* probably stop depending on the org.quasiliteral.quasiterm package, giving
* us a happy layering rather than a sad cycle.
* <p>
* The pretend parameterized types from AstroBuilder are: <pre>
* Leaf -- Leaves of the tree, representing tokens of the grammar.
* Node -- Lnternal nodes of the tree, looks like application of a Leaf
* as an functor to Args.
* Arg -- An individual argument in a list of arguments. Typically the
* same as Node, but not always. See QuasiTermBuilder.
* Args -- Represents a list of Arg.
* </pre>
* QuasiBuilder adds to this list:<pre>
*
* </pre>
*
* @author <a href="mailto:markm@caplet.com">Mark Miller</a>
*/
public interface QuasiBuilder extends AstroBuilder {
/**
*
*/
boolean doesQuasis();
/**
*
*/
Astro termHole(Astro optIdent, Astro functorHole);
/**
*
*/
AstroArg alt(AstroArg leftArg, AstroArg rightArg);
/**
*
*/
AstroArg seq(Astro optTerm, String quant);
/**
*
*/
AstroArg argGroup(Object args, String quant);
/**
*
*/
Object unpack(Astro litString);
/**
*
*/
Astro dollarHole(Astro litInt);
/**
*
*/
Astro atHole(Astro litInt);
}
1.1 e/src/jsrc/org/quasiliteral/quasiterm/QuasiBuilderAdaptor.java
Index: QuasiBuilderAdaptor.java
===================================================================
package org.quasiliteral.quasiterm;
import org.erights.e.elib.tables.Twine;
import org.quasiliteral.astro.AstroBuilder;
import org.quasiliteral.astro.AstroSchema;
import org.quasiliteral.astro.Astro;
import org.quasiliteral.astro.AstroTag;
import org.quasiliteral.astro.AstroArg;
import org.quasiliteral.term.TermBuilder;
//This file is hereby placed in the public domain
/**
* Wraps an AstroBuilder to pretend to be of type QuasiBuilder.
* <p>
* This kludge exists only until we switch to Antlr, and make use of its
* support for grammar inheritance. Until then, the one grammar, term.y, must
* support both literal and quasi-literal term trees, so it is therefore
* defined in terms of the larger subtype -- QuasiBuilder.
*
* @author <a href="mailto:markm@caplet.com">Mark Miller</a>
*/
public class QuasiBuilderAdaptor implements QuasiBuilder {
/**
* Builds Term trees according to the term.y grammar
*/
static public final QuasiBuilder FOR_TERMS =
new QuasiBuilderAdaptor(TermBuilder.FOR_TERMS);
/**
* Builds ASTs according to the term.y grammar
*/
static public final QuasiBuilder FOR_ASTS =
new QuasiBuilderAdaptor(TermBuilder.FOR_ASTS);
private AstroBuilder myBuilder;
public QuasiBuilderAdaptor(AstroBuilder builder) {
myBuilder = builder;
}
/**
*
*/
public String toString() {
return "<adapting " + myBuilder.toString() + ">";
}
public AstroSchema getSchema() {
return myBuilder.getSchema();
}
public Astro leafTag(AstroTag tag, Twine source) {
return myBuilder.leafTag(tag, source);
}
public Astro leafData(Object data, Twine source) {
return myBuilder.leafData(data, source);
}
public Astro composite(AstroTag tag, Object data, Twine source) {
return myBuilder.composite(tag, data, source);
}
public Astro node(Astro leaf) {
return myBuilder.node(leaf);
}
public Astro node(Astro leaf, Object args) {
return myBuilder.node(leaf, args);
}
public Object argList() {
return myBuilder.argList();
}
public Object argList(AstroArg first) {
return myBuilder.argList(first);
}
public Object argList(Object list, AstroArg next) {
return myBuilder.argList(list, next);
}
public AstroArg arg(Astro node) {
return myBuilder.arg(node);
}
public boolean doesQuasis() {
return false;
}
public Astro termHole(Astro optIdent, Astro functorHole) {
throw new RuntimeException("not quasi-ing");
}
public AstroArg alt(AstroArg leftArg, AstroArg rightArg) {
throw new RuntimeException("not quasi-ing");
}
public AstroArg seq(Astro optTerm, String quant) {
throw new RuntimeException("not quasi-ing");
}
public AstroArg argGroup(Object args, String quant) {
throw new RuntimeException("not quasi-ing");
}
public Object unpack(Astro litString) {
throw new RuntimeException("not quasi-ing");
}
public Astro dollarHole(Astro litInt) {
throw new RuntimeException("not quasi-ing");
}
public Astro atHole(Astro litInt) {
throw new RuntimeException("not quasi-ing");
}
}
1.4 +22 -25 e/src/jsrc/org/quasiliteral/syntax/BaseLexer.java
Index: BaseLexer.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/syntax/BaseLexer.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- BaseLexer.java 2001/12/05 00:46:11 1.3
+++ BaseLexer.java 2001/12/06 06:25:09 1.4
@@ -2,6 +2,8 @@
import org.erights.e.elib.tables.Twine;
import org.quasiliteral.astro.AstroBuilder;
+import org.quasiliteral.astro.Astro;
+import org.quasiliteral.astro.AstroTag;
import java.io.IOException;
import java.math.BigInteger;
@@ -124,7 +126,7 @@
*
*/
public String toString() {
- return "<Lexing " + myBuilder.getSchema().getName() + ">";
+ return "<Lexing " + myBuilder.getSchema().getSchemaName() + ">";
}
/**
@@ -234,7 +236,7 @@
/**
* @return :Leaf (see {@link AstroBuilder})
*/
- public Object nextToken() throws IOException, SyntaxException {
+ public Astro nextToken() throws IOException, SyntaxException {
try {
return getNextToken();
} finally {
@@ -360,53 +362,48 @@
}
/**
- * Just forwards to myBuilder
- */
- public int getCodeOfLeaf(Object leaf) {
- return myBuilder.getCodeOfLeaf(leaf);
- }
-
- /**
*
*/
- protected Object leafTag(int typeCode, Twine source) {
- return myBuilder.leafTag(typeCode, source);
+ protected Astro leafTag(short tagCode, Twine source) {
+ AstroTag tag = myBuilder.getSchema().getTagForCode(tagCode);
+ return myBuilder.leafTag(tag, source);
}
/**
*
*/
- protected Object leafData(Object data, Twine source) {
+ protected Astro leafData(Object data, Twine source) {
return myBuilder.leafData(data, source);
}
/**
*
*/
- protected Object composite(int typeCode, Object data, Twine source) {
- return myBuilder.composite(typeCode, data, source);
+ protected Astro composite(short tagCode, Object data, Twine source) {
+ AstroTag tag = myBuilder.getSchema().getTagForCode(tagCode);
+ return myBuilder.composite(tag, data, source);
}
/**
*
*/
- protected abstract Object getNextToken()
+ protected abstract Astro getNextToken()
throws IOException, SyntaxException;
/**
*
*/
- protected Object openBracket(char closer) throws IOException {
- int tokenType = myChar;
+ protected Astro openBracket(char closer) throws IOException {
+ short tagCode = (short)myChar;
nextChar();
Twine openner = endToken();
- return openBracket(tokenType, openner, closer);
+ return openBracket(tagCode, openner, closer);
}
/**
*
*/
- protected Object openBracket(int tokenType,
+ protected Astro openBracket(short tagCode,
Twine openner,
char closer)
throws IOException {
@@ -416,20 +413,20 @@
//Indent the next line to right after the open.
myIndenter.push(openner, closer, myPos);
}
- return leafTag(tokenType, openner);
+ return leafTag(tagCode, openner);
}
/**
*
*/
- protected Object closeBracket() throws IOException {
+ protected Astro closeBracket() throws IOException {
char closerChar = (char)myChar;
nextChar();
Twine closer = endToken();
//on mismatched close, throws SyntaxError at openner
//on unmatched close, throws Syntax error at closer
myIndenter.pop(closerChar, closer);
- return leafTag(closerChar, closer);
+ return leafTag((short)closerChar, closer);
}
/**
@@ -502,7 +499,7 @@
/**
*
*/
- protected Object charLiteral() throws IOException, SyntaxException {
+ protected Astro charLiteral() throws IOException, SyntaxException {
nextChar();
char value = charConstant();
nextChar();
@@ -565,7 +562,7 @@
/**
*
*/
- protected Object numberLiteral()
+ protected Astro numberLiteral()
throws IOException, SyntaxException {
// Now handles floating point numbers as well as integers
boolean floating = false;
@@ -707,7 +704,7 @@
/**
*
*/
- protected Object stringLiteral() throws IOException, SyntaxException {
+ protected Astro stringLiteral() throws IOException, SyntaxException {
nextChar();
Twine openner = (Twine)myLTwine.run(myOptStartPos, myPos);
myIndenter.push(openner, '"', 0);
1.11 +214 -47 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.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- Term.java 2001/12/05 00:46:11 1.10
+++ Term.java 2001/12/06 06:25:09 1.11
@@ -1,13 +1,21 @@
package org.quasiliteral.term;
import org.erights.e.elib.prim.StaticMaker;
+import org.erights.e.elib.prim.E;
import org.erights.e.elib.serial.PassByConstruction;
import org.erights.e.elib.serial.Persistent;
import org.erights.e.elib.tables.ConstList;
import org.erights.e.elib.tables.Selfless;
+import org.erights.e.elib.tables.Twine;
+import org.erights.e.elib.eio.TextWriter;
import org.erights.e.develop.format.StringHelper;
import org.quasiliteral.astro.AstroBuilder;
+import org.quasiliteral.astro.Astro;
+import org.quasiliteral.astro.AstroArg;
+import org.quasiliteral.astro.AstroTag;
+import java.io.IOException;
+
//This file is hereby placed in the public domain
/**
@@ -30,7 +38,8 @@
* @author Many thanks also to Dean Tribble
*/
public class Term
- implements Selfless, PassByConstruction, Persistent {
+ implements Selfless, PassByConstruction, Persistent,
+ Astro, AstroArg {
/**
*
@@ -39,97 +48,255 @@
StaticMaker.make(Term.class);
/**
- *
+ * @serial Represents the token-type of the functor of this term.
*/
- private final Functor myFunctor;
+ private final AstroTag myTag;
/**
- *
+ * @serial If the functor represents a literal-data token, then this is
+ * the data, and myTag must represent the cononical corresponding
+ * token-type for this kind of data in this schema.
*/
- private final ConstList myArgs;
+ private final Object myOptData;
/**
- *
+ * @serial What source text was originally lexed or parsed to produce
+ * this term, or the functor of this term?
*/
- public Term(Functor functor, ConstList args) {
- myFunctor = functor;
- myArgs = args;
- }
+ private final Twine mySource;
/**
- *
+ * A term is a functor (the above three instance variables) as
+ * parameterized by a list of argument Terms. These are the arguments. A
+ * term of zero arguments is often refered to as a "functor", so there's
+ * no information beyond the functor-part.
*/
- public String toString() {
- return "term`" + toString(" ", true) + "`";
- }
+ private final ConstList myArgs;
/**
- *
+ * Just used to decide how to pretty print.
+ * <p>
+ * Initialized lazily. 0 if uninitialized, so does not need to be
+ * recalculated on revival.
*/
- public String toString(String prefix, boolean quasiFlag) {
- String func = myFunctor.toString(quasiFlag);
- int len = myArgs.size();
- if (0 == len) {
- return func;
- }
- StringBuffer buf = new StringBuffer(func);
- buf.append("(");
- int indentCount = func.length() + 1; //for the "("
- String indent = prefix + StringHelper.multiply(" ", indentCount);
- Term child = (Term)myArgs.get(0);
- buf.append(child.toString(indent, quasiFlag));
- for (int i = 1; i < len; i++) {
- buf.append(",\n");
- buf.append(indent);
- child = (Term)myArgs.get(i);
- buf.append(child.toString(indent, quasiFlag));
- }
- buf.append(")");
- return buf.toString();
+ private transient int myHeight = 0;
+
+ /**
+ * @param tag Represents the token-type of the functor.
+ * @param optData Either literal data or null. If not null, then the tag
+ * must represent the canonical literal type for this
+ * kind of data in this schema.
+ * @param source What source text was originally lexed or parsed to
+ * produce this token?
+ * @param args This Term's argument list -- a list of Terms
+ */
+ public Term(AstroTag tag, Object optData, Twine source, ConstList args) {
+ myTag = tag;
+ myOptData = optData;
+ mySource = source;
+ myArgs = args;
}
/**
- * Uses 'TermMaker new(myFunctor, myArgs)'
+ * Uses 'TermMaker new(myTag, myOptData, mySource, myArgs)'
*/
public Object[] getCanonicalState() {
Object[] result = {
- TermMaker, "new", myFunctor, myArgs
+ TermMaker, "new", myTag, myOptData, mySource, myArgs
};
return result;
}
/**
- * @return :Node
+ *
*/
- public Object build(AstroBuilder builder) {
- Object func = myFunctor.build(builder);
+ public Astro build(AstroBuilder builder) {
+ Astro func;
+ if (null == myOptData) {
+ func = builder.leafTag(myTag, mySource);
+ } else {
+ //Assumes tag adds no more info.
+ func = builder.leafData(myOptData, mySource);
+ }
Object args = builder.argList();
int len = myArgs.size();
if (0 == len) {
- //It shouldn't be possible for myFunctor to be turned into
- //a composite, but just to accomodate this possibility, in order
- //to keep the composition of contracts clean, we call node/1 when
- //there are no args.
return builder.node(func);
}
for (int i = 0; i < len; i++) {
- Object arg = ((Term)myArgs.get(i)).build(builder);
+ AstroArg arg = builder.arg(((Term)myArgs.get(i)).build(builder));
args = builder.argList(args, arg);
}
return builder.node(func, args);
}
/**
+ * Represents the token-type of the functor of this term.
+ */
+ public AstroTag getTag() {
+ return myTag;
+ }
+
+ /**
*
+ */
+ public short getOptTagCode() {
+ throw new RuntimeException("XXX not yet implemented");
+ }
+
+ /**
+ * Either literal data or null. If not null, then the tag
+ * must represent the canonical literal type for this
+ * kind of data in this schema.
*/
- public Functor getFunctor() {
- return myFunctor;
+ public Object getOptData() {
+ return myOptData;
}
/**
*
*/
+ public Object getOptTokenData() {
+ throw new RuntimeException("XXX not yet implemented");
+ }
+
+ /**
+ * What source text was originally lexed or parsed to produce this token?
+ */
+ public Twine getSource() {
+ return mySource;
+ }
+
+ /**
+ * A term is a functor (the above three instance variables) as
+ * parameterized by a list of argument Terms. These are the arguments.
+ * A term of zero arguments is often refered to as a "functor", so there's
+ * no information beyond the functor-part.
+ */
public ConstList getArgs() {
return myArgs;
+ }
+
+ /**
+ *
+ */
+ public Astro withoutArgs() {
+ throw new RuntimeException("XXX not yet implemented");
+ }
+
+ /**
+ *
+ */
+ public Astro withArgs(ConstList args) {
+ throw new RuntimeException("XXX not yet implemented");
+ }
+
+ /**
+ * Lexicographic comparison of, in order:<ul>
+ * <li>the tags</li>
+ * <li>the data</li>
+ * <li>the args</li>
+ * </ul>
+ */
+ public double compareTo(Term other) {
+ double result = myTag.compareTo(other.myTag);
+ if (0.0 != result) {
+ return result;
+ }
+ if (null == myOptData) {
+ if (null == other.myOptData) {
+ //do nothing
+ } else {
+ //null is less than anything else
+ return -1.0;
+ }
+ } else {
+ if (null == other.myOptData) {
+ //everything else is greater than null
+ return 1.0;
+ } else {
+ result = E.asFloat64(E.call(myOptData,
+ "compareTo",
+ other.myOptData));
+ }
+ }
+ if (0.0 != result) {
+ return result;
+ }
+ return myArgs.compareTo(other.myArgs);
+ }
+
+ /**
+ * What's the longest distance to the bottom?
+ * <p>
+ * A leaf node is height 1. All other nodes are one more than the height
+ * of their highest child. This is used for pretty printing.
+ */
+ public int getHeight() {
+ if (myHeight <= 0) {
+ myHeight = 1;
+ for (int i = 0; i < myArgs.size(); i++) {
+ int h = ((Term)myArgs.get(i)).getHeight();
+ myHeight = Math.max(myHeight, h + 1);
+ }
+ }
+ return myHeight;
+ }
+
+ /**
+ *
+ */
+ public void printOn(TextWriter out) throws IOException {
+ out.print("term`");
+ prettyPrintOn(out.indent(" "), true);
+ out.print("`");
+ }
+
+ /**
+ *
+ */
+ public void prettyPrintOn(TextWriter out, boolean quasiFlag)
+ throws IOException {
+ String label = myTag.getTagName();
+ if (null != myOptData) {
+ label = E.toQuote(myOptData).bare();
+ if (quasiFlag) {
+ label = StringHelper.replaceAll(label, "$", "$$");
+ label = StringHelper.replaceAll(label, "@", "@@");
+ label = StringHelper.replaceAll(label, "`", "``");
+ }
+ }
+ out.print(label);
+ int h = getHeight();
+ if (h <= 1) {
+ if (myArgs.size() != 0) {
+ throw new RuntimeException("internal: bad height " + h);
+ }
+ //If it's a leaf, don't show parens either
+ return;
+ }
+ if (h == 2) {
+ //If it only contains leaves, do it on one line
+ out.print("(");
+ ((Term)myArgs.get(0)).prettyPrintOn(out, quasiFlag);
+ for (int i = 1; i < myArgs.size(); i++) {
+ out.print(", ");
+ ((Term)myArgs.get(i)).prettyPrintOn(out, quasiFlag);
+ }
+ out.print(")");
+ return;
+ }
+ //print each child lined up.
+ out.print("(");
+ int reps = label.length() + 1;
+ String spaces = StringHelper.multiply(" ", reps);
+ TextWriter sub = out.indent(spaces);
+
+ ((Term)myArgs.get(0)).prettyPrintOn(sub, quasiFlag);
+ for (int i = 1; i < myArgs.size(); i++) {
+ sub.println(",");
+ ((Term)myArgs.get(i)).prettyPrintOn(sub, quasiFlag);
+ }
+ sub.print(")");
}
}
1.11 +46 -33 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.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- TermBuilder.java 2001/12/05 00:46:11 1.10
+++ TermBuilder.java 2001/12/06 06:25:09 1.11
@@ -7,6 +7,9 @@
import org.quasiliteral.astro.AstroBuilder;
import org.quasiliteral.astro.AstroSchema;
import org.quasiliteral.astro.ASTBuilder;
+import org.quasiliteral.astro.Astro;
+import org.quasiliteral.astro.AstroTag;
+import org.quasiliteral.astro.AstroArg;
//This file is hereby placed in the public domain
@@ -52,7 +55,7 @@
*
*/
public String toString() {
- return "<building Term trees for " + mySchema.getName() + ">";
+ return "<building Term trees for " + mySchema.getSchemaName() + ">";
}
/**
@@ -63,21 +66,23 @@
}
/**
- * @return :Functor
+ * @return :Term
*/
- public Object leafTag(int typeCode, Twine source) {
- return new Functor(mySchema.getTagForCode(typeCode),
- null,
- source);
+ public Astro leafTag(AstroTag tag, Twine source) {
+ return new Term(tag,
+ null,
+ source,
+ ConstList.EmptyList);
}
/**
- * @return :Functor
+ * @return :Term
*/
- public Object leafData(Object data, Twine source) {
- return new Functor(mySchema.getOptDataTag(data),
- data,
- source);
+ public Astro leafData(Object data, Twine source) {
+ return new Term(mySchema.getTypeTag(data.getClass()),
+ data,
+ source,
+ ConstList.EmptyList);
}
/**
@@ -86,39 +91,39 @@
* code, and whose argument represents the data.
*
* @return :Term
- */
- public Object composite(int typeCode, Object data, Twine source) {
- return node(leafTag(typeCode, source),
- argList(node(leafData(data, source))));
- }
-
- /**
- * @param leaf :Functor
*/
- public int getCodeOfLeaf(Object leaf) {
- Functor functor = (Functor)leaf;
- return functor.getTag().getOptTypeCode();
+ public Astro composite(AstroTag tag, Object data, Twine source) {
+ return node(leafTag(tag, source),
+ argList(arg(leafData(data, source))));
}
/**
- * @param func :(Functor | Term)
+ * @param func :Term with no arguments
* @return :Term
*/
- public Object node(Object func) {
- if (func instanceof Term) {
- return func;
- }
- return new Term(((Functor)func), ConstList.EmptyList);
+ public Astro node(Astro leaf) {
+ Term result = (Term)leaf;
+ E.require(result.getArgs().size() == 0,
+ "To use as a functor, a Term must not have args: ",
+ result);
+ return result;
}
/**
- * @param func :Functor
+ * @param func :Term with no arguments
* @param args :(FlexList of(Term))
* @return :Term
*/
- public Object node(Object func, Object args) {
+ public Astro node(Astro leaf, Object args) {
+ Term func = (Term)leaf;
+ E.require(func.getArgs().size() == 0,
+ "To use as a functor, a Term must not have args: ",
+ func);
FlexList argList = (FlexList)E.as(args, FlexList.class);
- return new Term(((Functor)func), argList.snapshot());
+ return new Term(func.getTag(),
+ func.getOptData(),
+ func.getSource(),
+ argList.snapshot());
}
/**
@@ -137,7 +142,7 @@
* @param first :Term
* @return :(FlexList of(Term))
*/
- public Object argList(Object first) {
+ public Object argList(AstroArg first) {
FlexList result = FlexList.fromType(Term.class);
result.push(first);
return result;
@@ -153,9 +158,17 @@
* @param next :Term
* @return :(FlexList of(Term))
*/
- public Object argList(Object list, Object next) {
+ public Object argList(Object list, AstroArg next) {
FlexList argList = (FlexList)E.as(list, FlexList.class);
argList.push(next);
return argList;
+ }
+
+ /**
+ * @param node :Term
+ * @return :Term
+ */
+ public AstroArg arg(Astro node) {
+ return (Term)node;
}
}
1.10 +12 -11 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.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- TermLexer.java 2001/12/03 03:30:56 1.9
+++ TermLexer.java 2001/12/06 06:25:09 1.10
@@ -24,6 +24,7 @@
import org.erights.e.elib.tables.EmptyTwine;
import org.erights.e.elib.tables.Twine;
import org.quasiliteral.astro.AstroBuilder;
+import org.quasiliteral.astro.Astro;
import org.quasiliteral.syntax.BaseLexer;
import org.quasiliteral.syntax.FileFeeder;
import org.quasiliteral.syntax.LineFeeder;
@@ -99,18 +100,18 @@
/**
* Override to skip newlines.
*/
- public Object nextToken() throws IOException, SyntaxException {
- Object result;
+ public Astro nextToken() throws IOException, SyntaxException {
+ Astro result;
do {
result = super.nextToken();
- } while (getCodeOfLeaf(result) == TermParser.EOL);
+ } while (result.getOptTagCode() == TermParser.EOL);
return result;
}
/**
*
*/
- protected Object getNextToken() throws IOException, SyntaxException {
+ protected Astro getNextToken() throws IOException, SyntaxException {
if (myDelayedNextChar) {
nextChar();
myDelayedNextChar = false;
@@ -132,7 +133,7 @@
{
char c = (char)myChar;
nextChar();
- return leafTag(c, endToken());
+ return leafTag((short)c, endToken());
}
case EOFCHAR:
{
@@ -194,8 +195,8 @@
myContinueFlag = true;
skipLine();
stopToken();
- Object result = getNextToken();
- if (getCodeOfLeaf(result) == TermParser.EOFTOK) {
+ Astro result = getNextToken();
+ if (result.getOptTagCode() == TermParser.EOFTOK) {
needMore("continued line");
return null; //make compiler happy
} else {
@@ -243,7 +244,7 @@
/**
* Called with myChar as the first character of the identifier.
*/
- protected Object identifier() throws IOException, SyntaxException {
+ protected Astro identifier() throws IOException, SyntaxException {
do {
nextChar();
} while (myChar != EOFCHAR && isIdentifierPart((char)myChar));
@@ -277,17 +278,17 @@
TermLexer lex = new TermLexer(lr, false, false, false);
while (true) {
try {
- Object t;
+ Astro t;
do {
t = lex.nextToken();
//XXX should print t as a Functor.
stdout.println(t);
- if (lex.getCodeOfLeaf(t) == TermParser.EOL) {
+ if (t.getOptTagCode() == TermParser.EOL) {
stdout.print("stack: ",
lex.myIndenter.toString(),
"\n");
}
- } while (lex.getCodeOfLeaf(t) != TermParser.EOFTOK);
+ } while (t.getOptTagCode() != TermParser.EOFTOK);
return;
} catch (SyntaxException sex) {
TextWriter err = new TextWriter(PrintStreamWriter.err(),
1.12 +48 -45 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.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- TermParser.java 2001/12/05 00:46:11 1.11
+++ TermParser.java 2001/12/06 06:25:09 1.12
@@ -17,12 +17,14 @@
import org.erights.e.elib.tables.Twine;
import org.quasiliteral.astro.AstroSchema;
import org.quasiliteral.astro.BaseSchema;
+import org.quasiliteral.astro.Astro;
+import org.quasiliteral.astro.AstroArg;
import org.quasiliteral.quasiterm.QuasiBuilder;
import org.quasiliteral.quasiterm.QuasiBuilderAdaptor;
import org.quasiliteral.syntax.SyntaxException;
import java.io.IOException;
-//#line 24 "TermParser.java"
+//#line 26 "TermParser.java"
@@ -302,7 +304,7 @@
"functorHole : '@' '{' LiteralInteger '}'",
};
-//#line 135 "term.y"
+//#line 137 "term.y"
/**
@@ -368,23 +370,24 @@
/**
*
*/
-private int yylex() {
- Object token = null;
+private short yylex() {
+ Astro token = null;
try {
token = myLexer.nextToken();
} catch (IOException ex) {
yyerror("io: " + ex);
}
yylval = token;
- return myLexer.getCodeOfLeaf(token);
+ //Note that yacc uses tag-codes, while Antlr uses type-codes.
+ return token.getOptTagCode();
}
/**
*
*/
private void yyerror(String s) throws SyntaxException {
- int ttype = myLexer.getCodeOfLeaf(yylval);
- if (TermParser.EOFTOK == ttype && "syntax error".equals(s)) {
+ short tagCode = ((Astro)yylval).getOptTagCode();
+ if (TermParser.EOFTOK == tagCode && "syntax error".equals(s)) {
myLexer.syntaxError("Unexpected EOF");
} else {
myLexer.syntaxError(s);
@@ -436,7 +439,7 @@
static public final AstroSchema DEFAULT_SCHEMA =
new BaseSchema("Term-Tree-Language", ConstList.fromArray(TheTokens));
-//#line 388 "TermParser.java"
+//#line 391 "TermParser.java"
//###############################################################
// method: yylexdebug : check lexer state
//###############################################################
@@ -583,90 +586,90 @@
{
//########## USER-SUPPLIED ACTIONS ##########
case 1:
-//#line 72 "term.y"
+//#line 74 "term.y"
{ myOptResult = val_peek(0); }
break;
case 2:
-//#line 76 "term.y"
-{ yyval = b.node(val_peek(0)); }
+//#line 78 "term.y"
+{ yyval = b.node((Astro)val_peek(0)); }
break;
case 3:
-//#line 77 "term.y"
-{ yyval = b.node(val_peek(3), val_peek(1)); }
+//#line 79 "term.y"
+{ yyval = b.node((Astro)val_peek(3), val_peek(1)); }
break;
case 4:
-//#line 78 "term.y"
-{ yyval = b.node(val_peek(3), val_peek(1)); }
+//#line 80 "term.y"
+{ yyval = b.node((Astro)val_peek(3), val_peek(1)); }
break;
case 5:
-//#line 80 "term.y"
-{ yyval = b.termHole(null, val_peek(0)); }
+//#line 82 "term.y"
+{ yyval = b.termHole(null, (Astro)val_peek(0)); }
break;
case 6:
-//#line 81 "term.y"
-{ yyval = b.termHole(val_peek(1), val_peek(0));}
+//#line 83 "term.y"
+{ yyval = b.termHole((Astro)val_peek(1), (Astro)val_peek(0)); }
break;
case 7:
-//#line 85 "term.y"
+//#line 87 "term.y"
{ yyval = b.argList(); }
break;
case 9:
-//#line 90 "term.y"
-{ yyval = b.argList(val_peek(0)); }
+//#line 92 "term.y"
+{ yyval = b.argList((AstroArg)val_peek(0)); }
break;
case 10:
-//#line 91 "term.y"
-{ yyval = b.argList(val_peek(2), val_peek(0)); }
+//#line 93 "term.y"
+{ yyval = b.argList(val_peek(2), (AstroArg)val_peek(0)); }
break;
case 12:
-//#line 96 "term.y"
-{ yyval = b.alt(val_peek(2), val_peek(0)); }
+//#line 98 "term.y"
+{ yyval = b.alt((AstroArg)val_peek(2), (AstroArg)val_peek(0));}
break;
case 13:
-//#line 103 "term.y"
-{ yyval = b.seq( val_peek(0), "."); }
+//#line 105 "term.y"
+{ yyval = b.arg((Astro)val_peek(0)); }
break;
case 14:
-//#line 104 "term.y"
-{ yyval = b.seq( val_peek(1), (String)val_peek(0)); }
+//#line 106 "term.y"
+{ yyval = b.seq((Astro)val_peek(1), (String)val_peek(0)); }
break;
case 15:
-//#line 105 "term.y"
-{ yyval = b.seq(null, (String)val_peek(0)); }
+//#line 107 "term.y"
+{ yyval = b.seq(null, (String)val_peek(0)); }
break;
case 16:
-//#line 106 "term.y"
-{ yyval = b.seq(null, "."); }
+//#line 108 "term.y"
+{ yyval = b.seq(null, "."); }
break;
case 17:
-//#line 107 "term.y"
+//#line 109 "term.y"
{ yyval = b.argGroup(val_peek(2), (String)val_peek(0)); }
break;
case 18:
-//#line 108 "term.y"
-{ yyval = b.unpack(val_peek(0)); }
+//#line 110 "term.y"
+{ yyval = b.unpack((Astro)val_peek(0)); }
break;
case 19:
-//#line 112 "term.y"
+//#line 114 "term.y"
{ yyval = "?"; }
break;
case 20:
-//#line 113 "term.y"
+//#line 115 "term.y"
{ yyval = "+"; }
break;
case 21:
-//#line 114 "term.y"
+//#line 116 "term.y"
{ yyval = "*"; }
break;
case 27:
-//#line 129 "term.y"
-{ yyval = b.dollarHole(val_peek(1)); }
+//#line 131 "term.y"
+{ yyval = b.dollarHole((Astro)val_peek(1)); }
break;
case 28:
-//#line 130 "term.y"
-{ yyval = b.atHole(val_peek(1)); }
+//#line 132 "term.y"
+{ yyval = b.atHole( (Astro)val_peek(1)); }
break;
-//#line 615 "TermParser.java"
+//#line 618 "TermParser.java"
//########## END OF USER-SUPPLIED ACTIONS ##########
}//switch
//#### Now let's reduce... ####
1.11 +29 -26 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.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- term.y 2001/12/05 00:46:11 1.10
+++ term.y 2001/12/06 06:25:10 1.11
@@ -12,6 +12,8 @@
import org.erights.e.elib.tables.Twine;
import org.quasiliteral.astro.AstroSchema;
import org.quasiliteral.astro.BaseSchema;
+import org.quasiliteral.astro.Astro;
+import org.quasiliteral.astro.AstroArg;
import org.quasiliteral.quasiterm.QuasiBuilder;
import org.quasiliteral.quasiterm.QuasiBuilderAdaptor;
import org.quasiliteral.syntax.SyntaxException;
@@ -69,49 +71,49 @@
* </pre>
*/
start:
- term { myOptResult = $1; }
+ term { myOptResult = $1; }
;
term:
- functor { $$ = b.node($1); }
- | functor '(' argList ')' { $$ = b.node($1, $3); }
- | functorHole '(' argList ')' { $$ = b.node($1, $3); }
+ functor { $$ = b.node((Astro)$1); }
+ | functor '(' argList ')' { $$ = b.node((Astro)$1, $3); }
+ | functorHole '(' argList ')' { $$ = b.node((Astro)$1, $3); }
- | functorHole { $$ = b.termHole(null, $1); }
- | ID functorHole { $$ = b.termHole($1, $2);}
+ | functorHole { $$ = b.termHole(null, (Astro)$1); }
+ | ID functorHole { $$ = b.termHole((Astro)$1, (Astro)$2); }
;
argList:
- /* empty */ { $$ = b.argList(); }
+ /* empty */ { $$ = b.argList(); }
| args
;
args:
- arg { $$ = b.argList($1); }
- | args ',' arg { $$ = b.argList($1, $3); }
+ arg { $$ = b.argList((AstroArg)$1); }
+ | args ',' arg { $$ = b.argList($1, (AstroArg)$3); }
;
arg:
seq
- | arg '|' seq { $$ = b.alt($1, $3); }
+ | arg '|' seq { $$ = b.alt((AstroArg)$1, (AstroArg)$3);}
;
/**
* Each seq represents some number of Terms
*/
seq:
- term { $$ = b.seq( $1, "."); }
- | term quant { $$ = b.seq( $1, (String)$2); }
- | quant { $$ = b.seq(null, (String)$1); }
- | '.' { $$ = b.seq(null, "."); }
- | '(' args ')' quant { $$ = b.argGroup($2, (String)$4); }
- | '^' LiteralString { $$ = b.unpack($2); }
+ term { $$ = b.arg((Astro)$1); }
+ | term quant { $$ = b.seq((Astro)$1, (String)$2); }
+ | quant { $$ = b.seq(null, (String)$1); }
+ | '.' { $$ = b.seq(null, "."); }
+ | '(' args ')' quant { $$ = b.argGroup($2, (String)$4); }
+ | '^' LiteralString { $$ = b.unpack((Astro)$2); }
;
quant:
- '?' { $$ = "?"; }
- | '+' { $$ = "+"; }
- | '*' { $$ = "*"; }
+ '?' { $$ = "?"; }
+ | '+' { $$ = "+"; }
+ | '*' { $$ = "*"; }
;
functor:
@@ -126,8 +128,8 @@
* Starts off as a hole for a Functor, but may get promoted.
*/
functorHole:
- '$' '{' LiteralInteger '}' { $$ = b.dollarHole($3); }
- | '@' '{' LiteralInteger '}' { $$ = b.atHole($3); }
+ '$' '{' LiteralInteger '}' { $$ = b.dollarHole((Astro)$3); }
+ | '@' '{' LiteralInteger '}' { $$ = b.atHole( (Astro)$3); }
;
@@ -197,23 +199,24 @@
/**
*
*/
-private int yylex() {
- Object token = null;
+private short yylex() {
+ Astro token = null;
try {
token = myLexer.nextToken();
} catch (IOException ex) {
yyerror("io: " + ex);
}
yylval = token;
- return myLexer.getCodeOfLeaf(token);
+ //Note that yacc uses tag-codes, while Antlr uses type-codes.
+ return token.getOptTagCode();
}
/**
*
*/
private void yyerror(String s) throws SyntaxException {
- int ttype = myLexer.getCodeOfLeaf(yylval);
- if (TermParser.EOFTOK == ttype && "syntax error".equals(s)) {
+ short tagCode = ((Astro)yylval).getOptTagCode();
+ if (TermParser.EOFTOK == tagCode && "syntax error".equals(s)) {
myLexer.syntaxError("Unexpected EOF");
} else {
myLexer.syntaxError(s);