Survey
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
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
2
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
3
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
4
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
5
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
6
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
7
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
8
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
9
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
10
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
11
Type Expressions: Arrays
• Different languages have various kinds of
array types
• w/o bounds: array(T)
– C, Java: T[ ], Modula-3: array of T
• size: array(T, L) (may be indexed 0..L-1)
– C: T[L], Modula-3: array[L] of T
• 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
12
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
13
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
14
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
15
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
16
Inference Rules
• For more complex expressions, need to
know type of sub-expressions
• “In any context A, for any expressions E1
and E2 that have type int, the expression
E1 + E2 has the type int”
A |– E1 : int
Antecedents
Inference rule
A |– E2 : int
Consequent
A |– E1 + E2 : int
CS 412/413 Introduction to
Compilers and Translators -- Spring
17
Implementing a rule
• Work backward from goal:
T = E.typeCheck(A)
==
A |– E : T
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
18
Inference Rules
• Rules are implicitly universally quantified
over free variables: A |– true : bool
• Same goal judgment may be provable in
more than one way:
A |– E1 : float
A |– E2 : float
A |– E1 + E2 : float
A |– E1 : float
A |– E2 : int
A |– E1 + E2 : float
CS 412/413 Introduction to
Compilers and Translators -- Spring
19
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
20
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
21
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
22
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
23
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
24
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
25
Sequence
• Rule: A sequence of two statements is typesafe 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
26
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
27
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
28
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
29
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
30
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
31