Lecture - PowerPoint PPT Presentation

About This Presentation
Title:

Lecture

Description:

Writing type-checkers in ML. Role of type rules. Representing types. Representing ... We build type checkers as attribute computations. We need to think ahead. ... – PowerPoint PPT presentation

Number of Views:25
Avg rating:3.0/5.0
Slides: 35
Provided by: timsh3
Learn more at: http://web.cecs.pdx.edu
Category:
Tags: checkers | lecture

less

Transcript and Presenter's Notes

Title: Lecture


1
Lecture 14, Feb. 28, 2007
  • Writing type-checkers in ML
  • Role of type rules
  • Representing types
  • Representing programs
  • Handling errors
  • Guessing types
  • Declarations
  • Let expressions

2
Type Checkers in ML
  • To build type-checkers in ML we need
  • A datatype to represent types
  • A datatype (or datatypes) to represent programs
    (whose type we are checking)
  • Expressions
  • Statements
  • Declarations
  • A means for computing equality over types
  • A means for expressing type errors
  • We build type checkers as attribute computations
  • We need to think ahead.
  • An attribute computation for each datatype
    representing programs
  • What are the inherited and synthesized attributes
    for each datatype
  • What will the type of the functions that
    implement each attribute computation.
  • Will we simply compute a type, or will we
    decorate the syntax tree?

3
The role of type rules
  • Type rules play an important role.
  • They are short and concise
  • They are used as a communication mechanism.
  • S - x a
  • S - f a -gt t
  • ------------------
  • S - f x t
  • Normally, the context is an inherited attribute,
    and the result is a synthesized attribute

4
Representing Types
  • datatype MLtype
  • Unit
  • Int
  • Char
  • Bool
  • Product of MLtype list
  • Arrow of (MLtype MLtype)

5
Representing Programs 1
  • datatype Op Plus Less And
  • datatype Constant
  • Cint of int ( 5 )
  • Cchar of char ( z )
  • Cbool of bool ( true )
  • and Dec
  • Valdec of stringExp
  • ( let val x 5 in x end )
  • Fundec of stringstringMLtypeExp
  • ( let fun f (xint) x 1 in f end )

6
Representing Programs 2
  • datatype Exp
  • Lit of Constant ( 5 )
  • Var of string ( x )
  • App of ExpExp ( f x )
  • Tuple of Exp list ( (x,3,true) )
  • Infix of ExpOpExp ( x3 )
  • Stmt of Exp list ( (print x 3) )
  • If of Exp Exp Exp ( if x then y else 3
    )
  • While of Exp Exp ( while x do (f x) )
  • Anonfun of string MLtype Exp
  • ( (fn x gt x1) )
  • Let of DecExp ( let val x 1 in x end )

7
Type Equality
  • fun typeeq (x,y)
  • case (x,y) of
  • (Void,Void) gt true
  • (Int,Int) gt true
  • (Char,Char) gt true
  • (Bool,Bool) gt true
  • (Arrow(d1,r1),Arrow(d2,r2)) gt typeeq(d1,d2)
    andalso
  • typeeq(r1,r2)
  • (Product(ss),Product(ts)) gt (listeq ss ts)
  • (_,_) gt false
  • and listeq (xxs) (yys)
  • typeeq(x,y) andalso listeq xs ys
  • listeq true
  • listeq _ _ false

8
Expressing Errors
  • In ML we are lucky to have a rich exception
    mechanism.
  • We could use one exception for each kind of type
    error.
  • Or we could have a general purpose exception that
    carried specific information about the error.
  • Or something in between.
  • We use the second approach
  • exception TypeError of Expstring
  • fun error e s raise(TypeError (e,s))

9
Functions to report errors
  • fun showt Unit "()"
  • showt Int "int"
  • showt Char "char"
  • showt Bool "bool"
  • showt (Product ts)
  • let fun showeach ""
  • showeach x showt x
  • showeach (xxs)
  • (showt x)""(showeach xs)
  • in "("(showeach ts)")" end
  • fun unexpected r t1 t2
  • error r ("Found type "
  • (showt t1)
  • " expecting type "
  • (showt t2))

10
Thinking ahead
  • We have 4 different datatypes that represent
    programs
  • Op
  • Constant
  • Exp
  • Dec
  • What attributes will each have?
  • Two kinds of attributes in this case types and
    contexts
  • Types MLtyp
  • Context (stringMLtype) list
  • Inherited or Synthesized?
  • Op synthesized (MLtype
    MLtype MLtype)
  • Constant synthesized MLtype
  • Exp inherited (stringMLtype) list
  • synthesized MLtype
  • Dec inherited (stringMLtype) list
  • synthesized ( MLtype
    (stringMLtype) list)

11
Types of programs implementing the attribute
computations
  • TCOp OP -gt (MLtype MLtype MLtype)
  • TCConstant Constant -gt MLtype
  • TCExp Exp -gt
  • (stringMLtype) list -gt
  • MLtype
  • TCDec Dec -gt
  • (stringMLtype) list -gt
  • (MLtype (stringMLtype) list)

