×

Close

Type:
**Note**Institute:
**
ACET/JNTUK
**Course:
**
B.Tech
**Specialization:
**Computer Science Engineering**Views:
**8**Uploaded:
**2 months ago**

Type Checking
Type checker verifies that the type of a construct (constant,
variable, array, list, object) matches what is expected in its
Computer Science 332
usage context.
E.g., Java's % (modulo) operator expects two integers, so
Compiler Construction
Chapter 6: Type Checking
(Skip 6.4)
3%4.5 is a type error.
Some operators (+, -, *, /) are "overloaded"; i.e., they can apply
to objects of different types (int, real).
Functions may be polymorphic; i.e., accept arguments of
different types.
6.1 Type Systems
Type Constructors
Type checker needs to know about
Cartesian Product: If T1 and T2 are type expressions, then
– Syntactic constructs in language (e.g., operators)
T1 X T2 is a type expression (e.g., ML tuples)
– Basic types of language (int, real)
– Rules for assigning types to constructs
Function:If T1 and T2 are type expressions, then T1
type expression (e.g., ML functions)
E.g., "if both operands of + are int, result is int"
Leads to recursively defined type expression:
– Basic type: int, real
– Type variable (α, β, ...)
– Result of applying type constructor to type expression
mod:
X
int
int
int
T2 is a

6.2 Specification of a Simple Type
Checker
Static vs. Dynamic Type Checking
Static: Done at compile time (e.g., Java)
Consider a language (e.g., Java) that requires that an identifier
Dynamic: Done at run time (e.g., Scheme)
be declared with a type before the variable is used.
Sound type system is one where any program that passes the
For simplicity, we'll declare all identifiers before using them in
static type checker cannot contain run-time type errors. Such
a single expression:
languages are said to be strongly typed.
P
D
T
E
Some errors can only be detected at run-time; e.g., array out-ofbounds:
int [] a = new int [10];
for (int i=0; i<20; ++i)
a[i] = i;
Type Checking of Statements
Add syntax-directed definitions to type-check expressions:
D
T
T
T
T id
char
int
T1 [ num ]
{ addtype (id.entry, T.type ) }
{ T.type := char }
{ T.type := integer }
{ T.type := array (0..num.val-1, T1.type ) }
E
E
id
E1 mod E2
{ E.type := lookup ( id.entry ) }
{ E.type := if E1.type = integer and
E2.type = integer then integer
E
E1 [ E2 ]
else type_error }
{ E.type := if E2.type = integer and
E1.type = array(s,t) then t
else type_error }
Where addtype, lookup are symbol-table methods, array is a
type constructor
D;E
D ; D | T id
char | int | T [ num ]
id | E mod E | E [ E ]
A more realistic language would also have statements (whose
type is trivially void )
P
D;S
S
id := E
S
if E then S1
{ S.type := if id.type = E.type then void
else type_error }
{ S.type := if E.type = boolean then S1.type
S
S1 ; S2
else type_error }
{ S.type := if S1.type = void and
S2.type = void then void
else type_error }

Type Checking of Functions
We can declare function types using a rule:
T
T1 ' ' T2 { T.type := function (T1 , T2 ) }
6.3 Equivalence of Type Expressions
Need a way of implementing checks like "E2.type = s"
Structural Equivalence: Recursive definition:
where function is another type constructor
ML supports this, but in practice function types are usually
inferred.
In either case, we need to type-check function application:
E
function sequiv(s, t) : boolean
if s and t are the same basic type then return true
else if s = array(s1, s2) and t = array(t1, t2) then
return sequiv(s1, t1) and sequiv(s2, t2)
E1 ( E2 ) { E.type := { if E2.type = s and
else if s = cartesian(s1, s2) and t = cartesian(t1, t2) then
E1.type = function(s,t) then t
return sequiv(s1, t1) and sequiv(s2, t2)
else type_error }
else if s = function(s1, s2) and t = function(t1, t2) then
return sequiv(s1, t1) and sequiv(s2, t2)
else return false
6.5 Overloading of Functions and
Operators
Some operators (+, -, *, /) are "overloaded"; i.e., they can apply to
objects of different types (int, real).
Overloading is resolved when we determine the actual type
Arguments alone do not always resolve operator's type; e.g, in
Java type of 3*5 may resolve to either int or double, depending
on context: 3*5+2 (int) or 3*5+2.0 (double)
We allow the .type attribute to be a set of types, and add code to
narrow this set to a single type for a given expression
Add an attribute .unique to contain unique type, and a special
symbol E' to support narrowing:
E'
E
E
id
E
E1 ( E2 )
{ E'.types := E.types
E.unique := if E.types = {t} then t else type_error
}
{ E.types := { lookup ( id.entry ) }
}
{ E.types := s' | ∃ s ∈ E2.types such that
function(s, s') ∈ E1.types
t := E.unique
S := { s | s ∈ E2.types and function(s,t) ∈ E1.types }
E2.unique := if S = {s} then s else type_error
E1.unique := if S = {s} then function(s,t)
else type_error
}

## Leave your Comments