package de.gaalop.vis2d; import de.gaalop.cfg.AssignmentNode; import de.gaalop.cfg.ControlFlowGraph; import de.gaalop.cfg.EmptyControlFlowVisitor; import de.gaalop.dfg.*; import java.util.Arrays; import java.util.HashMap; /** * * @author Christian Steinmetz */ public class ValueEvaluater extends EmptyControlFlowVisitor implements ExpressionVisitor { private HashMap<String, double[]> values = new HashMap<String, double[]>(); private double resultValue; private ValueEvaluater() { } public static HashMap<String, double[]> evaluateValues(ControlFlowGraph graph) { ValueEvaluater valueEvaluater = new ValueEvaluater(); graph.accept(valueEvaluater); return valueEvaluater.values; } @Override public void visit(AssignmentNode node) { node.getValue().accept(this); MultivectorComponent mvC = (MultivectorComponent) node.getVariable(); double[] arrValues; if (values.containsKey(mvC.getName())) arrValues = values.get(mvC.getName()); else { arrValues = new double[16]; Arrays.fill(arrValues, 0); values.put(mvC.getName(), arrValues); } arrValues[mvC.getBladeIndex()] = resultValue; super.visit(node); } @Override public void visit(Subtraction node) { node.getLeft().accept(this); double leftValue = resultValue; node.getRight().accept(this); resultValue = leftValue-resultValue; } @Override public void visit(Addition node) { node.getLeft().accept(this); double leftValue = resultValue; node.getRight().accept(this); resultValue = leftValue+resultValue; } @Override public void visit(Division node) { node.getLeft().accept(this); double leftValue = resultValue; node.getRight().accept(this); resultValue = leftValue/resultValue; } @Override public void visit(InnerProduct node) { throw new IllegalStateException("InnerProducts should have been removed by TBA"); } @Override public void visit(Multiplication node) { node.getLeft().accept(this); double leftValue = resultValue; node.getRight().accept(this); resultValue = leftValue*resultValue; } @Override public void visit(MathFunctionCall node) { node.accept(this); double operandValue = resultValue; switch (node.getFunction()) { case ABS: resultValue = Math.abs(operandValue); break; case ACOS: resultValue = Math.acos(operandValue); break; case ASIN: resultValue = Math.asin(operandValue); break; case ATAN: resultValue = Math.atan(operandValue); break; case CEIL: resultValue = Math.ceil(operandValue); break; case COS: resultValue = Math.cos(operandValue); break; case EXP: resultValue = Math.exp(operandValue); break; case FACT: resultValue = 1; for (int i=2;i<=(int) operandValue;i++) resultValue *= i; break; case FLOOR: resultValue = Math.floor(operandValue); break; case LOG: resultValue = Math.log(operandValue); break; case SIN: resultValue = Math.sin(operandValue); break; case SQRT: resultValue = Math.sqrt(operandValue); break; case TAN: resultValue = Math.tan(operandValue); break; case INVERT: System.err.println("Inversions are not yet implemented in Vis2dCodeGen"); break; } } @Override public void visit(Variable node) { throw new IllegalStateException("Variables are not yet allowed in Vis2dCodeGen"); } @Override public void visit(MultivectorComponent node) { resultValue = values.get(node.getName())[node.getBladeIndex()]; } @Override public void visit(Exponentiation node) { node.getLeft().accept(this); double leftValue = resultValue; node.getRight().accept(this); resultValue = Math.pow(leftValue,resultValue); } @Override public void visit(FloatConstant node) { resultValue = node.getValue(); } @Override public void visit(OuterProduct node) { throw new IllegalStateException("OuterProducts should have been removed by TBA"); } @Override public void visit(BaseVector node) { throw new IllegalStateException("BaseVector should have been removed by TBA"); } @Override public void visit(Negation node) { node.getOperand().accept(this); resultValue = -resultValue; } @Override public void visit(Reverse node) { throw new IllegalStateException("Reverse should have been removed by TBA"); } @Override public void visit(LogicalOr node) { throw new IllegalStateException("LogicalOrs are not allowed in Vis2dCodeGen"); } @Override public void visit(LogicalAnd node) { throw new IllegalStateException("LogicalAnds are not allowed in Vis2dCodeGen"); } @Override public void visit(LogicalNegation node) { throw new IllegalStateException("LogicalNegations are not allowed in Vis2dCodeGen"); } @Override public void visit(Equality node) { throw new IllegalStateException("Equalities are not allowed in Vis2dCodeGen"); } @Override public void visit(Inequality node) { throw new IllegalStateException("Inequalities are not allowed in Vis2dCodeGen"); } @Override public void visit(Relation relation) { throw new IllegalStateException("Relations are not allowed in Vis2dCodeGen"); } @Override public void visit(FunctionArgument node) { throw new IllegalStateException("FunctionArguments are not allowed in Vis2dCodeGen"); } @Override public void visit(MacroCall node) { throw new IllegalStateException("MacroCalls are not allowed in Vis2dCodeGen"); } }