package eu.wietsevenema.lang.oberon.tests; import static org.junit.Assert.assertEquals; import java.io.IOException; import java.util.ArrayList; import org.junit.Before; import org.junit.Test; import xtc.tree.VisitingException; import eu.wietsevenema.lang.oberon.ast.declarations.Module; import eu.wietsevenema.lang.oberon.ast.expressions.AdditiveExpression; import eu.wietsevenema.lang.oberon.ast.expressions.BooleanConstant; import eu.wietsevenema.lang.oberon.ast.expressions.Expression; import eu.wietsevenema.lang.oberon.ast.expressions.Identifier; import eu.wietsevenema.lang.oberon.ast.expressions.IntegerConstant; import eu.wietsevenema.lang.oberon.ast.expressions.LessExpression; import eu.wietsevenema.lang.oberon.ast.statements.AssignmentStatement; import eu.wietsevenema.lang.oberon.ast.statements.ProcedureCallStatement; import eu.wietsevenema.lang.oberon.ast.statements.Statement; import eu.wietsevenema.lang.oberon.ast.statements.WhileStatement; import eu.wietsevenema.lang.oberon.ast.visitors.interpreter.ModuleEvaluator; import eu.wietsevenema.lang.oberon.ast.visitors.interpreter.StatementEvaluator; import eu.wietsevenema.lang.oberon.exceptions.InvalidInputException; import eu.wietsevenema.lang.oberon.exceptions.ParseException; import eu.wietsevenema.lang.oberon.exceptions.SymbolAlreadyDeclaredException; import eu.wietsevenema.lang.oberon.exceptions.SymbolNotDeclaredException; import eu.wietsevenema.lang.oberon.exceptions.ValueUndefinedException; import eu.wietsevenema.lang.oberon.interpreter.Environment; import eu.wietsevenema.lang.oberon.interpreter.InterpreterScope; import eu.wietsevenema.lang.oberon.interpreter.values.BooleanValue; import eu.wietsevenema.lang.oberon.interpreter.values.IntegerValue; public class StatementEvaluatorTest { private InterpreterScope scope; @Before public void setUp() { this.scope = new InterpreterScope(); } @Test public void testAssignment() throws SymbolAlreadyDeclaredException, ValueUndefinedException, SymbolNotDeclaredException { // Declare vars scope.declareValue("a", new IntegerValue(null)); scope.declareValue("b", new BooleanValue(null)); // Construct assignment statements AssignmentStatement as1 = new AssignmentStatement(new Identifier("a"), new IntegerConstant(2)); AssignmentStatement as2 = new AssignmentStatement(new Identifier("b"), new BooleanConstant(true)); StatementEvaluator se = new StatementEvaluator(scope); se.dispatch(as1); se.dispatch(as2); assertEquals(((IntegerValue) scope.lookupValue("a")).getValue(), new Integer(2)); assertEquals(((BooleanValue) scope.lookupValue("b")).getValue(), new Boolean(true)); } @Test public void testSecondAssignment() throws ValueUndefinedException, SymbolNotDeclaredException, SymbolAlreadyDeclaredException { scope.declareValue("a", new IntegerValue(null)); AssignmentStatement first = new AssignmentStatement(new Identifier("a"), new IntegerConstant(2)); AssignmentStatement second = new AssignmentStatement(new Identifier("a"), new IntegerConstant(3)); StatementEvaluator se = new StatementEvaluator(scope); se.dispatch(first); assertEquals(((IntegerValue) scope.lookupValue("a")).getValue(), new Integer(2)); se.dispatch(second); assertEquals(((IntegerValue) scope.lookupValue("a")).getValue(), new Integer(3)); } @Test(expected = SymbolNotDeclaredException.class) public void testCallNotExistingProcedureFails() throws Throwable { Statement call = new ProcedureCallStatement(new Identifier("idonotexist"), new ArrayList<Expression>()); StatementEvaluator statEval = new StatementEvaluator(scope); try { statEval.dispatch(call); } catch (VisitingException e) { throw e.getCause(); } } @Test public void testWhileStatement() throws SymbolAlreadyDeclaredException, ValueUndefinedException, SymbolNotDeclaredException { Expression condition = new LessExpression(new Identifier("count"), new IntegerConstant(5)); Statement stat1 = new AssignmentStatement(new Identifier("count"), new AdditiveExpression(new Identifier( "count"), new IntegerConstant(1))); Statement stat2 = new AssignmentStatement(new Identifier("touch"), new BooleanConstant(true)); ArrayList<Statement> statements = new ArrayList<Statement>(); statements.add(stat1); statements.add(stat2); WhileStatement whilestat = new WhileStatement(condition, statements); scope.declareValue("count", new IntegerValue(0)); scope.declareValue("touch", new BooleanValue(false)); StatementEvaluator eval = new StatementEvaluator(scope); eval.dispatch(whilestat); assertEquals(new Integer(5), ((IntegerValue) scope.lookupValue("count")).getValue()); assertEquals(new Boolean(true), ((BooleanValue) scope.lookupValue("touch")).getValue()); } @Test public void testWhileStatement2() throws InvalidInputException, ParseException, IOException, ValueUndefinedException, SymbolNotDeclaredException { String whileprog = "MODULE While; " + " VAR t1: INTEGER; t2 : BOOLEAN;" + "BEGIN" + " t1 := 0;" + " WHILE t1 <= 5" + " DO" + " t1 := t1 + 1;" + " t2 := TRUE" + " END " + "END While."; ModuleEvaluator me = new ModuleEvaluator(scope); me.dispatch(Util.parseModuleString(whileprog)); assertEquals(new Boolean(true), ((BooleanValue) scope.lookupValue("t2")).getValue()); assertEquals(new Integer(6), ((IntegerValue) scope.lookupValue("t1")).getValue()); } @Test public void testIfStatement() throws IOException, InvalidInputException, ParseException, SymbolAlreadyDeclaredException { Module result = (Module) Util.parseModuleFile(Util.getAbsFilename("oberon/ifstatement.o0")); Environment env = new Environment(System.in, System.out); env.runModule(result); } @Test public void testWithStatement() throws IOException, InvalidInputException, ParseException, SymbolAlreadyDeclaredException { Module result = (Module) Util.parseModuleFile(Util.getAbsFilename("oberon/statements/with.o0")); Environment env = new Environment(System.in, System.out); env.runModule(result); } @Test public void testAssignStatement() throws IOException, InvalidInputException, ParseException, SymbolAlreadyDeclaredException { Module result = (Module) Util.parseModuleFile(Util.getAbsFilename("oberon/statements/assignment.o0")); Environment env = new Environment(System.in, System.out); env.runModule(result); } }