Table of Contents
This chapter is work in progress. Not all parts have been finished yet. The latest revision of this manual may contain more material. Refer to the online version.
propagation of variable types and type annotation of expressions and statements
Figure 5.1. file: til/tc/til-typecheck.str
module til-typecheck imports liblib til-typecheck-stats strategies io-til-typecheck = io-wrap(typecheck-program) typecheck-program = Program(typecheck-stats)
Figure 5.2. file: til/tc/til-typecheck-exp.str
module til-typecheck-exp imports TIL strategies typecheck-exp(typecheck-var) = bottomup(try( typecheck-var <+ TypecheckAdd <+ TypecheckMul <+ TypecheckSub <+ TypecheckDiv <+ TypecheckMod <+ TypecheckLeq <+ TypecheckGeq <+ TypecheckLt <+ TypecheckGt <+ TypecheckEqu <+ TypecheckNeq <+ TypecheckOr <+ TypecheckAnd <+ TypecheckInt <+ TypecheckString <+ TypecheckBool )) rules typeof : e{t*} -> t where <fetch-elem(is-type)> t* => t is-type = ?TypeName(_) TypecheckInt : Int(i) -> Int(i){TypeName("int")} TypecheckString : String(x) -> String(x){TypeName("string")} TypecheckBool : True() -> True(){TypeName("bool")} TypecheckBool : False() -> False(){TypeName("bool")} TypecheckAdd : Add(e1, e2) -> Add(e1, e2){TypeName("string")} where <typeof> e1 => TypeName("string") ; <typeof> e2 => TypeName("string") TypecheckAdd : Add(e1, e2) -> Add(e1, e2){TypeName("int")} where <typeof> e1 => TypeName("int") ; <typeof> e2 => TypeName("int") TypecheckMul : Mul(e1, e2) -> Mul(e1, e2){TypeName("int")} where <typeof> e1 => TypeName("int") ; <typeof> e2 => TypeName("int") TypecheckSub : Sub(e1, e2) -> Sub(e1, e2){TypeName("int")} where <typeof> e1 => TypeName("int") ; <typeof> e2 => TypeName("int") TypecheckDiv : Div(e1, e2) -> Div(e1, e2){TypeName("int")} where <typeof> e1 => TypeName("int") ; <typeof> e2 => TypeName("int") TypecheckMod : Mod(e1, e2) -> Mod(e1, e2){TypeName("int")} where <typeof> e1 => TypeName("int") ; <typeof> e2 => TypeName("int") TypecheckLt : Lt(e1, e2) -> Lt(e1, e2){TypeName("bool")} where <typeof> e1 => TypeName("int") ; <typeof> e2 => TypeName("int") TypecheckGt : Gt(e1, e2) -> Gt(e1, e2){TypeName("bool")} where <typeof> e1 => TypeName("int") ; <typeof> e2 => TypeName("int") TypecheckLeq : Leq(e1, e2) -> Leq(e1, e2){TypeName("bool")} where <typeof> e1 => TypeName("int") ; <typeof> e2 => TypeName("int") TypecheckGeq : Geq(e1, e2) -> Geq(e1, e2){TypeName("bool")} where <typeof> e1 => TypeName("int") ; <typeof> e2 => TypeName("int") TypecheckEqu : Equ(e1, e2) -> Equ(e1, e2){TypeName("bool")} where <typeof> e1 => TypeName("int") ; <typeof> e2 => TypeName("int") TypecheckNeq : Neq(e1, e2) -> Neq(e1, e2){TypeName("bool")} where <typeof> e1 => TypeName("int") ; <typeof> e2 => TypeName("int") TypecheckAnd : And(e1, e2) -> And(e1, e2){TypeName("bool")} where <typeof> e1 => TypeName("bool") ; <typeof> e2 => TypeName("bool") TypecheckOr : Or(e1, e2) -> Or(e1, e2){TypeName("bool")} where <typeof> e1 => TypeName("bool") ; <typeof> e2 => TypeName("bool")
Figure 5.3. file: til/tc/til-typecheck-stats.str
module til-typecheck-stats imports til-typecheck-var strategies typecheck-block = Block(typecheck-stats) typecheck-stats = {| TypeOf : map(typecheck-stat) |} typecheck-stat = typecheck-block <+ typecheck-declaration <+ Assign(id, typecheck-exp) ; try(TypecheckAssign) <+ IfElse(typecheck-exp, typecheck-stats, typecheck-stats) ; TypecheckIf <+ IfThen(typecheck-exp, typecheck-stats) ; TypecheckIf <+ While(typecheck-exp, typecheck-stats) ; TypecheckWhile <+ ProcCall(id, map(typecheck-exp)) ; typecheck-proccall <+ For(id, typecheck-exp, typecheck-exp, typecheck-stats) ; TypecheckFor <+ debug(!"unknown statement: ") ; <exit> 1 TypecheckIf : IfElse(e, st1*, st2*) -> IfElse(e, st1*, st2*){TypeName("void")} where <typeof> e => TypeName("bool") TypecheckIf : IfThen(e, st*) -> IfThen(e, st*){TypeName("void")} where <typeof> e => TypeName("bool") TypecheckWhile : While(e, st*) -> While(e, st*){TypeName("void")} where <typeof> e => TypeName("bool") TypecheckFor : For(x, e1, e2, st*) -> For(x, e1, e2, st*){TypeName("void")} where <TypeOf> x => TypeName("int") ; <typeof> e1 => TypeName("int") ; <typeof> e2 => TypeName("int")
Figure 5.4. file: til/tc/til-typecheck-var.str
module til-typecheck-var imports til-typecheck-exp strategies typecheck-declaration = ?Declaration(x) ; rules( TypeOf+x : x -> TypeName("int") ) typecheck-declaration = ?DeclarationTyped(x, t) ; rules( TypeOf+x : x -> t ) TypecheckVar : Var(x) -> Var(x){t} where <TypeOf> x => t TypecheckAssign : Assign(x, e) -> Assign(x, e){TypeName("void")} where <typeof> e => t ; <TypeOf> x => t strategies // expressions with variables and calls typecheck-exp = typecheck-exp(TypecheckVar <+ typecheck-funcall) typecheck-funcall = TypecheckRead <+ TypecheckS2I <+ TypecheckI2S <+ TypecheckB2S typecheck-proccall = TypecheckWrite strategies // built-in functions TypecheckS2I : FunCall("string2int", [e]) -> FunCall("string2int", [e]){TypeName("int")} where <typeof> e => TypeName("string") TypecheckI2S : FunCall("int2string", [e]) -> FunCall("int2string", [e]){TypeName("string")} where <typeof> e => TypeName("int") TypecheckB2S : FunCall("bool2string", [e]) -> FunCall("bool2string", [e]){TypeName("string")} where <typeof> e => TypeName("bool") TypecheckRead : FunCall("read", []) -> FunCall("read", []){TypeName("string")} TypecheckRead : FunCall("readint", []) -> FunCall("readint", []){TypeName("int")} strategies // built-in procedures TypecheckWrite : ProcCall("write", [e]) -> ProcCall("write", [e]){TypeName("void")} where <typeof> e => TypeName("string") TypecheckWrite : ProcCall("writeint", [e]) -> ProcCall("writeint", [e]){TypeName("void")} where <typeof> e => TypeName("int")
Figure 5.5. file: til/xmpl/typecheck-test1
# typecheck test1.til after parsing ../tc/til-typecheck -i test1.atil | pp-aterm > test1.tc
Table 5.1. files: til/xmpl/test1.til, til/xmpl/test1.tc
before | after |
---|---|
// TIL program computing the factorial var n; n := readint(); var x; var fact; fact := 1; for x := 1 to n do fact := x * fact; end write("factorial of "); writeint(n); write(" is "); writeint(fact); write("\n"); | Program( [ Declaration("n") , Assign("n", FunCall("readint", []){TypeName("int")}){TypeName("void")} , Declaration("x") , Declaration("fact") , Assign("fact", Int("1"){TypeName("int")}){TypeName("void")} , For( "x" , Int("1"){TypeName("int")} , Var("n"){TypeName("int")} , [Assign("fact", Mul(Var("x"){TypeName("int")}, Var("fact"){TypeName("int")}){TypeName("int")}){TypeName("void")}] ){TypeName("void")} , ProcCall("write", [String("\"factorial of \""){TypeName("string")}]){TypeName("void")} , ProcCall("writeint", [Var("n"){TypeName("int")}]){TypeName("void")} , ProcCall("write", [String("\" is \""){TypeName("string")}]){TypeName("void")} , ProcCall("writeint", [Var("fact"){TypeName("int")}]){TypeName("void")} , ProcCall("write", [String("\"\\n\""){TypeName("string")}]){TypeName("void")} ] ) |