Skip to content

Commit

Permalink
(37) fix errors in interpreter functions of eval, implemented and tes…
Browse files Browse the repository at this point in the history
…ted weelTyped and typeOf functions
  • Loading branch information
waltim committed Nov 6, 2019
1 parent fd02052 commit cf599d2
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 98 deletions.
14 changes: 7 additions & 7 deletions sample-code/oberon/src/lang/oberon/Interpreter.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -98,21 +98,21 @@ public Expression eval(Add(lhs, rhs), Context ctx) {
public Expression eval(Sub(lhs, rhs), Context ctx) {
switch(<eval(lhs, ctx), eval(rhs, ctx)>) {
case <IntValue(n), IntValue(m)> : return IntValue(n - m);
default : throw "Invalid Expression <Add(lhs, rhs)>";
default : throw "Invalid Expression <Sub(lhs, rhs)>";
}
}

public Expression eval(Mult(lhs, rhs), Context ctx) {
switch(<eval(lhs, ctx), eval(rhs, ctx)>) {
case <IntValue(n), IntValue(m)> : return IntValue(n * m);
default : throw "Invalid Expression <Add(lhs, rhs)>";
default : throw "Invalid Expression <Mult(lhs, rhs)>";
}
}

public Expression eval(Div(lhs, rhs), Context ctx) {
switch(<eval(lhs, ctx), eval(rhs, ctx)>) {
case <IntValue(n), IntValue(m)> : return IntValue(n / m);
default : throw "Invalid Expression <Add(lhs, rhs)>";
default : throw "Invalid Expression <Div(lhs, rhs)>";
}
}
Expand All @@ -126,7 +126,7 @@ public Expression eval(And(lhs, rhs), Context ctx) {
public Expression eval(Or(lhs, rhs), Context ctx) {
switch(<eval(lhs, ctx), eval(rhs, ctx)>) {
case <BoolValue(n), BoolValue(m)> : return BoolValue(n || m);
default : throw "Invalid Expression <And(lhs, rhs)>";
default : throw "Invalid Expression <Or(lhs, rhs)>";
}
}
Expand All @@ -141,7 +141,7 @@ public Expression eval(Gt(lhs, rhs), Context ctx) {
switch(<eval(lhs, ctx), eval(rhs, ctx)>) {
case <IntValue(n), IntValue(m)> : return BoolValue(n > m);
case <BoolValue(n), BoolValue(m)> : return BoolValue(n > m);
default : throw "Invalid Expression <Lt(lhs, rhs)>";
default : throw "Invalid Expression <Gt(lhs, rhs)>";
}
}
Expand All @@ -157,15 +157,15 @@ public Expression eval(GoEq(lhs, rhs), Context ctx) {
switch(<eval(lhs, ctx), eval(rhs, ctx)>) {
case <IntValue(n), IntValue(m)> : return BoolValue(n >= m);
case <BoolValue(n), BoolValue(m)> : return BoolValue(n >= m);
default : throw "Invalid Expression <Lt(lhs, rhs)>";
default : throw "Invalid Expression <GoEq(lhs, rhs)>";
}
}
public Expression eval(LoEq(lhs, rhs), Context ctx) {
switch(<eval(lhs, ctx), eval(rhs, ctx)>) {
case <IntValue(n), IntValue(m)> : return BoolValue(n <= m);
case <BoolValue(n), BoolValue(m)> : return BoolValue(n <= m);
default : throw "Invalid Expression <Lt(lhs, rhs)>";
default : throw "Invalid Expression <LoEq(lhs, rhs)>";
}
}
Expand Down
145 changes: 78 additions & 67 deletions sample-code/oberon/src/lang/oberon/TypeChecker.rsc
Original file line number Diff line number Diff line change
@@ -1,162 +1,173 @@
module lang::oberon::TypeChecker

import lang::oberon::AST;
import lang::util::Stack;
import lang::oberon::ExecutionContext;
import List;
import Map;

//public Type wellTyped(Expression exp, Context ctx)
public Type typeOf(IntValue(v), ctx) = TInt();

public Type wellTyped(IntValue(v), ctx) = TInt();
public Type typeOf(BoolValue(v), ctx) = TBool();

public Type wellTyped(BoolValue(v), ctx) = TBool();
public Type typeOf(Undefined(), ctx) = TUndef();

public Type wellTyped(Undefined(), ctx) = TUndef();

public Type wellTyped(Add(lhs,rhs), ctx) {
switch(<wellTyped(lhs, ctx), wellTyped(rhs, ctx)>) {
public Type typeOf(Add(lhs,rhs), ctx) {
switch(<typeOf(lhs, ctx), typeOf(rhs, ctx)>) {
case <TInt(), TInt()> : return TInt();
default : return TError();
}
}

public Type wellTyped(Sub(lhs,rhs), ctx) {
switch(<wellTyped(lhs, ctx), wellTyped(rhs, ctx)>) {
public Type typeOf(Sub(lhs,rhs), ctx) {
switch(<typeOf(lhs, ctx), typeOf(rhs, ctx)>) {
case <TInt(), TInt()> : return TInt();
default : return TError();
}
}

public Type wellTyped(Mult(lhs,rhs), ctx) {
switch(<wellTyped(lhs, ctx), wellTyped(rhs, ctx)>) {
public Type typeOf(Mult(lhs,rhs), ctx) {
switch(<typeOf(lhs, ctx), typeOf(rhs, ctx)>) {
case <TInt(), TInt()> : return TInt();
default : return TError();
}
}

public Type wellTyped(Div(lhs,rhs), ctx) {
switch(<wellTyped(lhs, ctx), wellTyped(rhs, ctx)>) {
public Type typeOf(Div(lhs,rhs), ctx) {
switch(<typeOf(lhs, ctx), typeOf(rhs, ctx)>) {
case <TInt(), TInt()> : return TInt();
default : return TError();
}
}

public Type wellTyped(And(lhs,rhs), ctx) {
switch(<wellTyped(lhs, ctx), wellTyped(rhs, ctx)>) {
public Type typeOf(And(lhs,rhs), ctx) {
switch(<typeOf(lhs, ctx), typeOf(rhs, ctx)>) {
case <TBool(), TBool()> : return TBool();
default : return TError();
}
}

public Type wellTyped(Or(lhs,rhs), ctx) {
switch(<wellTyped(lhs, ctx), wellTyped(rhs, ctx)>) {
public Type typeOf(Or(lhs,rhs), ctx) {
switch(<typeOf(lhs, ctx), typeOf(rhs, ctx)>) {
case <TBool(), TBool()> : return TBool();
default : return TError();
}
}

public Type wellTyped(Not(exp), ctx) {
switch(<wellTyped(exp,ctx)>) {
public Type typeOf(Not(exp), ctx) {
switch(<typeOf(exp,ctx)>) {
case <TBool()> : return TBool();
default : return TError();
}
}

public Type wellTyped(Gt(lhs, rhs), ctx) {
switch(<wellTyped(lhs, ctx), wellTyped(rhs, ctx)>) {
public Type typeOf(Gt(lhs, rhs), ctx) {
switch(<typeOf(lhs, ctx), typeOf(rhs, ctx)>) {
case <TInt(), TInt()> : return TBool();
case <TBool(), TBool()> : return TBool();
default : return TError();
}
}

public Type wellTyped(Lt(lhs, rhs), ctx) {
switch(<wellTyped(lhs, ctx), wellTyped(rhs, ctx)>) {
public Type typeOf(Lt(lhs, rhs), ctx) {
switch(<typeOf(lhs, ctx), typeOf(rhs, ctx)>) {
case <TInt(), TInt()> : return TBool();
case <TBool(), TBool()> : return TBool();
default : return TError();
}
}

public Type wellTyped(GoEq(lhs, rhs), ctx) {
switch(<wellTyped(lhs, ctx), wellTyped(rhs, ctx)>) {
public Type typeOf(GoEq(lhs, rhs), ctx) {
switch(<typeOf(lhs, ctx), typeOf(rhs, ctx)>) {
case <TInt(), TInt()> : return TBool();
case <TBool(), TBool()> : return TBool();
default : return TError();
}
}

public Type wellTyped(LoEq(lhs, rhs), ctx) {
switch(<wellTyped(lhs, ctx), wellTyped(rhs, ctx)>) {
public Type typeOf(LoEq(lhs, rhs), ctx) {
switch(<typeOf(lhs, ctx), typeOf(rhs, ctx)>) {
case <TInt(), TInt()> : return TBool();
case <TBool(), TBool()> : return TBool();
default : return TError();
}
}

public Type wellTyped(Eq(lhs, rhs), ctx) {
switch(<wellTyped(lhs, ctx), wellTyped(rhs, ctx)>) {
public Type typeOf(Eq(lhs, rhs), ctx) {
switch(<typeOf(lhs, ctx), typeOf(rhs, ctx)>) {
case <TInt(), TInt()> : return TBool();
case <TBool(), TBool()> : return TBool();
default : return TError();
}
}

public Type typeOf(VarRef(n), ctx) {
if(n in top(ctx.heap)) {
return typeOf(top(ctx.heap)[n],ctx);
}
else if(n in ctx.global) {
return typeOf(ctx.global[n],ctx);
}
return TError();
}


//Statments TypeChecker

public Type wellTyped(WhileStmt(c,stmt), ctx){
switch(<wellTyped(c,ctx)>) {
case <TBool()> : return TBool();
default : return TError();
public bool wellTyped(WhileStmt(c,stmt), ctx){
switch(<typeOf(c,ctx)>) {
case <TBool()> : return wellTyped(stmt,ctx);
default : return false;
}
}

public Type wellTyped(IfStmt(c,stmt), ctx){
switch(<wellTyped(c,ctx)>) {
case <TBool()> : return TBool();
default : return TError();
}
public bool wellTyped(BlockStmt(list[Statement] stmts), ctx) {
m = toList((s : wellTyped(s,ctx) | s <- stmts));
switch(m){
case <false> : return false;
default : return true;
}
}

public bool wellTyped(IfStmt(c,stmt), ctx){
switch(<typeOf(c,ctx)>) {
case <TBool()> : return true;
default : return false;
}
}

public Type wellTyped(IfElseStmt(c,stmtThen, stmtElse), ctx){
switch(<wellTyped(c,ctx)>) {
case <TBool()> : return TBool();
default : return TError();
public bool wellTyped(IfElseStmt(c,stmtThen, stmtElse), ctx){
switch(<typeOf(c,ctx)>) {
case <TBool()> : return true;
default : return false;
}
}


public Type wellTyped(Print(e), ctx) {
switch(<wellTyped(e, ctx)>) {
case <TBool()>: return TBool();
case <TInt()>: return TInt();
default : return TError();
public bool wellTyped(Print(e), ctx) {
switch(<typeOf(e, ctx)>) {
case <TBool()>: return true;
case <TInt()>: return true;
default : return false;
}
}

public Type wellTyped(Return(e), ctx) {
switch(<wellTyped(e, ctx)>) {
case <TBool()>: return TBool();
case <TInt()>: return TInt();
default : return TError();
public bool wellTyped(Return(e), ctx) {
switch(<typeOf(e, ctx)>) {
case <TBool()>: return true;
case <TInt()>: return true;
default : return false;
}
}

public Type wellTyped(Assignment(n, e), ctx){
switch(<wellTyped(e, ctx)>) {
case <TBool()>: return TBool();
case <TInt()>: return TInt();
case <TUndef()>: return TUndef();
default : return TError();
public bool wellTyped(Assignment(n, e), ctx){
switch(<typeOf(e, ctx)>) {
case <TBool()>: return true;
case <TInt()>: return true;
case <TUndef()>: return true;
default : return false;
}
}

//public Type wellTyped(VarDecl(v), ctx){
// switch(<wellTyped(v, ctx)>) {
// case <TBool()>: return TBool();
// case <TInt()>: return TInt();
// case <TUndef()>: return TUndef();
// default : return TError();
// }
//}



6 changes: 2 additions & 4 deletions sample-code/oberon/src/lang/oberon/test/TestInterpreter.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@ test bool testValidLoEq() = BoolValue(true) == eval(LoEq(VarRef("x"),IntValue(15

test bool testExecuteAssignment() = expected == execute(Assignment("x", IntValue(30)), ctx);

test bool testExecuteIfStmt() = expected == execute(IfStmt(BoolValue(true),Assignment("x", IntValue(30))), ctx);
test bool testExecuteIfStmt() = expected == execute(IfStmt(Lt(VarRef("x"),IntValue(30)),Assignment("x", Add(VarRef("x"), IntValue(20)))), ctx);

test bool testExecuteIfElseStmt() = expected == execute(IfElseStmt(BoolValue(true),Assignment("x", IntValue(30)), Print(VarRef("x"))), ctx);

//test bool testExecuteIfStmt() = expected == execute(IfStmt(Lt(VarRef("x"),IntValue(30)),Assignment("x", Add(VarRef("x"), IntValue(20)))), ctx);
test bool testExecuteIfElseStmt() = expected == execute(IfElseStmt(BoolValue(true),Assignment("x", IntValue(30)), Print(VarRef("x"))), ctx);
47 changes: 27 additions & 20 deletions sample-code/oberon/src/lang/oberon/test/TestTypeChecker.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -16,45 +16,52 @@ Statement whileStmt = WhileStmt(exp,whileBlk);
Statement mainBlock = BlockStmt([attrib1, whileStmt]);
Expression undefined = Undefined();


public Context testContext = context((), ("x" : IntValue(10)), empty());

public Context emptyContext = context((), (), empty());

test bool testWellTypedAddExp() = TInt() == wellTyped(Add(IntValue(10), IntValue(7)), emptyContext);
test bool testTypeOfAddExp() = TInt() == typeOf(Add(IntValue(10), IntValue(7)), emptyContext);

test bool testTypeOfSubExp() = TInt() == typeOf(Sub(IntValue(10), IntValue(7)), emptyContext);

test bool testTypeOfMultExp() = TInt() == typeOf(Mult(IntValue(10), IntValue(7)), emptyContext);

test bool testTypeOfDivExp() = TInt() == typeOf(Div(IntValue(14), IntValue(7)), emptyContext);

test bool testTypeOfAndExp() = TBool() == typeOf(And(BoolValue(true), BoolValue(false)), emptyContext);

test bool testTypeOfOrExp() = TBool() == typeOf(Or(BoolValue(true), BoolValue(false)), emptyContext);

test bool testWellTypedSubExp() = TInt() == wellTyped(Sub(IntValue(10), IntValue(7)), emptyContext);
test bool testTypeOfNotExp() = TBool() == typeOf(Not(BoolValue(true)), emptyContext);

test bool testWellTypedMultExp() = TInt() == wellTyped(Mult(IntValue(10), IntValue(7)), emptyContext);
test bool testTypeOfGtExp() = TBool() == typeOf(Gt(BoolValue(true), BoolValue(false)), emptyContext);

test bool testWellTypedDivExp() = TInt() == wellTyped(Div(IntValue(14), IntValue(7)), emptyContext);
test bool testTypeOfLtExp() = TBool() == typeOf(Lt(BoolValue(true), BoolValue(false)), emptyContext);

test bool testWellTypedAndExp() = TBool() == wellTyped(And(BoolValue(true), BoolValue(false)), emptyContext);
test bool testTypeOfGoEqExp() = TBool() == typeOf(GoEq(BoolValue(true), BoolValue(false)), emptyContext);

test bool testWellTypedOrExp() = TBool() == wellTyped(Or(BoolValue(true), BoolValue(false)), emptyContext);
test bool testTypeOfLoEqExp() = TBool() == typeOf(LoEq(BoolValue(true), BoolValue(false)), emptyContext);

test bool testWellTypedNotExp() = TBool() == wellTyped(Not(BoolValue(true)), emptyContext);
test bool testTypeOfEqExp() = TBool() == typeOf(Eq(BoolValue(true), BoolValue(false)), emptyContext);

test bool testWellTypedGtExp() = TBool() == wellTyped(Gt(BoolValue(true), BoolValue(false)), emptyContext);
test bool testTypeOfVarRefExp() = TInt() == typeOf(VarRef("x"), testContext);

test bool testWellTypedLtExp() = TBool() == wellTyped(Lt(BoolValue(true), BoolValue(false)), emptyContext);

test bool testWellTypedGoEqExp() = TBool() == wellTyped(GoEq(BoolValue(true), BoolValue(false)), emptyContext);
//Statments tests

test bool testWellTypedLoEqExp() = TBool() == wellTyped(LoEq(BoolValue(true), BoolValue(false)), emptyContext);
test bool testWellTypedWhileStmt() = true == wellTyped(WhileStmt(exp,stmt),testContext);

test bool testWellTypedEqExp() = TBool() == wellTyped(Eq(BoolValue(true), BoolValue(false)), emptyContext);
test bool testWellTypedIfStmt() = true == wellTyped(IfStmt(BoolValue(true),attrib2),emptyContext);

test bool testWellTypedWhileStmt() = TBool() == wellTyped(WhileStmt(BoolValue(true),attrib1),emptyContext);
test bool testWellTypedIfElseStmt() = true == wellTyped(IfElseStmt(BoolValue(true),attrib1,attrib2),emptyContext);

test bool testWellTypedIfStmt() = TBool() == wellTyped(IfStmt(BoolValue(true),attrib2),emptyContext);
test bool testWellTypedPrintStmt() = true == wellTyped(Print(IntValue(10)),emptyContext);

test bool testWellTypedIfElseStmt() = TBool() == wellTyped(IfElseStmt(BoolValue(true),attrib1,attrib2),emptyContext);
test bool testWellTypedReturnStmt() = true == wellTyped(Return(IntValue(10)),emptyContext);

test bool testWellTypedPrintStmt() = TInt() == wellTyped(Print(IntValue(10)),emptyContext);
test bool testWellTypedAssignmentStmt() = true == wellTyped(Assignment("w",undefined),emptyContext);

test bool testWellTypedReturnStmt() = TInt() == wellTyped(Return(IntValue(10)),emptyContext);
test bool testWellTypedBlockStmt() = true == wellTyped(BlockStmt([stmt, attrib1]),testContext);

test bool testWellTypedAssignmentStmt() = TUndef() == wellTyped(Assignment("w",undefined),emptyContext);

//test bool testWellTypedVarDeclStmt() = TUndef() == wellTyped(VarDecl(var),emptyContext);

0 comments on commit cf599d2

Please sign in to comment.