Type_Checking by xuyuzhu

VIEWS: 2 PAGES: 4

									    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

								
To top