switch(t.getType()) {
case OBJ_NAME:
+
+ buf.setPendingExpr(parseObjectReference(t, buf));
break;
+
case LITERAL:
+
+ buf.setPendingExpr(new ELiteralValue(t.getValue()));
break;
+
case OP:
+
+ WordType wordType = getWordType(t);
+ if(wordType == null) {
+ // shouldn't happen
+ throw new RuntimeException("Invalid operator " + t);
+ }
+
+
break;
+
case STRING:
- WordType wordType = getWordType(t);
+
+ // see if it's a special word?
+ wordType = getWordType(t);
if(wordType == null) {
// literal string? or possibly function?
Expr funcExpr = maybeParseFuncCall(t, buf, exprType, isSimpleExpr);
buf.setPendingExpr(funcExpr);
continue;
}
+
+ // FIXME maybe obj name, maybe string?
+
+ } else {
+
+
// FIXME
}
+
break;
+
case SPACE:
- // top-level space is irrelevant
+ // top-level space is irrelevant (and we strip them anyway)
break;
+
default:
- throw new RuntimeException("unknown token type " + t.getType());
+ throw new RuntimeException("unknown token type " + t);
}
}
Expr expr = buf.takePendingExpr();
if(expr == null) {
- throw new IllegalArgumentException("No expression found?");
+ throw new IllegalArgumentException("No expression found? " + buf);
}
return expr;
}
+ private static Expr parseObjectReference(Token firstTok, TokBuf buf) {
+
+ // object references may be joined by '.' or '!';
+ List<String> objNames = new ArrayList<String>();
+ objNames.add(firstTok.getValueStr());
+
+ Token t = null;
+ boolean atSep = false;
+ while((t = buf.peekNext()) != null) {
+ if(!atSep) {
+ if(isOp(t, ".") || isOp(t, "!")) {
+ buf.next();
+ atSep = true;
+ continue;
+ }
+ } else {
+ if((t.getType() == TokenType.OBJ_NAME) ||
+ (t.getType() == TokenType.STRING)) {
+ buf.next();
+ objNames.add(t.getValueStr());
+ atSep = false;
+ continue;
+ }
+ }
+ break;
+ }
+
+ if(atSep) {
+ throw new IllegalArgumentException("Invalid object reference " + buf);
+ }
+
+ return new EObjValue(objNames);
+ }
+
private static Expr maybeParseFuncCall(Token firstTok, TokBuf buf,
Type exprType, boolean isSimpleExpr) {
}
}
- return new EFunc((String)firstTok.getValue(), params);
+ return new EFunc(firstTok.getValueStr(), params);
} finally {
if(!foundFunc) {
for(TokBuf paramBuf : params) {
if(!paramBuf.hasNext()) {
throw new IllegalArgumentException(
- "Invalid empty parameter for function");
+ "Invalid empty parameter for function " + paramBuf);
}
}
}
}
throw new IllegalArgumentException("Missing closing '" + FUNC_END_DELIM +
- "' for function call");
+ "' for function call " + buf);
}
private static boolean isSimpleExpression(TokBuf buf, Type exprType) {
}
private static boolean isOp(Token t, String opStr) {
- return ((t.getType() == TokenType.OP) &&
- opStr.equalsIgnoreCase((String)t.getValue()));
+ return ((t.getType() == TokenType.OP) && opStr.equalsIgnoreCase(t.getValueStr()));
}
private static WordType getWordType(Token t) {
- return WORD_TYPES.get(((String)t.getValue()).toLowerCase());
+ return WORD_TYPES.get(t.getValueStr().toLowerCase());
}
private static void setWordType(WordType type, String... words) {
private static final class TokBuf
{
private final List<Token> _tokens;
- private final boolean _topLevel;
+ private final TokBuf _parent;
private int _pos;
private Expr _pendingExpr;
private TokBuf(List<Token> tokens) {
- this(tokens, true);
+ this(tokens, null);
}
- private TokBuf(List<Token> tokens, boolean topLevel) {
+ private TokBuf(List<Token> tokens, TokBuf parent) {
_tokens = tokens;
- _topLevel = topLevel;
+ _parent = parent;
}
public boolean isTopLevel() {
- return _topLevel;
+ return (_parent == null);
}
public int curPos() {
}
public TokBuf subBuf(int start, int end) {
- return new TokBuf(_tokens.subList(start, end), false);
+ return new TokBuf(_tokens.subList(start, end), this);
}
public void setPendingExpr(Expr expr) {
if(_pendingExpr == null) {
- throw new IllegalArgumentException("Found multiple expressions with no operator");
+ throw new IllegalArgumentException(
+ "Found multiple expressions with no operator " + this);
}
_pendingExpr = expr;
}
public boolean hasPendingExpr() {
return (_pendingExpr != null);
}
+
+ @Override
+ public String toString() {
+ // FIXME show current pos
+ return null;
+ }
}
public static abstract class Expr
}
}
- private static final class EColumnValue extends Expr
+ private static final class EObjValue extends Expr
{
- private final String _colName;
+ private final List<String> _objNames;
- private EColumnValue(String colName) {
- _colName = colName;
+ private EObjValue(List<String> objNames) {
+ _objNames = objNames;
}
@Override
public Object eval(RowContext ctx) {
- return ctx.getRowValue(_colName);
+ // FIXME
+ return null;
+ // return ctx.getRowValue(_colName);
}
}