450 likes | 617 Views
2. TA1. Submit08/12/04 today after classor09/12/04 tomorrow to my mail box Schreiber 271Questions after the session. 3. Course Requirements. Compiler Project 60% Theoretical Assignments 5% Exam 35% (must pass to get credit) . 4. PA2. Average grades automatic 88manual 91total 89Main
E N D
1. 1 Mooly Sagiv and Greta Yorsh
School of Computer Science
Tel-Aviv University
gretay@post.tau.ac.il
http://www.cs.tau.ac.il/~gretay Modern Compiler Design
2. 2 TA1 Submit
08/12/04 today after class
or
09/12/04 tomorrow to my mail box Schreiber 271
Questions – after the session
3. 3 Course Requirements Compiler Project 60%
Theoretical Assignments 5%
Exam 35% (must pass to get credit)
4. 4 PA2 Average grades
automatic 88
manual 91
total 89
Main pitfalls
special characters in strings
newline and EOF in comments
too long strings
5. 5 Today Goals
Implementing Type Checking for Cool
Cool Type Rules
Next week
MIPS Recap – short (longer at the last session 15-16)
Stack Frames
6. 6 Major Semantic Tasks Inheritance graph construction and checking
Symbol table construction
construct symbol table for features using inheritance tree
assign enclosing scope for each AST node
Scope checking
check program using symbol tables
Check for Main class and main method
Type checking
uses inheritance graph and symbol tables
assign type for each AST node
7. 7 Inheritance Graph What do we put in it?
all predefined classes: Int, String, Bool, Object, IO
all user-defined classes
Why do we put it there ?
to be able to check that something is a type
to be able to compare types (for type checking)
8. 8 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?
Compare types by comparing Symbols Compare types by comparing Symbols
9. 9 Check Inheritance Graph Local properties - do not require traversing inheritance graph
base class is defined
base class can be inherited from
Global properties
find all classes reachable from root class Object
check that it really is a tree (no cycles)
10. 10 Major Semantic Tasks Inheritance graph construction and checking
Symbol table construction
construct symbol table for features using inheritance tree
assign enclosing scope for each AST node
Scope checking
check program using symbol tables
Check for Main class and main method
Type checking
uses inheritance graph and symbol tables
assign type for each AST node
11. 11 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
12. 12 Type Checking - example
13. 13 Type Checking - Implementation
Single traversal over AST
Types passed up the tree
Type environment passed down the tree
14. 14 Example
15. 15 Example
16. 16 Cool Types How types are represented ?
Symbol
compare types by comparing Symbols
When are types are created?
during lexer/parsing
predefined types
17. 17 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 language’s 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 is statically typed: type checking during compilation
18. 18 Cool Types O, M, K ? e: T
O --- mapping Object Id’s to types
types to free identifiers in the current scope
O(x) = T
O(T/y) --- O modified to return T on argument y
M --- mapping methods to method signatures
M(C, f) = (A, B, D) means there is a method f(a:A, b:B): D
defined in class C (or its ancestor)
there maybe a method and an object id with the same name
K --- the class in which expression e appears
when SELF_TYPE is involved
19. 19 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
20. 20 Subtyping Define a relation ? on classes
X ? X
X ? Y if X inherits from Y
X ? Z if X ? Y and Y ? Z
A ? C
B ? Object
E ? D and D ? E
21. 21 Least Upper Bounds
lub(A,B) = C
lub(C,D) = D
lub(C,E) = Object
In Cool, the least upper bound of two types is their least common ancestor in the inheritance tree
22. 22 Least Upper Bounds Z is the least upper bound of X and Y
lub(X, Y)=Z
X ? Z and Y ? Z Z is upper bound
X ? Z’ and Y ? Z’ ? Z ? Z’Z is the least upper bound
23. 23 Dynamic and Static Types in Cool
A variable of static type A can hold the value of static type B if B ? A
24. 24 Dynamic and Static Types The dynamic type of an object is the class that is used in the new expression
a runtime notion
even languages that are statically typed have dynamic types
The static type of an expression captures all the dynamic types that the expression could have
a compile-time notion
25. 25 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
26. 26 Assign
27. 27 Let Rule with Initialization Both rules are sound but more programs typecheck with the second one
uses subtyping
28. 28 If-Then-Else
29. 29 Case
30. 30 Dispatch
31. 31 Static Dispatch
32. 32 SELF_TYPE Example What can be a dynamic type of object returned by foo() ?
any subtype of A
33. 33 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
34. 34 Where can SELF_TYPE appear ? Parser checks that SELF_TYPE appears only where a type is expected
How ?
But SELF_TYPE is not allowed everywhere a type can appear
35. 35 Where can SELF_TYPE appear ? class T1 inherits T2 { … }
T1, T2 cannot be SELF_TYPE
x : SELF_TYPE
attribute
let
case
new SELF_TYPE
creates an object of the same type as self
foo@T(e)
T cannot be SELF_TYPE
foo(x:T1):T2 {…}
only T2 can be SELF_TYPE
36. 36 new Example class A {
foo() : A { new SELF_TYPE };
};
class B inherits A { … }
…
(new A).foo();
(new B).foo();
37. 37 Subtyping for SELF_TYPE SELF_TYPEc ? SELF_TYPEc
SELF_TYPEc ? C
It is always safe to replace SELF_TYPEc with C
SELF_TYPEc ? T if C ? T
T ? SELF_TYPEc is always false
because SELF_TYPEc can denote any subtype of C
38. 38 lub(T,T’) for SELF_TYPE lub(SELF_TYPEc, SELF_TYPEc) = SELF_TYPEc
lub(T, SELF_TYPEc) = lub(T,C)
the best we can do
39. 39 New Rules
40. 40 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
41. 41 Dispatch which class is used to find the declaration of foo() ?
It is safe to use the class where the dispatch appears
42. 42 Example class A {
foo() : A { self };
};
class B inherits A { … }
…
(new A).foo();
(new B).foo();
43. 43 Static Dispatch
44. 44 SELF_TYPE Example
45. 45 Error Recovery Error detection is easy
What type is assigned to an expression with no legitimate type ?
influences type of enclosing expressions
cascading errors
let y : Int ? x + 2 in y + 3
Better solution: special type No_Type
inheritance graph can be cyclic
46. 46 Major Semantic Tasks Inheritance graph construction and checking
Symbol table construction
construct symbol table for features using inheritance tree
assign enclosing scope for each AST node
Scope checking
check program using symbol tables
Check for Main class and main method
Type checking
uses inheritance graph and symbol tables
assign type for each AST node
Remaining Semantic Checks
checks that require type + symbol table information combined
Disclaimer: This is a naďve phase ordering. Phases could be mixed, combined, optimized, re-ordered etc.