12
Operators
  • fun TCOp Plus (Int,Int,Int)
  • TCOp Less (Int,Int,Bool)
  • TCOp And (Bool,Bool,Bool)

Left argument
Result type
Right argument
13
Constants
  • fun TCConstant (Cint n) Int
  • TCConstant (Cchar c) Char
  • TCConstant (Cbool t) Bool

Note that the value of the constant, has nothing
to do with its type. E.g. Both 4 and 12 have
type Int
14
Variables
  • (S x) t
  • ---------------------
  • S - x t (where x is a variable)
  • fun TCExp x cntxt
  • case x of
  • Var s gt
  • (case List.find (fn (nm,t) gt nms) cntxt of
  • SOME(nm,t) gt t
  • NONE gt error x "Undeclared variable")

15
Constants
  • S - n int (where n an integer constant
    like 5 or 23)
  • S - c char (where c character constant
    like a )
  • S - b bool (where b boolean like true or
    false)
  • fun TCConstant (Cint n) Int
  • TCConstant (Cchar c) Char
  • TCConstant (Cbool t) Bool
  • fun TCExp x cntxt
  • case x of
  • Lit c gt TCConstant c

16
Infix expressions
S - x t1 S - y t2 (S ltgt) t1 t2 -gt
t3 ----------------------------- where ltgt
is a binary operator like or S - x ltgt y
t3 fun TCExp x cntxt case x of
Infix(l,x,r) gt let val ltype TCExp l
cntxt val rtype TCExp r cntxt
val (lneed,rneed,result) TCOp x in case
(typeeq(ltype,lneed)
,typeeq(rtype,rneed)) of (true,true) gt
result (true,false) gt unexpected r
rtype rneed (false,true) gt unexpected
l ltype lneed (false,false) gt
unexpected l ltype lneed end

Notice how sub expressions are type-checked
first, then the result type is computed from
those results
17
The Big picture
  • fun TCExp x cntxt
  • case x of
  • Lit c gt TCConstant c
  • Var s gt
  • (case List.find (fn (nm,t) gt nms) cntxt of
  • SOME(nm,t) gt t
  • NONE gt error x "Undeclared variable")
  • Infix(l,x,r) gt
  • let val ltype TCExp l cntxt
  • val rtype TCExp r cntxt
  • val (lneed,rneed,result) TCOp x
  • in case (typeeq(ltype,lneed)
  • ,typeeq(rtype,rneed)) of
  • (true,true) gt result
  • (true,false) gt unexpected r rtype
    rneed
  • (false,true) gt unexpected l ltype
    lneed
  • (false,false) gt unexpected l ltype
    lneed
  • end

