Professional Documents
Culture Documents
Modern Compiler Design: T8 - Semantic Analysis: Type Checking
Modern Compiler Design: T8 - Semantic Analysis: Type Checking
Mooly Sagiv and Greta Yorsh School of Computer Science Tel-Aviv University gretay@post.tau.ac.il http://www.cs.tau.ac.il/~gretay
TA1
Submit
08/12/04 today after class or 09/12/04 tomorrow to my mail box Schreiber 271
Course Requirements
Compiler Project 60% Theoretical Assignments 5% Exam 35% (must pass to get credit)
PA2
Average grades
automatic 88 manual 91 total 89
Main pitfalls
special characters in strings newline and EOF in comments too long strings
Today
txt
Lexical Analysis Syntax Analysis Parsing AST Symbol Table etc. Inter. Rep. (IR) Code Gen.
exe
COOL code
Executable code
Goals
Implementing Type Checking for Cool Cool Type Rules
Next week
MIPS Recap short (longer at the last session 15-16) Stack Frames
5
Scope checking
check program using symbol tables
Inheritance Graph
What do we put in it?
all predefined classes: Int, String, Bool, Object, IO all user-defined classes
Implementation
Mapping class names to nodes in the graph For each node keep
parent (and children) in the inheritance graph is the class reachable/unreachable from the Object class via the "inherits from" relation?
Global properties
find all classes reachable from root class Object check that it really is a tree (no cycles)
Scope checking
check program using symbol tables
Semantic Checks
Scope rules
identifiers are defined no multiple definition of same identifier local variables are defined before used program conforms to scope rules
Type rules
which types can be combined with certain operator assignment of expression to variable formal and actual parameters of a method call
11
drive + drink
Int
String
12 + Rumster
ERROR
12
13
Example
globals
Symbol Foo kind class
lt
Foo
Symbol test kind Int->Int Int
plus
neg test
lookup(x)
Symbol c Int
int_const val=45
object name=x
int_const val=32
: Int
: Int
14
Example
lt
O,M,C
O,M,C
: Bool
O,M,C O,M,C
: Int
plus
neg
: Int
O,M,C O,M,C O,M,C
int_const val=45
object name=x
int_const val=32
: Int
: Int
: Int
15
Cool Types
How types are represented ?
Symbol compare types by comparing Symbols
16
Cool Types
The types are
Class Names SELF_TYPE
The user declares types for identifiers The semantic analysis infers types for expressions
Every expression has a unique type
A languages type system specifies which operations are valid for which types The goal of type checking is to ensure that operations are used with the correct types
Enforces intended interpretation of values
Cool Types
O, M, K e: T
type environment
Type rules
O, M, K e1 : Int O, M, K e2 : Int O, M, K e1 + e2 : Int Rules give templates describing how to type expressions By filling the templates, we can produce complete typings for expressions
O(x) = T O,M,C int_const : Int O,M,C x : T
19
Subtyping
Define a relation on classes
X X X Y if X inherits from Y X Z if X Y and Y Z Object D IO E B
A C B Object E D and D E
C A
20
IO E
22
static type of x is A
dynamic type of x A
dynamic type of x is B
23
The static type of an expression captures all the dynamic types that the expression could have
a compile-time notion
24
Soundness
A type system is sound if e. dynamic_type(e) static_type(e)
whenever the inferred type of e is T
( denoted by e : T )
Then e evaluates to a value of type T in all executions of the program
We only want sound rules But some sound rules are better than others
25
Assign
O (x) = T0 O,M,K e1 : T1 T 1 T0 O,M,K x e1 : T1 class B { foo() : B }; class A inherits B { ...
ERROR OK OK
B
[Assign]
{ }
};
let x:A in x (new A).foo(); let x:B in x (new A).foo(); let x:Object in x (new A).foo();
26
};
O,M,K let x: T0 e0 in e1 : T1
Both rules are sound but more programs typecheck with the second one
uses subtyping
27
If-Then-Else
O,M,K e0 :Bool O,M,K e1: T1 O,M,K e2 : T2 O,M,K if e0 then e1 else e2 fi : lub(T1, T2)
foo(a:A, b:B, c:C, e:E) : D { if (a < b) then e else c fi } lub(E,C) = Object Is Object D ? ERROR A
Object D C B IO E
28
Case
O,M,K e : T O[X/x],M,K e1: E O[Y/y],M,K e2: F O[Z/z],M,K e3: G O,M,K case e of x: X =>e1; y:Y =>e2 ; z:Z=>e3 esac : lub(E,F,G)
foo(d:D) : D { case d of x : IO => let a:A(new A) in x; A y : E => (new B); z : C => z; esac }; lub(A,B,C) = C and C D OK
Object D C A B IO E
29
Dispatch
O, M c : C O, M a : A O, M b : B M(C, f) = (A1, B1, D1) A A1 , B
[Dispatch]
B1
O, M, K c.f(a, b): D1
Static Dispatch
O, M, K c : C O, M, K a : A O, M, K b : B M(C, f) = (A1, B1, D1) A A1, B O, M, K B1, C C1 c@C1.f(a, b): D1 [StaticDispatch]
SELF_TYPE Example
class A { foo() : A { self } ; }; class B inherits A { ... }; class Main { B x (new B).foo(); }; }; class B inherits A { ... }; class Main { B x (new B).foo(); }; class A { foo() : SELF_TYPE { self } ;
ERROR
OK
SELF_TYPE
Research idea Helps type checker to accept more correct programs C,M,K (new A).foo() : A C,M,K (new B).foo() : B SELF_TYPE is NOT a dynamic type Meaning of SELF_TYPE depends on where it appears textually
33
34
x : SELF_TYPE
creates an object of the same type as self T cannot be SELF_TYPE only T2 can be SELF_TYPE
foo(x:T1):T2 {}
35
new Example
class A { foo() : A { new SELF_TYPE }; class B inherits A { } (new A).foo(); creates A object (new B).foo(); creates B object };
36
38
New Rules
O, M, K self : SELF_TYPEk
O, M, K
39
Other rules
A use of SELF_TYPE refers to any subtype of the current class Except in dispatch
because the method return type of SELF_TYPE might have nothing to do with the current class
40
Dispatch
O, M c : C O, M a : A O, M b : B M(C, foo) = (A1, B1, D1) A A1 , B
B1, D1 SELF_TYPE
O, M, K c.foo(a, b) : D1
which class is used to find the declaration of foo() ? It is safe to use the class where the dispatch appears
B1
41
O, M, K c.foo(a, b): C
Example
class A { foo() : A { self }; }; class B inherits A { } (new A).foo(); returns A object (new B).foo(); returns B object
42
Static Dispatch
O, M, K c : C O, M, K a : A O, M, K b : B M(C, f) = (A1, B1, D1) A A1, B O, M, K B1, C C1, D1 SELF_TYPE c.f@C1(a, b): D1
O, M, K c : C O, M, K a : A
if we dispatch a method returning SELF_TYPE in class C1, do we get back C1 ? No. SELF_TYPE is the type of self, which may be a subtype of the class in which the method appears
SELF_TYPE Example
class A { deligate : B; callMe() : ??? SELF_TYPE { deligate.callMe(); } ; }; class B { callMe() : SELF_TYPE { self }; }; class Main { A a (new A).callMe(); };
44
ERROR
Error Recovery
Error detection is easy What type is assigned to an expression with no legitimate type ?
influences type of enclosing expressions cascading errors
Scope checking
check program using symbol tables
Disclaimer: This is a nave phase ordering. Phases could be mixed, combined, optimized, re-ordered etc.
46