0% found this document useful (0 votes)
41 views28 pages

Type Checking

The document discusses type checking in compiler design. It begins with an overview of static semantic checks done by a compiler, including type checks to ensure operands are compatible. It then discusses type checking in more detail, including representing type expressions as trees or DAGs, defining type systems with grammars, and algorithms for type checking expressions and statements. It also covers more advanced topics such as equivalence of type expressions, recursive types, overloading, polymorphic functions, and using substitutions and unification in type checking.

Uploaded by

gdayanand4u
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
41 views28 pages

Type Checking

The document discusses type checking in compiler design. It begins with an overview of static semantic checks done by a compiler, including type checks to ensure operands are compatible. It then discusses type checking in more detail, including representing type expressions as trees or DAGs, defining type systems with grammars, and algorithms for type checking expressions and statements. It also covers more advanced topics such as equivalence of type expressions, recursive types, overloading, polymorphic functions, and using substitutions and unification in type checking.

Uploaded by

gdayanand4u
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 28

Compiler Design

Type Checking

Winter 2010

Static Checking
Abstract Syntax Tree Decorated Abstract Syntax Tree

Token Stream

Parser

Static Checker

Intermediate Code Generator

Intermediate Code

Static (Semantic) Checks


Type checks: operator applied to incompatible operands? Flow of control checks: break (outside while?) Uniqueness checks: labels in case statements Name related checks: same name?

Winter 2010

based on CSE 504, Stony Brook University

Type Checking

Problem: Verify that a type of a construct matches that expected by its context. Examples: mod requires integer operands (PASCAL) * (dereferencing) applied to a pointer a[i] indexing applied to an array f(a1, a2, , an) function applied to correct arguments. Information gathered by a type checker: Needed during code generation.
based on CSE 504, Stony Brook University 3

Winter 2010

Type Systems

A collection of rules for assigning type expressions to the various parts of a program. Based on: Syntactic constructs, notion of a type. Example: If both operators of +, -, * are of type integer then so is the result. Type Checker: An implementation of a type system. Syntax Directed. Sound Type System: eliminates the need for checking type errors during run time.

Winter 2010

based on CSE 504, Stony Brook University

Type Expressions

Implicit Assumptions:

Each program has a type Types have a structure Basic Types

Expressions Statements

Type Constructors
Arrays (strings) Records Sets Pointers Functions
5

Boolean Real

Enumerations Sub-ranges

Character integer Error Names

Void Variables

Winter 2010

based on CSE 504, Stony Brook University

Representation of Type Expressions


cell = record x x char char pointer integer x char pointer integer x x ptr

info int next


struct cell { int info;

Tree

DAG

(char x char) pointer (integer)

struct cell * next; };

Winter 2010

based on CSE 504, Stony Brook University

Type Expressions Grammar


Type int | float | char | | void | error | name | variable | array( size, Type) | record( (name, Type)*) | pointer( Type) | tuple((Type)*) | fcn(Type, Type)
Winter 2010

Basic Types

Structured Types

(Type Type)
7

based on CSE 504, Stony Brook University

A Simple Typed Language


Program Declaration; Statement Declaration Declaration; Declaration | id: Type Statement Statement; Statement | id := Expression | if Expression then Statement | while Expression do Statement Expression literal | num | id | Expression mod Expression | E[E] | E | E (E)
Winter 2010 based on CSE 504, Stony Brook University 8

Type Checking Expressions


E int_const E float_const E id E E 1 + E2
{ E.type = int } { E.type = float }

{ E.type = sym_lookup(id.entry, type) } {E.type = if E1.type {int, float} | E2.type {int, float}) then error else if E1.type == E2.type == int then int else float }

Winter 2010

based on CSE 504, Stony Brook University

Type Checking Expressions


E E1 [E2] E *E1 E &E1 E E1(E2)
{E.type = if E1.type = array(S, T) E2.type = int then T else error} {E.type = if E1.type = pointer(T) then T else error}

