Type_Checking
Document Sample


Type Checking (ASU Ch 6 Fig 6.1) Type Systems (ASU Ch 6.1)
static checks tokens syntax tree syntax tree Rules for assigning type expressions to various parts of program
Objects & types
parsing type checker in-code-gen
– strongly typed languages - object/type binding is static (compile time)
– type checks
– weakly typed languages - object/type binding is dynamic (run time)
operation <=> operator compatibility
– array indexes usually checked at run time
unique name check (in scope in symbol table)
– basic types: e.g. Boolean, char, integer, real, enumerated, (void)
de-referencing applied only to pointers
– constructed types: e.g. array, record (structure)
indexing applies only to arrays
function parameters (type + number) type expressions (may be… / may contain …) (ADT: tree / DAG )
overloaded operations (e.g +) in context / type coercion – basic types / type names / type variables / type constructors :-
polymorphism & polymorphic functions array: Ta x index => Tb
– flow-of-control checks (loop/case exits) record: (N1, T1) x … x (Nk, Tm) => Tx (cf Cartesian Product)
– object uniqueness checks (labels, scalar type elements)
pointer: Ti => pTi
– name checks (uniqueness)
function: domain => range
1 03/09/2010 DFR - CC - Type Checking 2 03/09/2010 DFR - CC - Type Checking
Simple Type Checker (ASU Ch 6.2) Type Checking of Expressions (ASU Ch 6.2 Fig 6.4)
Grammar (array indexes start at 1) translation scheme for type E => literal {E.type := char} E => E1^
P => D ; E E => num {E.type := integer}
{E.type := if E1.type = pointer(t)
D => D ; D | id : T E => id {E.type :=
P => D ; E lookup(id.entry)}
then t else type_error }
T => char | integer | num | ^T |
array[num] of T D => D ; D E => E1 mod E2
E => literal | num | id | E mod E | D => id : T {addT(id.entry, T.type)} { E.type := if E1.type = integer & E2.type = similarly T => Boolean can be
T => char { T.type := char } integer then integer else type_error }
E[E] | E^ added with appropriate rules
E => E1[E2]
basic types: char, integer (error) T => integer { T.type := integer } for ‘and, ‘<‘, ‘>’ etc. added to
{E.type := if E1.type = array(s,t) & E2.type =
constructors: array, ^ (pointer) T => ^T1 { T.type := p(T1) } integer then t else type_error } the productions for E
for char integer, T.type is T => array[num] of T1
respectively char, integer {T.type := array( 1..num.val,
value of num is num.val T1.type) }
3 03/09/2010 DFR - CC - Type Checking 4 03/09/2010 DFR - CC - Type Checking
Type Checking of Statements (ASU Ch 6.2 Fig 6.5) Type Checking of Functions (ASU Ch 6.2)
statements do not have types - application of a function to an argument E => E ( E )
type can be considered as void (or type_error) type expression rules are augmented by
adding P => D ; S to G defines a program to be declarations T => T1 ‘=>’ T2 { T.type := T1.type => T2.type }
followed by statements where => denotes a function constructor f: t.arg => t.result
statements may contain expressions hence require type checking the type checking rule becomes
rules - e.g. (TE = type_error)
E => E1 ( E2 ) { E.type := if E2 = s and E1.type = s => t then t else TE }
the type of E1 must be a function s => t from the (domain) type s of E2 to
S => id := E { S.type := if id.type = E.type then void else TE } some (range) type t; the type of E1(E2) is t
S => if E then S1 { S.type := if E.type = Boolean then S1.type else TE } n arguments T1, T2, …, Tn can be viewed a as single argument
S => while E do S1 { S.type := if E.type = Boolean then S1.type else TE } T1 x T2 x … x Tn (i.e. a cartesian product)
S => S1 ; S2 { S.type := if S1.type = void & S2.type = void then void
else TE }
5 03/09/2010 DFR - CC - Type Checking 6 03/09/2010 DFR - CC - Type Checking
Algorithm for Testing Structural Equivalence of Type Expressions
Equivalence of Type Expressions (ASU Ch 6.3) (ASU Ch 6.3 Fig 6.6)
if Ta is equivalent to Tb then return Tc else return type_error Boolean function sequiv(s, t)
what is the definition of equivalence? { if (s, t are same basic type) return true // basic type
does a name in a type expression stand for itself or is it an else if (s= array(s1, s2) and t = array(t1, t2) ) // array
abbreviation for another type expression? return sequiv(s1, t1) and sequiv(s2, t2)
name versus structural equivalence else if ( s = s1 x s2 and t = t1 x t2 ) // cartesian product
structural - as long as type expressions are built from basic types return sequiv(s1, t1) and sequiv(s2, t2)
and type constructors then E1 and E2 are either else if ( s = pointer(s1) and t = pointer(t1) ) // pointer
– the same basic type
return sequiv(s1, t1)
– OR formed by applying the same constructor to structurally
equivalent types else if ( s = s1 => s2 and t = t1 => t2 ) // function
– i.e. Ea := C(Ex) and Eb := C(Ex) (for constructor C) return sequiv(s1, t1) and sequiv(s2, t2)
– Ex can be C1(C2(…Cn(Ez))) where Ez is a basic type else return false } // error
7 03/09/2010 DFR - CC - Type Checking 8 03/09/2010 DFR - CC - Type Checking
Names for Type Expressions (ASU Ch 6.3 Ex 6.3) Names for Type Expressions (ASU Ch 6.3 Ex 6.2)
Pascal example - do link, next, last, p, q, r have identical types ? - Substitute out type expressions (variable name / type expression)
depends on the implementation !!!!
type link = ^cell; allow type expressions to be named next : link; next and last are name equivalent
var next : link; allow these names to appear in type
last : link;
last : link; expressions where only basic types
were p : pointer(cell); p, q and r have the same type
p : ^cell; previously allowed q : pointer(cell);
q, r : ^cell; e.g. cell is the name of a type r : pointer(cell);
expression
^cell is a type expression next, last, p, q, and r are structurally equivalent since link is a
name equivalence: each name is a distinct type - two type expressions name for the type expression pointer(cell)
are name equivalent iff they are identical
structural equivalence: two type expressions are structurally equivalent
if they represent two structurally equivalent type expressions when
all names have been substituted out
9 03/09/2010 DFR - CC - Type Checking 10 03/09/2010 DFR - CC - Type Checking
Names for Type Expressions (ASU Ch 6.3 Ex 6.3) Type Conversions (ASU Ch 6.4)
Pascal example - implicit type names (implementation dependent) Consider real x; integer i ; x + i ; the language definition
every time a variable declaration contains a type expression that must specify what happens
is not a name (anonymous type), an implicit name is created by type checker is used to insert conversion operations into the
the compiler intermediate code
type link = ^cell => type link = ^cell; name – x + i => x i inttoreal real+ (postfix)
equivalence – in assignment statements, type(RHS) is converted to type(LHS)
var next : link; np = ^cell; next & last overloading - a symbol with different meanings (depends on
last : link; npr = ^cell; q&r context)
p : ^cell; var next : link; not p & q – e.g. + => integer+, real+, possible complex+
q, r : ^cell; last : link; var x, y : ^cell; conversion
p : np; is not the same – implicit (coercion): performed automatically by the compiler
as
– explicit: performed by the programmer e.g. Pascal ord(c), chr(i)
see ASU Fig 6.7 for type q : npr; var x : ^cell;
– Ada: almost all conversions are explicit; C char => integer is implicit
graph representation r : npr; var y : ^cell;
11 03/09/2010 DFR - CC - Type Checking 12 03/09/2010 DFR - CC - Type Checking
Type Checking Rules: Integer to Real Coercion Overloading of Functions and Operators (ASU
(ASU Ch 6.4 Fig 6.9) Ch 6.5)
E => num E.type := integer e.g. + => real+, integer+, …, unary, binary (especially Ada)
E => num.num E.type := real ( ) => array indexing, function arguments (Ada)
E => id E.type := lookup(id.entry) resolution of overloading
E => E1 op E2 E.type := if E1.type = integer & E2.type = integer
– an unique meaning for the overloaded symbol(s) is (are) determined
then integer
– also called operator identification
else if if E1.type = integer & E2.type = real
arithmetic operators are usually overloaded in most PLs
then real
– E => E1 op E2 check the possible types of E1 and E2 (as above)
else if if E1.type = real & E2.type = integer
sub-expressions may have a set of possible types
then real
– Ada: operator ‘*’ : integer x integer => integer
else if if E1.type = real & E2.type = real
operator ‘*’ : real x real => real
then real
– user function ‘*’ : integer x integer => complex
else type_error
defined: function ‘*’ : complex x complex => complex
13 03/09/2010 DFR - CC - Type Checking 14 03/09/2010 DFR - CC - Type Checking
Overloading of Functions and Operators (ASU Narrowing the Set of Possible Types (ASU Ch 6.5
Ch 6.5 Fig 6.11) Fig 6.12)
3 * 5 may have result type integer or complex Production Semantic rule
– 2 * (3 * 5) => integer result E’ => E E’.types : := E.types
– (3 * 5) * z => complex result (if z is complex) E.unique := if E’.types = {t} then t else type_error
generalisation to sets of types E’.code := E.code
E’ => E E’.types := E.types E => id E.types := lookup(id.entry)
E => id E.types := lookup(id.entry) E.code := gen(id.lexeme ‘:’ E.unique)
E => E1 (E2) E.types := { t | ∃ s in E2.types s.t. s => t is in E1.types } E => E1 ( E2 ) E.types := { s’ | ∃ s in E2.types s.t. s => s’ is in E1.types }
Ada example: 3 * 5 where ‘*’ is defined above t := E.unique
3 {i} * { i x i => i, i x i => c, c x c => c } 5 {i} S := { s | s in E2.types and s => t in E1.types }
E {i} * { i x i => i, i x i => c, c x c => c } E {i} E2.unique := if S = {s} then s else type_error
E {i, c} E1.unique := if S = {s} then s => t else type_error
E.code := E1.code || E2.code || gen(‘apply’ ‘:’ E.unique)
15 03/09/2010 DFR - CC - Type Checking 16 03/09/2010 DFR - CC - Type Checking
Get documents about "