320 likes | 475 Views
CS412/413. Introduction to Compilers and Translators Spring ’99 Lecture 9: Types and static semantics. Administration. Programming Assignment 1 due now Programming Assignment 2 handout. Review. Semantic analysis performed on representation of program as AST
E N D
CS412/413 Introduction to Compilers and Translators Spring ’99 Lecture 9: Types and static semantics
Administration • Programming Assignment 1 due now • Programming Assignment 2 handout CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Review • Semantic analysis performed on representation of program as AST • Implemented as a recursive traversal of abstract syntax tree CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Semantic Analysis • Catching errors in a syntactically valid program • Identifier errors: unknown identifier, duplicate identifier, used before declaration • Flow control errors: unreachable statements, invalid goto/break/continue statements • Expressions have proper type for using context • LHS of assignment is variable of proper type • This lecture: • What kinds of checks are done (particularly type chks) • How to specify them clearly • Converting into an implementation • Not covered in Appel or Dragon Book CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Type checking • Most extensive semantic checks • Operators (e.g. +, !, [ ]) must receive operands of the proper type • Functions must be called w/ right number & type of arguments • Return statements must agree w/ return type • In assignments, assigned value must be compatible with type of variable on LHS. • Class members accessed appropriately CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Static vs. Strong Typing • Many languages statically typed (e.g. C, Java, but not Scheme, Dylan): expressions, variables have a static type • Static type is a predicate on values might occur at run time. int x; in Java means x [-231, 231). • Strongly typed language: operations unsupported by a value never performed at run time. • In strongly typed language with sound static type system: run-time values of expressions, variables characterized conservatively by static type CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Why Static Typing? • Compiler can reason more effectively • Allows more efficient code: don’t have to check for unsupported operations • Allows error detection by compiler • But: • requires at least some type declarations • type decls often can be inferred (ML) CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Dynamic checks • Array index out of bounds • null in Java, null pointers in C • Inter-module type checking in Java • Sometimes can be eliminated through static analysis (but usually harder than type checking) CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Type Systems • Type is predicate on values • Arbitrary predicates: type checking intractable (theorem proving) • Languages have type systems that define what types can be expressed • Types described in program by type expressions: int, string, array[int], Object, InputStream[ ]; compiler interprets as types in type system CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Example: Iota type system • Language type systems have primitive types (also: basic types, atomic types) • Iota: int, string, bool • Also have type constructors that operate on types to produce other types • Iota: for any type T, array[ T ] is a type. Java: T [ ] is a type. • Extra types: void denotes absence of value CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Type expressions: aliases • Some languages (not Java) allow type aliases (type definitions, equates) • C: typedef int int_array[ ]; • Modula-3: type int_array = array of int; • int_array is type expression denoting same type as int [ ] -- not a type constructor • Type expressions not isomorphic with type system in general CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Type Expressions: Arrays • Different languages have various kinds of array types • w/o bounds: array(T) • C, Java: T[ ], Modula-3: array ofT • size: array(T, L) (may be indexed 0..L-1) • C: T[L], Modula-3: array[L] ofT • upper & lower bounds: array(T,L,U) • Pascal, Modula-3: indexed L..U • Multi-dimensional arrays (FORTRAN) CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Records/Structures • More complex type constructor • Has form {id1: T1, id2: T2, …} for some ids and types Ti • Supports access operations on each field, with corresponding type • C: struct { int a; float b; } corresponds to type {a: int, b: float} • Class types (e.g. Java) extension of record types CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Functions • Some languages have first-class function types (C, ML, Modula-3, Pascal, not Java) • Function value can be invoked with some argument expressions with types Ti, returns return type Tr. • Type: T1T2 … TnTr • C: int f(float x, float y) • f: float float int • Function types useful for describing methods, as in Java, even though not values, but need extensions for exceptions. CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Static Semantics • Can describe the types used in a program. How to describe type checking? • Formal description: static semantics for the programming language • Static semantics includes language syntax, but implementation operates on AST. CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Type Judgments • Static semantics consists of judgments • Type judgment: A |– E : T • means “In the context A (symbol table), the expression E can be shown to have the type T” • Context is set of id : T mappings • Examples: for all A, A |– true : bool A |– integer_const : int A |– id : A[id] CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Inference Rules • For more complex expressions, need to know type of sub-expressions • “In any context A, for any expressions E1 and E2that have type int, the expression E1 + E2has the type int” A |– E1: int A |– E2: int A |– E1+ E2: int Antecedents Inference rule Consequent CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Implementing a rule T = E.typeCheck(A) == A|– E : T • Work backward from goal: class Add extends Expr { Expr e1, e2; Type typeCheck() { Type t1 = e1.typeCheck(), t2 = e2.typeCheck(); if (t1 == Int && t2 == Int) return Int; else throw new TypeCheckError(“+”); } A |– E1: int A |– E2: int A |– E1+ E2: int CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
A |– E1: float A |– E2: float A |– E1+ E2: float A |– E1: float A |– E2: int A |– E1+ E2: float Inference Rules • Rules are implicitly universally quantified over free variables: • Same goal judgment may be provable in more than one way: A |– true : bool CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Statements • For statements that do not have a value, use the type void to represent their result type: A|– E : bool A|– S : T A|– while (E) S : void CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
If statements • Iota: the value of an if statement (if any) is the value of the arm that is executed. • If no else clause, no value: A|– E : bool A|– S : T A|– if ( E ) S : void CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Assignment id : T A A |– E : T A|– id = E; : T A|– E3 : T A|– E2 : int A|– E1 : array(T) A|– E1[E2] = E3; : T CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Checking a function • Create an environment A containing all the argument variables (+globals) • Check the body E in this environment • Type of E must match declared return type of function • Need notation: A[x] is the type of identifier x in the symbol table, A {x : T} is environment extended with binding x : T CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Function-checking rule • Create an environment A containing all the argument variables • Check the body E in this environment • Type of E must match declared return type of function (ignoring return statements) A { ..., ai : Ti, ...} |–E : T A |– ( id ( ..., ai : Ti, ...) : T = E ) CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Example fact(x: int) : int = { if (x==0) 1; else x * fact(x - 1); } A|– (fact(x: int) : int = {…} ) A {x : int} |– if (x==0) ...; else ... : int A {x : int} |– x==0 : bool A {x : int} |– 1 : T1 (T1=int) A {x : int} |– x * fact(x-1) : T2 (T2=int) CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Sequence • Rule: A sequence of two statements is type-safe if the first statement is type-safe, and the second is type safe including any new variable definitions from the first: A |– S1: T1 extend(A, S1) |– S2 : T2 A |– S1 S2 : T2 CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Variable declarations • Function extend gathers up variable declarations and produces a new environment: extend(A, id: T[ = E ] ) = A { id : T } extend(A, S ) = A (otherwise) • This formally describes the type-checking code from last lecture! CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Implementation class Block { Stmt stmts[]; Type typeCheck(SymTab s) { Type t; for (int i = 0; i < stmts.length; i++) { t = stmts[i].typeCheck(s); if (stmts[i] instanceof Decl) s = s.add(Decl.id, Decl.typeExpr.evaluate()); } return t; } } extend(A, id: T[ = E ] ) = A {id : T} extend(A, S ) = A (otherwise) CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Completing static semantics • Remainder of static semantics can be written in this style • Provides complete recipe (inductively) for how to show a program type-correct • Induction: • have rules for atoms: A |– true : bool • have inference rules for checking all valid syntactic constructs in language • Therefore, have rules for checking all syntactically valid programs CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Implementing rules • Start from goal judgments for each function A |– ( id ( ..., ai : Ti, ...) : T = E ) • Work backward applying inference rules to sub-trees of abstract syntax trees • Same recursive traversal described last time CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers
Summary • Type systems • Static semantics • Inference rules: compact, precise language for specifying static semantics (can specify Java in ~10 pages vs. 100’s of pages of Java Language Specification) • Inference rules correspond directly to recursive AST traversal that implements them CS 412/413 Introduction to Compilers and Translators -- Spring '99 Andrew Myers