{E.type = pointer(E1.type)}
{E.type = if (E1.type = fcn(S, T) E2.type = S, then T else error} {E.type = tuple(E1.type, E2.type)}
10

E (E1, E2)
Winter 2010

based on CSE 504, Stony Brook University

Type Checking Statements


S id := E S if E then S1 S while E do S1 S S1; S2
Winter 2010

{S.type := if id.type = E.type then void else error} {S.type := if E.type = boolean then S1.type else error} {S.type := if E.type = boolean then S1.type}

{S.type := if S1.type = void S2.type = void then void else error}


11

based on CSE 504, Stony Brook University

Equivalence of Type Expressions


Problem: When in E1.type = E2.type?

Example:

We need a precise definition for type equivalence Interaction between type equivalence and type representation
type vector = array [1..10] of real type weight = array [1..10] of real var x, y: vector; z: weight

Name Equivalence: When they have the same name. x, y have the same type; z has a different type. Structural Equivalence: When they have the same structure. x, y, z have the same type.
Winter 2010 based on CSE 504, Stony Brook University 12

Structural Equivalence

Definition: by Induction

Same basic type Same constructor applied to SE Type Same DAG Representation

(basis) (induction step)

In Practice: modifications are needed


Do not include array bounds when they are passed as parameters Other applied representations (More compact) Does not check for cycles Later improve it.

Can be applied to: Tree/ DAG


Winter 2010

based on CSE 504, Stony Brook University

13

Algorithm Testing Structural Equivalence


function sequiv(s, t): boolean { if (s t are of the same basic type) return true; if (s = array(s1, s2) t = array(t1, t2)) return sequiv(s1, t1) sequiv(s2, t2); if (s = tuple(s1, s2) t = tuple(t1, t2)) return sequiv(s1, t1) sequiv(s2, t2); if (s = fcn(s1, s2) t = fcn(t1, t2)) return sequiv(s1, t1) sequiv(s2, t2); if (s = pointer(s1) t = pointer(t1)) return sequiv(s1, t1); }

Winter 2010

based on CSE 504, Stony Brook University

14

Recursive Types
Where: Linked Lists, Trees, etc. How: records containing pointers to similar records Example: type link = cell; cell = record info: int; next = link end Representation: cell = record x x x ptr cell x cell = record x x ptr

info int next DAG with Names


Winter 2010

info int next

Substituting names out (cycles)


15

based on CSE 504, Stony Brook University

Recursive Types in C

C Policy: avoid cycles in type graphs by: Using structural equivalence for all types Except for records name equivalence Example:

Name use: name cell becomes part of the type of the record.

struct cell {int info; struct cell * next;}

Use the acyclic representation Names declared before use except for pointers to records. Cycles potential due to pointers in records Testing for structural equivalence stops when a record constructor is reached ~ same named record type?
based on CSE 504, Stony Brook University

Winter 2010

16

Overloading Functions & Operators

Overloaded Symbol: one that has different meanings depending on its context Example: Addition operator + Resolving (operator identification): overloading is resolved when a unique meaning is determined. Context: it is not always possible to resolve overloading by looking only the arguments of a function Set of possible types Context (inherited attribute) necessary
based on CSE 504, Stony Brook University 17

Winter 2010

Overloading Example
function * (i, j: integer) return complex; function * (x, y: complex) return complex; * Has the following types: fcn(tuple(integer, integer), integer) fcn(tuple(integer, integer), complex) fcn(tuple(complex, complex), complex) int i, j; k = i * j;
Winter 2010 based on CSE 504, Stony Brook University 18

Narrowing Types
E E E id E E1(E2)
{E.types = E. types {E.types = lookup(id.entry)} {E.types = {s' | s E2.types and ss E1.types} t = E.unique S = {s | s E2.types and St E1.types} E2.unique = if S ={s} then S else error E1.unique = if S = {s} then St else error
Winter 2010 based on CSE 504, Stony Brook University 19

E.unique = if E.types = {t} then t else error}

Polymorphic Functions

Defn: a piece of code (functions, operators) that can be executed with arguments of different types. Examples: Built in Operator indexing arrays, pointer manipulation Why use them: facilitate manipulation of data structures regardless of types. Example ML: fun length(lptr) = if null (lptr) then 0 else length(+l(lptr)) + 1
based on CSE 504, Stony Brook University 20

Winter 2010

A Language for Polymorphic Functions


PD;E D D ; D | id : Q Q . Q | T T fcn (T, T) | tuple (T, T) | unary (T) | (T) | basic | E E (E) | E, E | id
Winter 2010 based on CSE 504, Stony Brook University 21

Type Variables

Why: variables representing type expressions allow us to talk about unknown types.

Use Greek alphabets , ,

Application: check consistent usage of identifiers in a language that does not require identifiers to be declared before usage.

A type variable represents the type of an undeclared identifier.

Type Inference Problem: Determine the type of a language constant from the way it is used.

We have to deal with expressions containing variables.


based on CSE 504, Stony Brook University 22

Winter 2010

Examples of Type Inference


Type link cell; Procedure mlist (lptr: link; procedure p); { while lptr <> null { p(lptr); lptr := lptr .next}} Hence: p: link void Function deref (p) { return p ; } P: , = pointer() Hence deref: . pointer()

Winter 2010

based on CSE 504, Stony Brook University

23

Program in Polymorphic Language


deref: . pointer() q: pointer (pointer (integer)) deref (deref( (q)) Notation: fcn x tuple
q: pointer (pointer (integer)) deref0: pointer (0 ) 0 derefi: pointer (i ) i apply: i apply: 0

Subsripts i and o distinguish between the inner and outer occurrences of deref, respectively.

Winter 2010

based on CSE 504, Stony Brook University

24

Type Checking Polymorphic Functions

Distinct occurrences of a p.f. in the same expression need not have arguments of the same type.

deref ( deref (q)) Replace with fresh variable and remove (i, o)

The notion of type equivalence changes in the presence of variables.

Use unification: check if s and t can be made structurally equivalent by replacing type vars by the type expression.

We need a mechanism for recording the effect of unifying two expressions.

A type variable may occur in several type expressions.


based on CSE 504, Stony Brook University

Winter 2010

25

Substitutions and Unification


Substitution S: a mapping from type variables to type expressions. Function aplly (t: type Expr, S: Substitution): type Expr { if (t is a basic type) return t; if (t is a variable) return S(t); -- check if t S if (t is t1 t2) return (apply (t1) apply (t2)); }

Instance: S(t) is an instance of t written S(t) < t. Examples: pointer (integer) < pointer () , int real Unify: t1 t2 if S. S (t1) = S (t2) Most General Unifier S: A substitution S: S (t ) = S (t ) 1 2 S. S (t ) = S (t ) t. S(t) < S(t). 1 2
based on CSE 504, Stony Brook University 26

Winter 2010

Polymorphic Type checking Translation Scheme


E E1 (E2) { p := mkleaf(newtypevar); E.type = p} E E1, E2 E id unify (E1.type, mknode(, E2.type, p);

{E.type := mknode(x, E1.type, E2.type); } { E.type := fresh (id.type) }

fresh (t): replaces bound variables in t by fresh variables. Returns pointer to a node representing result type. fresh( .pointer() ) = pointer(1) 1. unify (m, n): unifies expressions represented by m and n.

Side-effect: keep track of substitution Fail-to-unify: abort type checking.


based on CSE 504, Stony Brook University

Winter 2010

27

PType Checking Example


Given: derefo (derefi (q)) q = pointer (pointer (int)) Bottom Up: fresh (. Pointer() )
derefo : 3 pointer : 2 derefi q : 6 pointer : 5 pointer : 9 pointer : 8 integer : 7 n : 6 pointer : 5 pointer : 8 integer : 7
28

: 3 pointer : 2

: 1

o : 1
: 3 pointer : 2

i : 4
m : 6 pointer : 5

: 8

o : 1
Winter 2010

i : 4

based on CSE 504, Stony Brook University

You might also like