package nl.uva.se.ql.evaluation; import nl.uva.se.ql.ast.form.Form; import nl.uva.se.ql.ast.form.FormVisitor; import nl.uva.se.ql.ast.statement.CalculatedQuestion; import nl.uva.se.ql.ast.statement.Condition; import nl.uva.se.ql.ast.statement.Question; import nl.uva.se.ql.ast.statement.StatementVisitor; import nl.uva.se.ql.ast.type.BooleanType; import nl.uva.se.ql.ast.type.DecimalType; import nl.uva.se.ql.ast.type.IntegerType; import nl.uva.se.ql.ast.type.StringType; import nl.uva.se.ql.ast.type.Type; import nl.uva.se.ql.ast.type.TypeVisitor; import nl.uva.se.ql.ast.type.UndefinedType; import nl.uva.se.ql.evaluation.value.Value; public class Evaluator implements FormVisitor, StatementVisitor, TypeVisitor<Value> { private ValueTable values; private Value currentValue; private Evaluator() { values = new ValueTable(); } private Evaluator(ValueTable values) { this.values = values; } public static ValueTable evaluate(Form form, ValueTable values) { Evaluator evaluator = new Evaluator(values); form.accept(evaluator); return evaluator.values; } public void visit(Form form) { form.visitChildren(this); } public void visit(Question question) { if (values.containsKey(question.getId())) { values.addValue(question.getId(), values.getValue(question.getId())); } else { Type questionType = question.getType(); values.addValue(question.getId(), questionType.getDefaultValue()); } } public void visit(CalculatedQuestion calculatedQuestion) { Value exprValue = ExpressionEvaluator.evaluate(calculatedQuestion.getExpression(), values); currentValue = exprValue; Type questionType = calculatedQuestion.getType(); Value promotedValue = questionType.accept(this); values.addValue(calculatedQuestion.getId(), promotedValue); } public void visit(Condition condition) { condition.visitChildren(this); } @Override public Value visit(BooleanType booleanType) { return currentValue; } @Override public Value visit(DecimalType decimalType) { return currentValue.promote(); } @Override public Value visit(IntegerType integerType) { return currentValue; } @Override public Value visit(StringType stringType) { return currentValue; } @Override public Value visit(UndefinedType undefinedType) { return currentValue; } }