1 / 24

Modern Compiler Design

Modern Compiler Design. T9 – More 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. Today. MIPS code. exe. COOL code. txt. Today More type checking rules! SELF_TYPE….

vance
Download Presentation

Modern Compiler Design

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Modern Compiler Design T9 – More 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

  2. Today MIPS code exe COOL code txt • Today • More type checking rules! SELF_TYPE…. • PA4 with Eclipse on Windows • Next week • MIPS tutorial LexicalAnalysis Syntax Analysis Parsing AST SymbolTableetc. Inter.Rep. (IR) Code Gen.

  3. 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.

  4. Let Rule with Initialization O,M,K  e0: T O(T/x)  e1 : T1 O,M,K  let x: Te0 in e1 : T1 O,M,K  e0: T O(T0/x)  e1 : T1 T  T0 O,M,K  let x: T0 e0 in e1 : T1 • Both rules are sound but more programs typecheck with the second one (uses subtyping) Weak rule class A { foo():C { … } }; class B inherits A { }; class C { bar():C { let x:A  new B in x.foo() }; }

  5. 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) Object IO D E C A B 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

  6. Case Object IO D E IO C A B 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) X,Y,Z must be distinct types foo(d:D) : D { case d of x : IO => let a:A(new A) in x; y : E => (new B); z : C => z; esac }; lub(IO,B,C) = Object and Object  D ERROR

  7. Case Object IO D E A C A B 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 a; y : E => (new B); z : C => z; esac }; lub(A,B,C) = C and C  D OK

  8. Case – why? • Static types can be too conservative • O,M,K  e : P • programmer knows that for all vvalues(e), type(v)=C • C  P and C ≠ P • Use dynamic check • runtime error if no branch can be selected class P { foo():P { new C }; }; class C inherits P { }; class D { x : C <- (new P).foo(); y : C <- case (new P).foo() of x : C => x; esac; }; ERROR OK

  9. SELF_TYPE Example class A { foo() : A { self } ; }; class B inherits A { ... }; class Main { x : B (new B).foo(); }; class A { foo() : B { self } ; }; class B inherits A { ... }; class Main { x : B  (new B).foo(); }; ERROR ERROR OK

  10. SELF_TYPE Example • What can be a dynamic type of object returned by foo() ? • any subtype of A class A { foo() : A { self } ; }; class B inherits A { ... }; class Main { x : B  (new B).foo(); }; class A { foo() : SELF_TYPE { self } ; }; class B inherits A { ... }; class Main { x : B  (new B).foo(); }; ERROR OK

  11. 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 dynamictype • Meaning of SELF_TYPE depends on where it appears textually

  12. 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

  13. 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

  14. new Example class A { foo() : A { new SELF_TYPE }; }; class B inherits A { … } … (new A).foo(); (new B).foo(); creates A object creates B object

  15. SELF_TYPE vs. SELF_TYPEC • SELF_TYPE is keyword • part of Cool syntax • refers to the type of self variable • NOT a dynamictype • meaning of SELF_TYPE depends on where it appears textually • may refer to class C in which it appears or its subclass • SELF_TYPEc is type • part of notations for type rules, not part of Cool syntax • referred to by SELF_TYPE keyword used in class C

  16. 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 in reference coolc • because SELF_TYPEc can denote any subtype of C

  17. 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

  18. New Rules O, M, K  self : SELF_TYPEk O, M, K  new SELF_TYPE : SELF_TYPEk

  19. 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

  20. Dispatch O, M, K  c : C O, M, K  a : A O, M, K  b : B M(C, foo) = (A1, B1,SELF_TYPE) A  A1 , B  B1 O, M, K  c.foo(a, b): C O, M, K  c : C O, M, K  a : A O, M, K  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() ?

  21. Static Dispatch O, M, K  c : C O, M, K  a : A O, M, K  b : B M(C1, f) = (A1, B1, D1) A  A1, B  B1, C  C1, D1  SELF_TYPE O, M, K  c.f@C1(a, b): D1 • 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 O, M, K  c : C O, M, K  a : A O, M, K  b : B M(C1, f) = (A1, B1,SELF_TYPE) A  A1, B  B1, C  C1 O, M, K  c@C1.f@(a, b): C

  22. Error Handling • Error detection is easy • Error recovery: 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

  23. Summary • Type is a set of values • Type rules are logical rules of inference • Soundness of (static) type systems • for every expression e, for every value v of e at runtime v values_of(static_type(e)) • static_type(e) may actually describe more values • can reject correct programs • Becomes more complicated with subtyping (inheritance)

  24. PA4 with Eclipse on Windows • You do not have to use it • Warning 1: set up may take some time • requires rt.jar and matching java_cup • download PA4JE.tar.gz • create a new project in eclipse • put all sources in default package • set build path • Warning 2: Compile and test on nova !!

More Related