SCM Repository
[diderot] / trunk / src / typechecker / typechecker.sml |
View of /trunk/src/typechecker/typechecker.sml
Parent Directory
|
Revision Log
Revision 80 -
(download)
(annotate)
Tue May 25 03:05:33 2010 UTC (10 years, 7 months ago) by jhr
File size: 6051 byte(s)
Tue May 25 03:05:33 2010 UTC (10 years, 7 months ago) by jhr
File size: 6051 byte(s)
Working on typechecker
(* typechecker.sml * * COPYRIGHT (c) 2010 The Diderot Project (http://diderot.cs.uchicago.edu) * All rights reserved. *) structure Typechecker : sig val check : ParseTree.program -> AST.program end = struct structure PT = ParseTree structure Ty = Types (* check a differentiation level, which muse be >= 0 *) fun checkDiff (cxt, k) = if (k < 0) then raise Fail "differentiation must be >= 0" else Ty.DiffConst(IntInf.toInt k) (* check a dimension, which must be 2 or 3 *) fun checkDim (cxt, d) = if (d < 2) orelse (3 < d) then raise Fail "invalid dimension; must be 2 or 3" else Ty.DimConst(IntInf.toInt d) (* check a shape *) fun checkShape (cxt, shape) = let fun chkDim d = if (d < 1) then raise Fail "invalid shape dimension; must be >= 1" else Ty.DimConst(IntInf.toInt d) in Ty.Shape(List.map chkDim shape) end (* check the well-formedness of a type and translate it to an AST type *) fun checkTy (cxt, ty) = (case ty of PT.T_Mark m => checkTy(#span m, #tree m) | PT.T_Bool => Ty.T_Bool | PT.T_Int => Ty.T_Int | PT.T_Real => Ty.realTy | PT.T_String => Ty.T_String | PT.T_Vec n => (* NOTE: the parser guarantees that 2 <= n <= 4 *) Ty.vecTy(IntInf.toInt n) | PT.T_Kernel k => Ty.T_Kernel(checkDiff(cxt, k)) | PT.T_Field{diff, dim, shape} => Ty.T_Field{ diff = checkDiff (cxt, diff), dim = checkDim (cxt, dim), shape = checkShape (cxt, shape) } | PT.T_Tensor shape => Ty.T_Tensor(checkShape(cxt, shape)) | PT.T_Image{dim, shape} => Ty.T_Image{ dim = checkDim (cxt, dim), shape = checkShape (cxt, shape) } | PT.T_Array(ty, dims) => raise Fail "Array type" (* end case *)) fun checkLit lit = (case lit of (Literal.Int _) => (AST.E_Lit lit, Ty.T_Int) | (Literal.Float _) => (AST.E_Lit lit, Ty.realTy) | (Literal.String s) => (AST.E_Lit lit, Ty.T_String) | (Literal.Bool _) => (AST.E_Lit lit, Ty.T_Bool) (* end case *)) (* (* typecheck an expression and translate it to AST *) fun checkExpr (env, cxt, e) = (case e of PT.E_Mark m => checkExpr (env, #span m, #tree m) | PT.E_Var x => (case Env.findVar (env, x) of SOME x' => (case Var.typeOf x' of ([], ty) => (AST.E_Var x', ty) | scheme => let val (args, ty) = Util.instantiate scheme in (AST.E_VarInst(x', args, ty), ty) end (* end case *)) | NONE => raise Fail "undefined variable" (* end case *)) | PT.E_Lit lit => checkLit lit | PT.E_BinOp of expr * var * expr | PT.E_UnaryOp of var * expr | PT.E_Tuple of expr list | PT.E_Apply of var * expr list | PT.E_Cons of ty * expr list (* end case *)) fun checkVarDecl (env, cxt, kind, d) = (case d of PT.VD_Mark m => checkVarDecl (env, #span m, kind, #tree m) | PT.VD_Decl(ty, x, e) => let val ty = checkType ty val x' = Var.new (x, kind, ty) val (e', ty') = checkExpr (env, cxt, e) in (* FIXME: check types *) AST.VD_Decl(x', e') end (* end case *)) (* typecheck a statement and translate it to AST *) fun checkStmt (env, cxt, s) = (case s of PT.S_Mark m => checkStmt (env, #span m, #tree m) | PT.S_Block stms => let fun chk (_, [], stms) = AST.S_Block(List.rev stms) | chk (env, s::ss, stms) = let val (s', env') = checkStmt (env, cxt, s) in chk (env', ss, s'::ss) end in (chk (env, stms, []), env) end | PT.S_Decl vd => let val vd as AST.VD_Decl(x, _) = checkVarDecl (env, cxt, Var.LocalVar, vd) in (AST.S_Decl vd, Env.insertLocal(env, x, x')) end | PT.S_IfThen(e, s) => let val (e', ty) = checkExpr (env, cxt, e) val s' = checkStmt (env, cxt, s) in (* check that condition has bool type *) case ty of Ty.T_Bool => () | _ => raise Fail "condition not boolean type" (* end case *); (AST.S_IfThenElse(e', s', AST.S_Block[]), env) end | PT.S_IfThenElse(e, s1, s2) => let val (e', ty) = checkExpr (env, cxt, e) val s1' = checkStmt (env, cxt, s1) val s2' = checkStmt (env, cxt, s2) in (* check that condition has bool type *) case ty of Ty.T_Bool => () | _ => raise Fail "condition not boolean type" (* end case *); (AST.S_IfThenElse(e', s1', s2'), env) end | PT.S_Assign(x, e) => (case Env.findVar (env, x) of NONE => raise Fail "undefined variable" | SOME x' => let val (e', ty) = checkExpr (env, cxt, e) in (* FIXME: check types *) (* check that x' is mutable *) case Var.kindOf x' of Var.ActorStateVar => () | Var.LocalVar => () | _ => raise Fail "assignment to immutable variable" (* end case *); (AST.S_Assign(x', e'), env) end (* end case *)) | PT.S_New(actor, args) => let val argTys' = List.map (fn e => checkExpr(env, cxt, e)) args val (args', tys') = ListPair.unzip argTys' in (* FIXME: check that actor is defined and has the argument types match *) AST.S_New(actor, args') end | PT.S_Die => (AST.S_Die, env) | PT.S_Stabilize => (AST.S_Stabilize, env) (* end case *)) fun checkDecl (env, cxt, d) = (case d of PT.D_Mark m => checkDecl (env, #span m, #tree m) | PT.D_Input(ty, x, optExp) => let val ty = checkTy(cxt, ty) val x' = Var.new(x, Var.InputVar, ty) val dcl = (case optExp of NONE => AST.D_Input(x', NONE) | SOME e => let val (e', ty') = checkExpr (env, cxt, e) in (* FIXME: check types *) AST.D_Input(x', SOME e') end (* end case *)) in (dcl, Env.insertGlobal(env, x, x')) end | PT.D_Var vd => let val vd as AST.VD_Decl(x, _) = checkVarDecl (env, cxt, Var.GlobalVar, vd) in (AST.D_Var vd, Env.insertGlobal(env, x, x')) end | PT.D_Actor{nam, params, state, methods} => ?? | PT.D_InitialArray of create * iter list | PT.D_InitialCollection of create * iter list (* end case *)) *) fun check (PT.Program dcls) = AST.Program[] end
root@smlnj-gforge.cs.uchicago.edu | ViewVC Help |
Powered by ViewVC 1.0.0 |