package synthesijer.ast; import synthesijer.ast.expr.Literal; import synthesijer.ast.type.PrimitiveTypeKind; public class SimpleEvaluator { interface MathBiFunction<E>{ E operation(E a, E b); } interface CompareBiFunction<E>{ boolean operation(E a, E b); } interface UniFunction<E>{ E operation(E a); } public static Literal eval(Op op, Type t0, String v0) throws SynthesijerAstException{ UniFunction<Double> floatFunc = null; UniFunction<Long> intFunc = null; UniFunction<Boolean> boolFunc = null; switch(op){ case ASSIGN: floatFunc = (a) -> a; intFunc = (a) -> a; boolFunc = (a) -> a; break; case MINUS: case MMMINUS: floatFunc = (a) -> -a; intFunc = (a) -> -a; break; case NOT: intFunc = (a) -> ~a; break; case LNOT: boolFunc = (a) -> !a; break; case INC: floatFunc = (a) -> a+1; intFunc = (a) -> a+1; break; case DEC: floatFunc = (a) -> a-1; intFunc = (a) -> a-1; break; default: throw new SynthesijerAstException(); } long la = 0L, lc = 0L; double da = 0d, dc = 0d; boolean ba = false, bc = false; boolean floatFlag = false; boolean booleanFlag = false; if(t0 == PrimitiveTypeKind.FLOAT || t0 == PrimitiveTypeKind.DOUBLE){ da = Double.parseDouble(v0); floatFlag = true; }else if(t0 == PrimitiveTypeKind.BOOLEAN){ ba = Boolean.parseBoolean(v0); booleanFlag = true; }else{ la = Long.parseLong(v0); } Literal result = new Literal(null); if(booleanFlag){ bc = boolFunc.operation(ba); result.setValue(bc); }else if(floatFlag){ dc = floatFunc.operation(da); result.setValue(dc); }else{ lc = intFunc.operation(la); result.setValue(lc); } return result; } public static Literal eval(Op op, Type t0, String v0, Type t1, String v1) throws SynthesijerAstException{ MathBiFunction<Double> floatFunc = null; MathBiFunction<Long> intFunc = null; CompareBiFunction<Double> floatCompare = null; CompareBiFunction<Long> intCompare = null; CompareBiFunction<Boolean> boolCompare = null; boolean mathFunc = false; boolean compareFunc = false; switch(op){ case PLUS: floatFunc = (a, b) -> a + b; intFunc = (a, b) -> a + b; mathFunc = true; break; case MINUS: floatFunc = (a, b) -> a - b; intFunc = (a, b) -> a - b; mathFunc = true; break; case MUL: floatFunc = (a, b) -> a * b; intFunc = (a, b) -> a * b; mathFunc = true; break; case DIV: floatFunc = (a, b) -> a / b; intFunc = (a, b) -> a / b; mathFunc = true; break; case MOD: floatFunc = (a, b) -> a % b; intFunc = (a, b) -> a % b; mathFunc = true; break; case COMPEQ: floatCompare = (a, b) -> a == b; intCompare = (a, b) -> a == b; boolCompare = (a, b) -> a == b; compareFunc = true; break; case NEQ: floatCompare = (a, b) -> a != b; intCompare = (a, b) -> a != b; boolCompare = (a, b) -> a != b; compareFunc = true; break; case GT: floatCompare = (a, b) -> a > b; intCompare = (a, b) -> a > b; compareFunc = true; break; case GEQ: floatCompare = (a, b) -> a >= b; intCompare = (a, b) -> a >= b; compareFunc = true; break; case LT: floatCompare = (a, b) -> a < b; intCompare = (a, b) -> a < b; compareFunc = true; break; case LEQ: floatCompare = (a, b) -> a <= b; intCompare = (a, b) -> a <= b; compareFunc = true; break; case LSHIFT: intFunc = (a, b) -> a << b; mathFunc = true; break; case LOGIC_RSHIFT: intFunc = (a, b) -> a >>> b; mathFunc = true; break; case ARITH_RSHIFT: intFunc = (a, b) -> a >> b; mathFunc = true; break; case AND: intFunc = (a, b) -> a & b; boolCompare = (a, b) -> a & b; mathFunc = true; break; case LAND: boolCompare = (a, b) -> a && b; break; case LOR: boolCompare = (a, b) -> a || b; break; case OR: intFunc = (a, b) -> a | b; boolCompare = (a, b) -> a | b; mathFunc = true; break; case XOR: intFunc = (a, b) -> a ^ b; boolCompare = (a, b) -> a ^ b; mathFunc = true; break; default: throw new SynthesijerAstException(); } long la = 0L, lb = 0L, lc = 0L; double da = 0d, db = 0d, dc = 0d; boolean ba = false, bb = false, bc = false; boolean floatFlag = false; boolean booleanFlag = false; if(t0 == PrimitiveTypeKind.FLOAT || t0 == PrimitiveTypeKind.DOUBLE || t1 == PrimitiveTypeKind.FLOAT || t1 == PrimitiveTypeKind.DOUBLE){ da = Double.parseDouble(v0); db = Double.parseDouble(v1); floatFlag = true; }else if(t0 == PrimitiveTypeKind.BOOLEAN || t1 == PrimitiveTypeKind.BOOLEAN){ ba = Boolean.parseBoolean(v0); bb = Boolean.parseBoolean(v1); booleanFlag = true; }else{ la = Long.parseLong(v0); lb = Long.parseLong(v1); } Literal result = new Literal(null); if(booleanFlag){ bc = boolCompare.operation(ba, bb); result.setValue(bc); }else if(floatFlag){ if(mathFunc){ dc = floatFunc.operation(da, db); result.setValue(dc); }else{ bc = floatCompare.operation(da, db); result.setValue(bc); } }else{ if(mathFunc){ lc = intFunc.operation(la, lb); result.setValue(lc); }else{ bc = intCompare.operation(la, lb); result.setValue(bc); } } return result; } public static void main(String... args) throws Exception{ System.out.println(eval(Op.PLUS, PrimitiveTypeKind.INT, "10", PrimitiveTypeKind.INT, "20")); System.out.println(eval(Op.PLUS, PrimitiveTypeKind.DOUBLE, "10.1", PrimitiveTypeKind.FLOAT, "20.2")); System.out.println(eval(Op.MINUS, PrimitiveTypeKind.DOUBLE, "10.1", PrimitiveTypeKind.FLOAT, "20.2")); } }