Bottop-Up Type Checking
Recall function interpExpr function in
Forget about uninitialized values for now, worry only about types
We evaluate type analogously to evaluating expressions
Principles:
- all variables are declared with their types
- scoping rules determine how to update environment (innermost declarations take precedence)
- lookup in environment gives types for variable uses
- each operator has type evaluation rules
Relevant piece of code from Semantic Analysis as Simplified Interpretation:
def interpExpr(e : Env)(expr : Expression) : Value = { expr match { case Var(n) => { getVar(e, n).v } case IntConst(i) => IntValue case Plus(expr1,expr2) => { (interpExpr(e)(expr1),interpExpr(e)(expr2)) match { case (IntValue,IntValue) => IntValue case (_,_) => error("type error") } } case BoolConst(b) => BoolValue case Leq(expr1, expr2) => { (interpExpr(e)(expr1),interpExpr(e)(expr2)) match { case (IntValue,IntValue) => BoolValue case (_,_) => error("type error") } } case And(expr1, expr2) => { (interpExpr(e)(expr1),interpExpr(e)(expr2)) match { case (BoolValue,BoolValue) => BoolValue case (_,_) => error("type error") } } } }