/** Compiles ParameterExpressions */ @Override public void visit(ParameterExpression param) { if (param == null) { throw new ArgumentException(PARAMETER + E_IS_NULL); } if (parameters.containsKey(param.getName())) { /** If the parameter itself is and expression */ if (parameters.get(param.getName()) instanceof ExpressionCompiler) { // The parameter is itself another Expression ExpressionCompiler expr = (ExpressionCompiler) parameters.get(param.getName()); expr.setParameters(parameters); expr.setMethodResolver(getMethodResolver()); expr.setParameterizedResolver(getParameterizedResolver()); // TODO: Need a way to pass in the compile type here, maybe from // global scope of API call for compile... result.setResult( (LogicalExpression) ((ExpressionCompiler) parameters.get(param.getName())).compile()); } else { result.setResult((LogicalExpression) parameters.get(param.getName())); } } else { ParameterizedArgs args = new ParameterizedArgs(result, param.getName()); resolveParameterizedReference(args); if (args.getResult() == null) throw new CompilationException( String.format(E_PARAMETER_S_WAS_NOT_DEFINED, param.getName())); result.setResult((LogicalExpression) args.getResult()); } }
/** Compiles MethodExpressions */ @Override public void visit(MethodExpression method) { if (method == null) { throw new ArgumentException(METHOD + E_IS_NULL); } LogicalExpression[] parameters = new LogicalExpression[method.getParameters().length]; for (int i = 0; i < parameters.length; i++) { parameters[i] = evaluate(method.getParameters()[i]); } MethodArgs args = new MethodArgs(method.getName()); args.setParameters(parameters); resolveMethod(args); // If an external implementation was found get the result back if (args.getResult() != null) { result.setResult((LogicalExpression) args.getResult()); return; } defaultMethodResolver.resolve(args); result.setResult((LogicalExpression) args.getResult()); }
/** Compiles UnaryExpression */ @Override public void visit(UnaryExpression expression) { if (expression == null) { throw new ArgumentException(EXPRESSION + E_IS_NULL); } expression.getExpression().accept(this); switch (expression.getType()) { case NOT: result.setResult(new Not(result.getResult())); break; case NEGATE: result.setResult(new Negate(result.getResult())); break; } }
/** Compiles ValueExpressions */ @Override public void visit(ValueExpression expression) { if (expression == null) { throw new ArgumentException(EXPRESSION + E_IS_NULL); } // FIXME: Treat all numerics as BigDecimal or better yet, MutableDecimal // Also - what other types must we handle? // BYTE? BYTEARRAY? CHARACTER? switch (expression.getType()) { case BOOLEAN: result.setResult( new Literal<Boolean>(ValueType.BOOLEAN, Boolean.parseBoolean(expression.getText()))); break; case DATETIME: result.setResult( new Literal<DateTime>( ValueType.DATETIME, // DateTime.parse(expression.getText().substring(1, // expression.getText().length() - 2)))); DateTime.parse(expression.getText()))); break; case INTEGER: case DECIMAL: result.setResult( new Literal<Double>(ValueType.DECIMAL, Convert.parseNumeric(expression.getText()))); break; case TEXT: result.setResult(new Literal<String>(ValueType.TEXT, expression.getText())); break; case VARIABLE: Variable var = new Variable(expression.getText()); // Record for easy update before compute result.addOrUpdateVariable(var); result.setResult(var); break; } }
@Override public void visit(AssignmentExpression assignment) { if (assignment == null) { throw new ArgumentException(ASSIGNMENT + E_IS_NULL); } /** processes the left hand expression and saves the value to result */ assignment.getLeft().accept(this); LogicalExpression left = result.getResult(); // LHS must always be a variable. if (!(left instanceof Variable)) { throw new ArgumentException(E_ASSIGNMENT_LHS_NOT_VARIABLE); } assignment.setLeft(left); /** processes the right hand expression and saves the value to result */ assignment.getRight().accept(this); assignment.setRight(result.getResult()); /** No magic here, just set the original instance */ result.setResult(assignment); }
/** Compiles BinaryExpressions */ @Override public void visit(BinaryExpression expression) { if (expression == null) { throw new ArgumentException(EXPRESSION + E_IS_NULL); } /** processes the left hand expression and saves the value to result */ expression.getLeft().accept(this); LogicalExpression left = result.getResult(); /** processes the right hand expression and saves the value to result */ expression.getRight().accept(this); LogicalExpression right = result.getResult(); switch (expression.getType()) { case AND: result.setResult(new And(left, right)); break; case OR: result.setResult(new Or(left, right)); break; case DIV: result.setResult(new Divide(left, right)); break; case EQ: result.setResult(new Equal(left, right)); break; case GT: result.setResult(new Greater(left, right)); break; case GTE: result.setResult(new GreaterEqual(left, right)); break; case LT: result.setResult(new Lesser(left, right)); break; case LTE: result.setResult(new LesserEqual(left, right)); break; case MINUS: result.setResult(new Minus(left, right)); break; case MOD: result.setResult(new Modulo(left, right)); break; case NE: result.setResult(new NotEqual(left, right)); break; case PLUS: result.setResult(new Plus(left, right)); break; case MULT: result.setResult(new Multiply(left, right)); break; case POW: result.setResult(new Power(left, right)); break; } }