18
Function calls
  • S - x a
  • S - f a -gt t
  • ----------------------
  • S - f x t
  • fun TCExp x cntxt
  • case x of
  • App(f,x) gt
  • let val ftype TCExp f cntxt
  • val xtype TCExp x cntxt
  • in case ftype of
  • Arrow(dom,rng) gt
  • if ( typeeq(dom,xtype) )
  • then rng
  • else unexpected x xtype dom
  • other gt error f ("the type "
  • showt other
  • " is not a
    function")
  • end

Note how the domain of the function must have the
same type as the actual argument.,
19
ML statement types
  • S - ei ai S en t
  • --------------------------------------
  • S - (e1 en) t
  • fun TCExp x cntxt
  • case x of
  • Stmt xs gt
  • let val xstypes List.map
  • (fn x gt TCExp x cntxt) xs
  • fun last x x
  • last (xxs) last xs
  • last error x "Tuple with no
    elements"
  • in last xstypes end

20
ML tuples
  • S - ei ti
  • --------------------------------------
  • S - (e1, ,en) (t1 tn)
  • fun TCExp x cntxt
  • case x of
  • Tuple xs gt
  • let val xstypes
  • List.map (fn x gt TCExp x cntxt) xs
  • in Product xstypes end

21
If expressions
  • S - x bool S y t
  • S - z t
  • ---------------------------------------
  • S - if x then y else z t
  • fun TCExp x cntxt
  • case x of
  • If(x,y,z) gt
  • let val xtype TCExp x cntxt
  • val ytype TCExp y cntxt
  • val ztype TCExp z cntxt
  • in case xtype of
  • Bool gtif (typeeq(ytype,ztype))
  • then ytype
  • else unexpected y ytype
    ztype
  • other gt error x ("the type "
  • showt other
  • " is not boolean")

22
ML while stmt
  • S - e bool S - s a
  • ------------------------------
  • S - while e do s unit
  • fun TCExp x cntxt
  • case x of
  • While(test,body) gt
  • let val ttype TCExp test cntxt
  • val btype TCExp body cntxt
  • in case ttype of
  • Bool gt Unit
  • other gt unexpected test ttype Bool
  • end

23
ML anonymous function types
  • S(x,a) - e b
  • ------------------------------
  • S - (fn (xa) gt e) a -gt b
  • fun TCExp x cntxt
  • case x of
  • Anonfun(x,t,body) gt
  • let val btype TCExp body ((x,t)cntxt)
  • in Arrow(t,btype) end

S(x,a) means add the mapping of variable x to
the type a to the table S. If S already has a
mapping for x, then overwrite it with a
Note, how for the first time, the context, which
is an inherited attribute, gets bigger as it
flows down the syntax tree into the body
24
Handling declarations
  • Declarations are interesting because they have
    contexts as both synthesized and inherited
    attributes.
  • Consider
  • Let fun f x x 9
  • In 3 f 4 end
  • The context flows into (fun f x x9), but a
    new context also flows out of it with a new
    typing for f so that the new context can flow
    into (3 f 4)
  • TCDec Dec -gt
  • (stringMLtype) list -gt
  • (MLtype (stringMLtype) list)

25
  • and TCDec (Valdec(nm,exp)) cntxt
  • let val nmtype TCExp exp cntxt
  • in (nmtype,(nm,nmtype)cntxt) end
  • TCDec (Fundec(nm,arg,argtype,body)) cntxt
  • let val bodytype TCExp body
  • ((arg,argtype)cntx
    t)
  • val nmtype Arrow(argtype,bodytype)
  • val newcntxt (nm,nmtype)cntxt
  • in (nmtype,newcntxt) end

Note, recursive functions would need a different
strategy
26
Let expressions
  • fun TCExp x cntxt
  • case x of
  • Let(d,b) gt
  • let val (_,cntxt2) TCDec d cntxt
  • val btype TCExp b cntxt2
  • in btype end

27
Guessing types
  • Recall the type constructor for anonymous
    functions
  • Anonfun(x,t,body)
  • Note in real ML the type of the argument is not
    given.
  • The type is computed from the context it is used
    inside of body.
  • In order to guess we must initialize the table
    with an empty slot, and then fill it in later.

28
Represent types
  • datatype MLtype
  • Unit
  • Int
  • Char
  • Bool
  • Product of MLtype list
  • Arrow of (MLtype MLtype)
  • Tvar of (MLtype option) ref
  • Think of the ref as a pointer (ref NONE) is a
    null pointer. (ref (SOME x)) is a pointer to x

A mutable reference we can overwrite later.
29
We must be careful
Tvar(ref (SOME _ ))
Tvar(ref (SOME _ ))
Tvar(ref (SOME _ ))
Tvar(ref (SOME Int ))
30
prune
  • fun prune (Tvar(r as (ref(SOME x))))
  • let val last prune x
  • in r SOME last last end
  • prune x x
  • Makes all references in a chain point to the very
    last type.
  • Also returns the very last type.
  • Will never return a Tvar unless it is unbound.
    I.e. it is a reference to NONE

31
Implement type equality
  • fun typeeq (x,y)
  • case (prune x,prune y) of
  • (Unit,Unit) gt true
  • (Int,Int) gt true
  • (Char,Char) gt true
  • (Bool,Bool) gt true
  • (Arrow(d1,r1),Arrow(d2,r2)) gt
  • typeeq(d1,d2) andalso typeeq(r1,r2)
  • (Product(ss),Product(ts)) gt (listeq ss ts)
  • (Tvar(r as (ref NONE)),t) gt (r SOME t
    true)
  • (t,Tvar(r as (ref NONE))) gt (r SOME t
    true)
  • (_,_) gt false

Overwrite a null pointer once we know what it is
supposed to be equal to.
32
Whenever we case over an MLtype
  • App(f,x) gt
  • let val ftype TCExp f cntxt
  • val xtype TCExp x cntxt
  • in case prune ftype of
  • Arrow(dom,rng) gt
  • if (typeeq(dom,xtype))
  • then rng
  • else unexpected x xtype dom
  • other gt
  • error f ("the type "
  • showt other
  • " is not a function")
  • end

33
A Second try
  • fun TCExp x cntxt
  • case x of
  • Anonfun(x, _ ,body) gt
  • let val t Tvar(ref NONE)
  • val btype
  • TCExp body ((x,t)cntxt)
  • in Arrow(prune t,btype) end

Generate a new fresh empty slot. I.e. guess the
type
Hopefully typing the body will force the slot to
be filled in.
Get rid of the indirect reference if there is one
34
  • CS321 Prog Lang Compilers
    Assignment 10
  • Assigned Feb. 28, 2006 Due
    Wednesday. March 7, 2007
  • 1) The goal of this assignment is to extend the
    type checker discussed in lecture 14 to handle
    refereces and assinments. To do this you will
    need to
  • A) Add a new constructed type to MLtype to
    represent reference types. Do this by adding a
    new type constructor to MLtype called "Ref".
  • B) Add two new type constructors to "Exp" called
    "Init" and "Assign". They should coorespond to
    the underlined ML expressions in the examples
    below
  • val x ref 5
  • -------
  • val y ( x 6 print x)
  • --------
  • C) Extend the function "typeeq" to handle the new
    "Ref" type.
  • D) Extend the function "TCExp" to handle the two
    new kinds of expressions. The cases should
    correspond to the type rules below.
Write a Comment
User Comments (0)
About PowerShow.com