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.