package eu.wietsevenema.lang.oberon.tests;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import org.junit.Test;
import xtc.tree.Node;
import eu.wietsevenema.lang.oberon.ast.visitors.interpreter.ModuleEvaluator;
import eu.wietsevenema.lang.oberon.ast.visitors.interpreter.ModulePrinter;
import eu.wietsevenema.lang.oberon.exceptions.InvalidInputException;
import eu.wietsevenema.lang.oberon.exceptions.ParseException;
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.values.IntegerValue;
public class ParserTest {
@Test
public void testProcedureCall() throws IOException, InvalidInputException, ParseException {
Node result = Util.parseModuleFile(Util.getAbsFilename("oberon/parser/procedurecall.o0"));
ModulePrinter printer = new ModulePrinter();
String actual = (String) printer.dispatch(result);
assertEquals("Module[Procedure,Declarations[{},{},{},{}],{" + "ProcedureCallStatement[Procedure1,{}],"
+ "ProcedureCallStatement[Procedure2,{}],"
+ "ProcedureCallStatement[Procedure3,{a,1,AdditiveExpression[a,2]}]}]", actual);
}
@Test
public void testProcedureDecl() throws IOException, InvalidInputException, ParseException {
Node result = Util.parseModuleFile(Util.getAbsFilename("oberon/parser/proceduredef.o0"));
ModulePrinter printer = new ModulePrinter();
String actual = (String) printer.dispatch(result);
String expected = "Module[Procedure,Declarations[{},{},{}," + "{ProcedureDecl[test,"
+ "{FormalVarRef[i,INTEGER],FormalVarRef[k,INTEGER],FormalVar[x,BOOLEAN],FormalVar[y,BOOLEAN]},"
+ "Declarations[{},{},{VarDecl[{t},INTEGER],VarDecl[{q,r},BOOLEAN]},{}],"
+ "{AssignmentStatement[i,0]}],"
+ "ProcedureDecl[test2,{},Declarations[{},{},{VarDecl[{x},INTEGER]},{}],{}]" + "}],{}]";
assertEquals(expected, actual);
}
@Test
public void testWhileStatement() throws IOException, InvalidInputException, ParseException {
Node result = Util.parseModuleFile(Util.getAbsFilename("oberon/parser/whilestatement.o0"));
ModulePrinter printer = new ModulePrinter();
String actual = (String) printer.dispatch(result);
String expected = "Module[While,Declarations[{},{},{VarDecl[{t1},INTEGER],VarDecl[{t2},BOOLEAN]},{}],{"
+ "WhileStatement[LessOrEqualExpression[t1,5],{"
+ "AssignmentStatement[t,AdditiveExpression[t,1]],AssignmentStatement[t2,true]" + "}]" + "}]";
assertEquals(expected, actual);
}
@Test
public void testSwapProcedure() throws IOException, InvalidInputException, ParseException, ValueUndefinedException,
SymbolNotDeclaredException {
Node result = Util.parseModuleFile(Util.getAbsFilename("oberon/swap.o0"));
InterpreterScope st = new InterpreterScope();
ModuleEvaluator me = new ModuleEvaluator(st);
me.dispatch(result);
/*
* x := 1; y := 2; Swap(x, y)
*/
assertEquals(new Integer(2), ((IntegerValue) st.lookupValue("x")).getValue());
assertEquals(new Integer(1), ((IntegerValue) st.lookupValue("y")).getValue());
}
@Test
public void testAllOperatorsGetParsed() throws IOException, InvalidInputException, ParseException {
Util.parseExpressionFile(Util.getAbsFilename("oberon/expr/allops.expr"));
}
@Test
public void testAdditionOpsLeftAssoc() throws IOException, InvalidInputException, ParseException {
Node result = Util.parseExpressionFile(Util.getAbsFilename("oberon/expr/additionopsleftassoc.expr"));
ModulePrinter printer = new ModulePrinter();
String actual = (String) printer.dispatch(result);
assertEquals("AdditiveExpression[SubtractiveExpression[AdditiveExpression[2,3],1],41]", actual);
}
@Test(expected = ParseException.class)
public void testEqualityOpsNotChainable() throws IOException, InvalidInputException, ParseException {
Node result = Util.parseExpressionFile(Util.getAbsFilename("oberon/expr/equalityops.expr"));
ModulePrinter printer = new ModulePrinter();
printer.dispatch(result);
}
@Test
public void testMultiplicationOpsLeftAssoc() throws IOException, InvalidInputException, ParseException {
Node result = Util.parseExpressionFile(Util.getAbsFilename("oberon/expr/multiplicationopsleftassoc.expr"));
ModulePrinter printer = new ModulePrinter();
String actual = (String) printer.dispatch(result);
assertEquals("ModulusExpression[DivisiveExpression[MultiplicativeExpression[2,3],666],12]", actual);
}
@Test
public void testParenthesisedOpsBind() throws IOException, InvalidInputException, ParseException {
Node result = Util.parseExpressionFile(Util.getAbsFilename("oberon/expr/parenthesisedopsbind.expr"));
ModulePrinter printer = new ModulePrinter();
String actual = (String) printer.dispatch(result);
assertEquals(
"GreaterOrEqualExpression[LessExpression[SubtractiveExpression[AdditiveExpression[2,1],4],false],3]",
actual);
}
@Test
public void testPrecedenceOrder() throws IOException, InvalidInputException, ParseException {
// 1 # 1 + 1 DIV 1 & 1 OR 1 ~ 1
Node result = Util.parseExpressionFile(Util.getAbsFilename("oberon/expr/precedence.expr"));
ModulePrinter printer = new ModulePrinter();
String actual = (String) printer.dispatch(result);
String expected = "NotExpression[1,LogicalDisjunctiveExpression["
+ "AdditiveExpression[1,LogicalConjunctiveExpression["
+ "DivisiveExpression[1,1],1]],LogicalNegationExpression[1]]]";
assertEquals(expected, actual);
}
@Test
public void testUnaryMin() throws IOException, InvalidInputException, ParseException {
// -3 * 2 bind als -(3*2)!!
Node unaryMinLhs = Util.parseExpressionFile(Util.getAbsFilename("oberon/expr/unarymin.expr"));
ModulePrinter printer = new ModulePrinter();
String actual = (String) printer.dispatch(unaryMinLhs);
assertEquals("UnaryMinExpression[MultiplicativeExpression[3,2]]", actual);
}
@Test
public void arraySelectorTest() throws InvalidInputException, ParseException, IOException {
ModulePrinter printer = new ModulePrinter();
Node result = Util.parseExpressionString("a[1][2+3]");
String actual = (String) printer.dispatch(result);
assertEquals("ArraySelector[ArraySelector[a,1],AdditiveExpression[2,3]]", actual);
result = Util.parseExpressionString("a[b]");
actual = (String) printer.dispatch(result);
assertEquals("ArraySelector[a,b]", actual);
}
@Test(expected = ParseException.class)
public void emptyArraySelectorTest() throws InvalidInputException, ParseException, IOException {
Util.parseExpressionString("a[]");
}
@Test
public void testTypeAlias() throws IOException, InvalidInputException, ParseException {
Node result = Util.parseModuleFile(Util.getAbsFilename("oberon/parser/typealias.o0"));
ModulePrinter printer = new ModulePrinter();
String actual = (String) printer.dispatch(result);
String expected = "Module[TypeAlias,Declarations[{},{TypeDecl[myType,INTEGER],TypeDecl[secondType,BOOLEAN]},"
+ "{VarDecl[{a},myType]},{}],{AssignmentStatement[a,999]}]";
assertEquals(expected, actual);
}
@Test
public void testRecordType() throws IOException, InvalidInputException, ParseException {
Node result = Util.parseModuleFile(Util.getAbsFilename("oberon/parser/record.o0"));
ModulePrinter printer = new ModulePrinter();
String actual = (String) printer.dispatch(result);
String expected = "Module[Record,Declarations[{},{},{VarDecl[{globalPerson},"
+ "RecordType[{Age:INTEGER,Length:INTEGER,Subscribed:BOOLEAN}]],"
+ "VarDecl[{input},INTEGER]},"
+ "{ProcedureDecl[test,{FormalVarRef[person,RecordType[{Age:INTEGER,Length:INTEGER,Subscribed:BOOLEAN}]]},"
+ "Declarations[{},{},{},{}],{" + "AssignmentStatement[RecordSelector[person,Age],18],"
+ "AssignmentStatement[RecordSelector[person,Length],188],"
+ "AssignmentStatement[RecordSelector[person,Subscribed],false]}]}],"
+ "{AssignmentStatement[RecordSelector[globalPerson,Age],0],"
+ "AssignmentStatement[RecordSelector[globalPerson,Length],0],"
+ "AssignmentStatement[RecordSelector[globalPerson,Subscribed],false]}]";
assertEquals(expected, actual);
}
@Test
public void testWithStatement() throws IOException, InvalidInputException, ParseException {
Node result = Util.parseModuleFile(Util.getAbsFilename("oberon/parser/with.o0"));
ModulePrinter printer = new ModulePrinter();
String actual = (String) printer.dispatch(result);
String expected = "Module[With,Declarations[{},{},{},{}],{WithStatement[arecord,{"
+ "AssignmentStatement[member1,AdditiveExpression[2,2]]," + "AssignmentStatement[member2,false]}"
+ "]}]";
assertEquals(expected, actual);
}
}