/*
* System.out.flush(); (new Exception("expr(" + priority +
* ") called")).printStackTrace(); System.err.flush();
*/
Token tok = expr_token(true);
ExprOrValue lhs;
// System.out.println("Expr lhs token is " + tok);
switch (tok.getType()) {
case Token.P_FEATUREEXPR:
// only found internally: generated FeatureExprToken
assert tok instanceof FeatureExprToken;
assert expectExpr;
lhs = new ExprOrValue(((FeatureExprToken) tok).getExpr());
break;
case '(':
lhs = parse_featureExprOrValue(0, expectExpr);
tok = expr_token(true);
if (tok.getType() != ')') {
expr_untoken(tok);
error(tok, "missing ) in expression after " + lhs + ", found "
+ tok + " instead");
return new ExprOrValue(FeatureExprLib.False(), FeatureExprLib.zero());
}
break;
case '~':
lhs = new ExprOrValue(FeatureExprLib.l().createComplement(parse_featureExprOrValue(11, false).assumeValue(tok)));
break;
case '!':
lhs = new ExprOrValue(parse_featureExprOrValue(11, true).assumeExpression(tok).not());
break;
case '-':
lhs = new ExprOrValue(FeatureExprLib.l().createNeg(parse_featureExprOrValue(11, false).assumeValue(tok)));
break;
case '+':
lhs = new ExprOrValue((parse_featureExprOrValue(11, false).assumeValue(tok)));
break;
case INTEGER:
lhs = new ExprOrValue(FeatureExprLib.l().createInteger(
((Number) tok.getValue()).longValue()));
break;
case CHARACTER:
lhs = new ExprOrValue(FeatureExprLib.l()
.createCharacter((Character) tok.getValue()));
break;
case IDENTIFIER:
if (tok.getText().equals("___BASE___")) //XXX: False code?
lhs = new ExprOrValue(FeatureExprLib.True());
else if (tok.getText().equals("___DEAD___")) //XXX: False code?
lhs = new ExprOrValue(FeatureExprLib.False());
else if (tok.getText().equals("__IF__")) {
lhs = new ExprOrValue(parse_ifExpr(tok));
} else if (tok.getText().equals("defined")) {
lhs = new ExprOrValue(parse_definedExpr(false));
} else if (tok.getText().equals("definedEx")) {
lhs = new ExprOrValue(parse_definedExpr(true));
} else {
if (isPotentialFlag(tok.getText())
&& warnings.contains(Warning.UNDEF))
warning(tok, "Undefined token '" + tok.getText()
+ "' encountered in conditional.");
lhs = new ExprOrValue(FeatureExprLib.False(), FeatureExprLib.zero());
}
break;
default:
expr_untoken(tok);
error(tok, "Bad token in expression: " + getTextOrDefault(tok, "<Feature Expression>"));
return new ExprOrValue(FeatureExprLib.False(), FeatureExprLib.zero());
}
EXPR:
for (; ; ) {
// System.out.println("expr: lhs is " + lhs + ", pri = " +
// priority);
Token op = expr_token(true);
int pri = expr_priority(op); /* 0 if not a binop. */
if (pri == 0 || priority >= pri) {
expr_untoken(op);
break EXPR;
}
// System.out.println("rhs token is " + rhs);
switch (op.getType()) {
case '/':
lhs = new ExprOrValue(FeatureExprLib.l().createDivision(lhs.assumeValue(tok), parse_featureExprOrValue(pri, false).assumeValue(tok)));
// if (rhs == 0) {
// error(op, "Division by zero");
// lhs = 0;
// } else {
// lhs = lhs / rhs;
// }
break;
case '%':
lhs = new ExprOrValue(FeatureExprLib.l().createModulo(lhs.assumeValue(tok), parse_featureExprOrValue(pri, false).assumeValue(tok)));
// if (rhs == 0) {
// error(op, "Modulus by zero");
// lhs = 0;
// } else {
// lhs = lhs % rhs;
// }
break;
case '*':
lhs = new ExprOrValue(FeatureExprLib.l().createMult(lhs.assumeValue(tok), parse_featureExprOrValue(pri, false).assumeValue(tok)));
break;
case '+':
lhs = new ExprOrValue(FeatureExprLib.l().createPlus(lhs.assumeValue(tok), parse_featureExprOrValue(pri, false).assumeValue(tok)));
break;
case '-':
lhs = new ExprOrValue(FeatureExprLib.l().createMinus(lhs.assumeValue(tok), parse_featureExprOrValue(pri, false).assumeValue(tok)));
break;
case '<':
lhs = new ExprOrValue(FeatureExprLib.l().createLessThan(lhs.assumeValue(tok), parse_featureExprOrValue(pri, false).assumeValue(tok)));
// lhs < rhs ? 1 : 0;
break;
case '>':
lhs = new ExprOrValue(FeatureExprLib.l().createGreaterThan(lhs.assumeValue(tok), parse_featureExprOrValue(pri, false).assumeValue(tok)));// lhs >
// rhs ?
// 1 : 0;
break;
case '&':
lhs = new ExprOrValue(FeatureExprLib.l().createBitAnd(lhs.assumeValue(tok), parse_featureExprOrValue(pri, false).assumeValue(tok)));// lhs & rhs;
break;
case '^':
lhs = new ExprOrValue(FeatureExprLib.l().createPwr(lhs.assumeValue(tok), parse_featureExprOrValue(pri, false).assumeValue(tok)));// lhs ^ rhs;
break;
case '|':
lhs = new ExprOrValue(FeatureExprLib.l().createBitOr(lhs.assumeValue(tok), parse_featureExprOrValue(pri, false).assumeValue(tok)));// lhs | rhs;
break;
case LSH:
lhs = new ExprOrValue(FeatureExprLib.l().createShiftLeft(lhs.assumeValue(tok), parse_featureExprOrValue(pri, false).assumeValue(tok)));// lhs <<
// rhs;
break;
case RSH:
lhs = new ExprOrValue(FeatureExprLib.l().createShiftRight(lhs.assumeValue(tok), parse_featureExprOrValue(pri, false).assumeValue(tok)));// lhs >>
// rhs;
break;
case LE:
lhs = new ExprOrValue(FeatureExprLib.l().createLessThanEquals(lhs.assumeValue(tok), parse_featureExprOrValue(pri, false).assumeValue(tok)));// lhs
// <=
// rhs ?
// 1 :
// 0;
break;
case GE:
lhs = new ExprOrValue(FeatureExprLib.l().createGreaterThanEquals(lhs.assumeValue(tok), parse_featureExprOrValue(pri, false).assumeValue(tok)));// lhs
// >=
// rhs ?
// 1 :
// 0;
break;
case EQ:
lhs = new ExprOrValue(FeatureExprLib.l().createEquals(lhs.assumeValue(tok), parse_featureExprOrValue(pri, false).assumeValue(tok)));// lhs == rhs
// ?
// 1 :
// 0;
break;
case NE:
lhs = new ExprOrValue(FeatureExprLib.l().createNotEquals(lhs.assumeValue(tok), parse_featureExprOrValue(pri, false).assumeValue(tok)));// lhs !=
// rhs
// ?
// 1 : 0;
break;
case LAND:
lhs = new ExprOrValue(lhs.assumeExpression(tok).and(parse_featureExprOrValue(pri, true).assumeExpression(tok)));// (lhs != 0) && (rhs
// != 0) ? 1 : 0;
break;
case LOR:
lhs = new ExprOrValue(lhs.assumeExpression(tok).or(parse_featureExprOrValue(pri, true).assumeExpression(tok)));// (lhs != 0) || (rhs
// != 0) ? 1 : 0;
break;
case '?':
lhs = parse_qifExpr(lhs.assumeExpression(tok), tok);
break;
default:
error(op, "Unexpected operator " + op.getText());
return new ExprOrValue(FeatureExprLib.False(), FeatureExprLib.zero());
}
}