package eu.wietsevenema.lang.oberon.ast.visitors.interpreter; import xtc.tree.Visitor; import eu.wietsevenema.lang.oberon.ast.declarations.RecordSelector; import eu.wietsevenema.lang.oberon.ast.expressions.ArraySelector; import eu.wietsevenema.lang.oberon.ast.expressions.Identifier; import eu.wietsevenema.lang.oberon.exceptions.SymbolNotDeclaredException; import eu.wietsevenema.lang.oberon.exceptions.ValueUndefinedException; import eu.wietsevenema.lang.oberon.interpreter.InterpreterScope; import eu.wietsevenema.lang.oberon.interpreter.ValueReference; import eu.wietsevenema.lang.oberon.interpreter.values.ArrayValue; import eu.wietsevenema.lang.oberon.interpreter.values.IntegerValue; import eu.wietsevenema.lang.oberon.interpreter.values.RecordValue; public class ValueReferenceResolver extends Visitor { private InterpreterScope scope; public ValueReferenceResolver(InterpreterScope scope) { this.scope = scope; } public ValueReference visit(Identifier id) throws SymbolNotDeclaredException { return scope.lookupValueReference(id.getName()); } public ValueReference visit(ArraySelector selector) throws ValueUndefinedException { // 1. Get reference to left ArrayValue. ExpressionEvaluator exprEval = new ExpressionEvaluator(scope); ArrayValue left = (ArrayValue) exprEval.dispatch(selector.getLeft()); // 2. Evaluate right side to get index IntegerValue index = (IntegerValue) exprEval.dispatch(selector.getIndex()); return left.getReference(index.getValue()); } public ValueReference visit(RecordSelector selector) throws ValueUndefinedException { ExpressionEvaluator exprEval = new ExpressionEvaluator(scope); RecordValue record = (RecordValue) exprEval.dispatch(selector.getLeft()); return record.getReference(selector.getKey()); } }