You are on page 1of 17

Type checking

A source program should follow both the


syntactic and semantic rules of the source
language.
Compiler must check that the source
program follows both the syntactic and
semantic conventions of the source
language.
Static checks - reported during the
compilation phase.
Dynamic checks - occur during the
execution of the program
Static Check
Static checking includes the syntax checks
performed by the parser and semantic
checks such as
Type checks (A compiler should report
an error if an operator is applied to an
incompatible operand.)
Flow-of-control checks (break statement)
Uniqueness checks (uniquely declared
identifier)
Name-related checks
Here we focus on type checking


Use of Type

Virtually all high-level programming languages
associate types with values.
Types often provide an implicit context for
operations.
In C the expression x + y will use integer addition if x
and y are int's, and floating-point addition if x and y
are float's.
Types can catch programming errors at compile time
by making sure operators are applied to semantically
valid operands.
For example, a Java compiler will report an error if x
and y are String's in the expression x * y.

Type
A type is a set of values together with a set
of operations that can be performed on them
The purpose of type checking is to verify
that operations performed on a value are in
fact permissible
The type of an identifier is typically
available from declarations, but we may
have to keep track of the type of
intermediate expressions
5
Type system
Languages can be divided into three categories with
respect to the type:

untyped
No type checking needs to be done
Assembly languages

Statically typed
All type checking is done at compile time
Algol class of languages
Also, called strongly typed

Dynamically typed
Type checking is done at run time
Mostly functional languages like Lisp, Scheme etc.
Type System
Basic types are atomic types that have no internal structure
as far as the programmer is concerned.
Each operator and expression in a program has
Basic types like integer, real, boolean, and character.
Subrange types like 1..10 in Pascal and enumerated
types like (violet, indigo, blue, green, yellow, orange,
red) are also basic types.
Constructed types include arrays, records, sets, and
structures constructed from the basic types and/or other
constructed types.
Pointers and functions are also constructed types.
A type system is a collection of rules for assigning type
expression to variables
Type checker implements the type system
Position of type checker




Notes: 1)A type checker verifies that the type of a
construct matches that expected by its context.
2)Type information gathered by a type checker may
be needed when code is generated.
The design of a type checker for a language is based
on the information about the syntactic constructs in
the language.
Each expression has a type associated with it.

parser
Token
stream
Type
checker
Syntax
tree
Intermedi
ate code
generator
Syntax
tree
Intermediate
representation
8
Type Checking

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.
string x;int y;
y = x + 3
the use of x is a type error


Information gathered by a type checker:
Needed during code generation.
9
Type Expression
The type of a language construct is denoted by a type expression.
A type expression can be:
A basic type
a primitive data type such as integer, real, char, boolean,
void : no type
A type name
a name can be used to denote a type expression.
A type constructor applies to other type expressions.
arrays: If T is a type expression, then array(I,T) is a type expression where I
denotes index range. Ex: array(0..99,int)
products: If T
1
and T
2
are type expressions, then their cartesian product T
1
x T
2
is
a type expression. Ex: int x int
pointers: If T is a type expression, then pointer(T) is a type expression. Ex:
pointer(int)
functions: We may treat functions in a programming language as mapping from a
domain type D to a range type R. So, the type of a function can be denoted by the
type expression DR where D are R type expressions. Ex: intint represents
the type of a function which takes an int value as parameter, and its return type is
also int.
Type Expression
Char eg:static check
array(char)
ptr(array(char))
ptr(ptr(array(char)))
The array type int [2] [3] can be read as
"array of 2 array of 3 integers each" and
written as a type expression
array( 2, array(3, integer)).
int a, b[10], c;

a = b + c;

Type Checking is the process of verifying fully typed programs
Type Inference is the process of filling in missing type information.

E.g., result types for x + y:


+ int float
int int float
float float float
Simple Type Checker
A type checker has two kinds of actions:
(1) when processing declarations it stores the appropriate type
expressions in the symbol table entries of ID tokens;
(2) when processing statements it checks that all ID tokens,
constants, etc., are of the proper types.






Type Checking and Type Inference
12
Type checking for expressions
E num E.type = int
E num.num E.type = real
E id E.type = lookup( id.entry )

E E
1
op E
2
E.type = if E
1
.type == int && E
2
.type == int
then int
elseif E
1
.type == int && E
2
.type == real
then real
elseif E
1
.type == real && E
2
.type == int
then real
elseif E
1
.type == real && E
2
.type==real
then real


Specification of a Simple Type Checker
Type Checking of Statements
S if E then S
1

{S.type= if (E.type==boolean) S
1
.type else
type_error}

Specification of a Simple Type Checker
Type Checking of Statements
S while E do S
1

{S.type= if (E.type==boolean) S
1
.type else
type_error}
16
Equivalence of Type expression
Structural equivalence: Two type expressions are
equivalent if
either these are same basic types
or these are formed by applying same constructor to
equivalent types
Name equivalence: types can be given names
Two type expressions are equivalent if they have the
same name
Type Conversions

Implicit type conversions
In an expression such as f + i where f is a float and i is an integer, a
compiler must first convert the integer to a float before the floating
point addition operation is performed. That is, the expression must be
transformed into an intermediate representation like
t1 = INTTOFLOAT i
t2 = x FADD t1

Explicit type conversions
In C, explicit type conversions can be forced ("coerced") in an
expression using a unary operator called a cast. E.g., sqrt((double) n)
converts the value of the integer n to a double before passing it on to
the square root routine sqrt.