Cse 321 Programming Languages and Compilers Lecture 16
- Slides: 26
Cse 321, Programming Languages and Compilers Lecture #16, March 7, 2007 • Mutual Recursion • Symbol Tables • Class Hierarchies • Type checkers that rebuild code 9/9/2020 1
Cse 321, Programming Languages and Compilers Assignments • Reading – Finish Chapter 4. Sections 4. 4, 4. 5, and 4. 6 pages 188 -208 – Read Section 5. 7 on Symbol tables page 238 -248 – Possible Quiz next Monday. • Project 3 is due Monday March 19 9/9/2020 2
Cse 321, Programming Languages and Compilers Mutual Recursion • Mutual recursion is found in almost all real languages • Mutual recursion requires different techniques – Multiple passes. – One pass to build a temporary table with just the information about the mutually recursive entities – Second pass to type the recursive entities where the current scope is extended with the temporary table. » Inside this pass, the table is often extended even more to capture information about entities declared in a single one of the mutually recursive entities. – Finally, the temporary table is exported to the scope in which the mutually recursive entities exist. 9/9/2020 3
Cse 321, Programming Languages and Compilers Example in ML x: int val x = 56; fun f x = x + 5; fun even n = if n=0 then true else odd (n-1) and odd n = if n=0 then false else if n=1 then true else even (n-1); val main = even(f x) 9/9/2020 f: int -> int x: int f: int -> int even: int->bool odd: int->bool n: int x: int f: int -> int even: int->bool odd: int->bool main: bool 4
Cse 321, Programming Languages and Compilers Concrete Example and = | | Dec Valdec of (string*MLtype)*Exp Fundec of (string*MLtype)*string*Exp Mutdec of Dec list • Assume we represent declarations as above. • Every val and fun declaration contains explicit information about their types (as is true in Mini-Java) • Then the concrete syntax may look like: val (x: int) = 56; fun (f: int->int) (x: int) = x + 5; 9/9/2020 5
Cse 321, Programming Languages and Compilers Type Checking Declarations • Type checking will depend upon two attribute computations. • Checking declarations will map an environment to a delta environment. • New environment will be the old one plus the delta. TCExp: Exp ->(string * MLtype)list ->MLtype TCDec: Dec ->(string * MLtype)list ->(string * MLtype) list fun (even: int ->bool) (n: int) = if n=0 then true else odd (n-1) and (odd: int -> bool) (n: int) = if n=0 then false else if n=1 then true else even (n-1); 9/9/2020 x: int even: int -> bool f: int -> int odd: int -> bool 6
Cse 321, Programming Languages and Compilers Non mutually recursive cases fun TCDec (Valdec((nm, t), exp)) cntxt = let val bodyt = TCExp exp cntxt in if typeeq(t, bodyt) then [(nm, t)] else unexpected exp bodyt t end | TCDec (Fundec((f, dom, rng), x, body)) cntxt = let val ft = Arrow(dom, rng) val bodyt = TCExp body((x, dom): : cntxt) (* f is not recursive unless inside a Mutdec *) in if typeeq(bodyt, rng) then [(f, ft)] else unexpected bodyt rng end 9/9/2020 7
Cse 321, Programming Languages and Compilers Mutually recursive case | TCDec (Mutdec ds) cntxt = let fun pass 1 [] cntxt = cntxt | pass 1 (Valdec(p, b): : ds) cntxt = pass 1 ds (p: : cntxt) | pass 1 (Fundec((f, d, r), x, b): : ds) cntxt = pass 1 ds ((f, Arrow(d, r)): : cntxt) val temp = pass 1 ds cntxt val pass 2 = map (fn d => TCDec d temp) ds in List. concat pass 2 end; cntxt temp pass 2 result x: int odd: int->bool even: int->bool f: int -> int even: int->bool x: int f: int -> int odd: int->bool 9/9/2020 8
Cse 321, Programming Languages and Compilers Symbol Tables • Symbol Tables map names to information • Many kinds of Names – – – Variables Procedure and function names Labels Data Structure names (Constructors in ML or named Struct in C) Types • Many kinds of information – – – 9/9/2020 Type Physical location in source (line number) Size Storage class Lexical location (Inside what class) Location in memory in the translation 9
Cse 321, Programming Languages and Compilers Multiple symbol tables • Compilers might use one big table, or many smaller ones. • Multiple tables have advantages – Each table stores uniform items – Tables might have limited scope and can be recycled – Each table can use different implementation » Hash Table » Linked List » Balanced Tree – Each table probably has different access patterns » Create Once, then read only » Block Structured, so stack allocation is possible » Insertions only » Both insertions and deletions • Tables can have mutable or non-mutable data • Language may have multiple name spaces – Types, labels, variables, selectors, . . . 9/9/2020 10
Cse 321, Programming Languages and Compilers Nested Scope • Many tables record information with block structure or nested scope. • Stack allocation is possible • Easy to implement in a functional language like ML – Use inherited attribute computation – Table becomes a parameter to the function – Entering new block means a new call to function with the parameter augmented. – Exiting scope means restoring the old parameter » Natural in a functional style since the old parameter is always still around. 9/9/2020 11
Cse 321, Programming Languages and Compilers Operations on nested scope • • Initialize Scope Insert name value Scope Lookup name Scope Finalize Scope type ('name, 'value)table = ('name * 'value) list; type ('name, 'value)Scope = (('name, 'value)table) list ; More sophisticated kinds of tables can be used here rather than a linked list of pairs. Hash Tables, Balanced trees, etc. fun initialize scope = [ ] : : scope fun insert name value (table: : scope) = ((name, value): : table): : scope fun Lookup name (table: : scope) = case List. find (fn (x, y) => x=name) table of NONE => error | SOME (x, y) => y fun finalize (table: : scope) = scope 9/9/2020 12
Cse 321, Programming Languages and Compilers Data Structures for the Mini. Java Type Checker • Scope in object oriented languages like mini-java is attached to the class structure. • Each class has its own symbol table – Usually this table is an ordinary nested scope table • Each class must link to the symbol table for its super -class. • The Class hierarchy is a tree of symbol tables. • The set of operations on the tables can be found by inspecting the type rules. 9/9/2020 13
Cse 321, Programming Languages and Compilers Judgments from the type rules Th, C, TE |- exp : type Th, R, C, TE |= stmt C |~ t 1 ≤ t 2 t 1 = t 2 C defines x In C p has method f In C p has variable x Op <+> : (t 1, t 2) -> t 3 t is basic 9/9/2020 14
Cse 321, Programming Languages and Compilers Data Structure datatype CTab = Node of Id * (* Class Name (Id * Type)list * (* Class Variables (Id * Type list * Type)list * (* Methods CTab ref * (* Parent Class CTab list (* Sub Classes | Null. Class; *) *) *) val root = Node("object", [], ref Null. Class, []); CTab for class table is an n-way branching tree. object point colorpoint 9/9/2020 numeric int boolean void double 15
Cse 321, Programming Languages and Compilers new. Class fun new. Class name vars methods parent Null. Class = Null. Class | new. Class name vars methods parent (n as Node(nm, vs, ms, p, subs)) = if parent=nm then let val p 1 = ref n val new = Node(name, vars, methods, p 1, []) val new. P = Node(nm, vs, ms, p, new : : subs) val _ = p 1 : = new. P in new. P end else Node(nm, vs, ms, p, map (new. Class name vars methods parent) subs) • new. Class creates a new class hierarchy from the old one. The old one is unchanged. 9/9/2020 16
Cse 321, Programming Languages and Compilers val t 1 = new. Class "point" [] [] "object" root; root Node(“object”, [ ], ref Null. Class, [ ]) new Node(“point”, [ ], ref _ , [ ]) new. P Node(“object”, [ ], ref Null. Class, [Node(“point”, [ ], ref _ , [ ])]) • The final step is to overwrite the pointer to root with new. P, and then return new. P • new. Class rebuilds the part of the tree that are unchanged 9/9/2020 • The references make cyclic structures 17
Cse 321, Programming Languages and Compilers val t 1 = new. Class "point" [] [] "object" root; val t 2 = new. Class "colorpoint" [] [] "point" t 1; t 2 Node(“object”, [ ], ref Null. Class , [ _ ]) Node(“point”, [ ], ref _ , [ _ ]) Node(“colorpoint”, [ ], ref _ , [ ]) 9/9/2020 18
Cse 321, Programming Languages and Compilers val t 1 = new. Class "point" [] [] "object" root; val t 2 = new. Class "colorpoint" [] [] "point" t 1; val t 3 = new. Class "person" [] [] "object" t 2 t 3 Node(“object”, [ ], ref Null. Class , [ _ , _ ]) Node(“point”, [ ], ref _ , [ _ ]) Node(“colorpoint”, [ ], ref _ , [ ]) Node(“person”, [ ], ref _ , [ ]) 9/9/2020 19
Cse 321, Programming Languages and Compilers C defines x fun defines name Null. Class = false | defines name (Node(n, vs, ms, p, ss)) = if name=n then true else List. exists (defines name) ss; 9/9/2020 20
Cse 321, Programming Languages and Compilers t 1 = t 2 fun basiceq (x, y) = case (x, y) of (Real, Real) => true | (Int, Int) => true | (Bool, Bool) => true | (_, _) => false fun typeeq (x, y) = case (x, y) of (Basic. Type x, Basic. Type y) => basiceq(x, y) | (Array. Type x, Array. Type y) => basiceq(x, y) | (Obj. Type x, Obj. Type y) => x=y | (Void. Type, Void. Type) => true | (_, _) => false 9/9/2020 21
Cse 321, Programming Languages and Compilers C |~ t 1 ≤ t 2 fun use. Tree Null. Class (x, y) = false | use. Tree (Node(nm, vs, ms, p, ss)) (x, y) = if nm = y then List. exists (defines x) ss else List. exists (fn t => use. Tree t (x, y)) ss fun subtype class. H (x, y) = case (x, y) of (x, Obj. Type "object") => true | (Basic. Type Int, Obj. Type "numeric") => true | (Basic. Type Real, Obj. Type "numeric") => true | (Obj. Type x, Obj. Type y) => use. Tree class. H (x, y) | (_, _) => typeeq(x, y) 9/9/2020 22
Cse 321, Programming Languages and Compilers Type checkers that rebuild the syntax tree • Some type checkers use inference to add things to the syntax tree that are missing. – Coercions » 3 + 5. 6 -> to. Float 3 + 5. 6 – Implicit class information » X. f(3, 5) -> X. ffrompoint(2, 5) – Implicit type information » (fn x => x + 1) -> (fn (x: Int) => x + 1) • Such type checkers return a tuple. – The tuple includes the synthesized attributes and a new syntax tree. Compare the two types – TCExp 2: Exp -> (string * MLtype) list -> MLtype * Exp – TCExp: Exp -> (string * MLtype) list -> MLtype 9/9/2020 23
Cse 321, Programming Languages and Compilers TCExp 2 fun TCExp 2 x cntxt = When a term has no sub terms, the old term can case x of usually be returned Lit c => (TCConstant c, x) | Var s => (case List. find (fn (nm, t) => nm=s) cntxt of SOME(nm, t) => (t, x) | NONE => error x "Undeclared variable") | Infix(l, x, r) => let val (ltype, l 2) = TCExp 2 l cntxt val (rtype, r 2) = TCExp 2 r cntxt val (lneed, result) = TCOp x in case (typeeq(ltype, lneed), typeeq(rtype, rneed)) of (true, true) => (result, Infix(l 2, x, r 2) ) | (true, false) => unexpected r rtype rneed | (false, true) => unexpected l ltype lneed Sub terms are | (false, false) => unexpected l ltype lneed rebuilt and the returned term is end constructed from these. 9/9/2020 24
Cse 321, Programming Languages and Compilers Why Bother • If all we ever do is return the same tree, why bother? • We use type (or other) information to add little bits of syntax. Infix(l, x, r) => let val (ltype, l 2) = TCExp 2 l cntxt val (rtype, r 2) = TCExp 2 r cntxt val (lneed, result) = TCOp x in case (typeeq(ltype, lneed), typeeq(rtype, rneed)) of (true, true) => Fix result (x, ltype, rtype) l 2 r 2 | (true, false) => unexpected r rtype rneed | (false, true) => unexpected l ltype lneed | (false, false) => unexpected l ltype lneed end fun Fix result info left right = case info of (Plus, Int, Real) => (result, Infix( Int 2 Real left , Plus, right)) | (Plus, Real, Int) => (result, Infix(left, Plus, Int 2 Real right )) | (oper, _ ) => (result, Infix(left, oper, right)) 9/9/2020 25
Cse 321, Programming Languages and Compilers Class exercise • As an in class exercise, lets continue the function on the previous pages. • Start with an non rebuilding type-checker – Make a copy of it. • Rename every call to a new name (so it doesn’t conflict) • For each returned expression add a another value to the tuple. • For each recursive call, accept (or pattern match against) an additional value. 9/9/2020 26
- Elsa gunter uiuc
- Cs 421 uiuc
- Adam doupe cse 340
- Vineeth kashyap
- Cse 321
- Pros and cons of compilers and interpreters
- Finding and understanding bugs in c compilers
- Lex leblanc
- Compilers and interpreters are themselves
- Real-time systems and programming languages
- Advantages and disadvantages of programming languages
- Real time programming language
- C++ binarymove
- Cousins of compiler
- Crafting a compiler
- Machine dependent compiler features
- Dash phase is known as the back end of the compiler
- 01:640:244 lecture notes - lecture 15: plat, idah, farad
- Multithreaded programming languages
- Cxc it
- Introduction to programming languages
- Plc coding language
- Joey paquet
- Imperative programming languages
- Alternative programming languages
- Strongly typed vs weakly typed
- Transmission programming languages