0% found this document useful (0 votes)
42 views

Type Checking: By:Vishnu Kumar Gehlot

This document describes type checking in programming languages. It discusses: - Static type checking verifies that types of constructs match their context - A type checker implements a type system with rules assigning types to program parts - Type expressions represent types like basic types, arrays, pointers, and functions - The type system eliminates runtime type errors if it is sound

Uploaded by

vishnugehlot
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 PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
42 views

Type Checking: By:Vishnu Kumar Gehlot

This document describes type checking in programming languages. It discusses: - Static type checking verifies that types of constructs match their context - A type checker implements a type system with rules assigning types to program parts - Type expressions represent types like basic types, arrays, pointers, and functions - The type system eliminates runtime type errors if it is sound

Uploaded by

vishnugehlot
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 PPT, PDF, TXT or read online on Scribd
You are on page 1/ 16

Type Checking

By:Vishnu Kumar Gehlot


Static Checking

Abstract Decorated Intermediate


Token Syntax Static Abstract Intermediate
Parser Code
Stream Tree Checker Syntax Code
Tree Generator

 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?
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.
Type Checking
 A type checker implements a type system.
 A sound type system eliminates run-time type
checking for type errors.
 A programming language is strongly-typed, if every
program its compiler accepts will execute without
type errors.
 In practice, some of type checking operations

are done at run-time (so, most of the


programming languages are not strongly-typed).
 Ex: int x[100]; … x[i]  most of the
compilers cannot guarantee that i will be
between 0 and 99
Type Checking
 A compiler has to do semantic checks in addition
to syntactic checks.
 Semantic Checks
 Static – done during compilation

 Dynamic – done during run-time

 Type checking is one of these static checking


operations.
 we may not do all type checking at compile-time.

 Some systems also use dynamic type checking

too.
 A type system is a collection of rules for assigning
type expressions to the parts of a program.
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.
Type Expressions
 Implicit Assumptions: Expressions
 Each program has a type
Statements
 Types have a structure

Basic Types Type Constructors


Boolean Character Arrays
Real Integer Records
Enumerations Sub-ranges Sets
Void Error Pointers
Variables Names Functions
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, …
 type-error to signal a type error
 void : no type
 A type name
 a name can be used to denote a type
expression.
Type constructors
 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 T1 and T2 are type expressions,
then their cartesian product T1 x T2 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)
Type Constructors
 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
D→R where D are R type expressions. Ex:
int→int represents the type of a function which
takes an int value as parameter, and its return
type is also int
Representation of Type
Expressions
cell = record
-> ->
x

x pointer x pointer x x

char char integer char integer info int next ptr

struct cell {
Tree DAG int info;
struct cell * next;
(char x char)-> pointer (integer) };
A Simple Type Checking
System
P → D;E

D → D;D
D → id:T { addtype(id.entry,T.type) }
T → char { T.type=char }
T → int { T.type=int }
T → real { T.type=real }
T → ↑T1 { T.type=pointer(T1.type) }
T → array[intnum] of T1 {
T.type=array(1..intnum.val,T1.type) }
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)
Type Checking of
Expressions

E id
→ { E.type=lookup(id.entry) }
E charliteral
→ { E.type=char }
E intliteral
→ { E.type=int }
E realliteral { E.type=real }

E E1 + E2
→ { if (E1.type=int and E2.type=int) then E.type=int
else if (E1.type=int and E2.type=real) then E.type=real
else if (E1.type=real and E2.type=int) then E.type=real
else if (E1.type=real and E2.type=real) then
E.type=real else E.type=type-error }
E → E1 [E2] { if (E2.type=int and E1.type=array(s,t)) then E.type=t
else E.type=type-error }
E → E1 ↑ { if (E1.type=pointer(t)) then E.type=t
else E.type=type-error }
Type Checking of
Statements
S  id = E { if (id.type=E.type then
S.type=void
else S.type=type-error }

S  if E then S1 { if (E.type=boolean then


S.type=S1.type
else S.type=type-error }
S  while E do S1 { if (E.type=boolean then
S.type=S1.type
else S.type=type-error }
Type Checking of Functions
E  E1 ( E2 ) { if (E2.type=s and E1.type=st) then
E.type=t
else E.type=type-error }

Ex: int f(double x, char y) { ... }

f: double x char  int

argument types return type

You might also like