Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] Diff of /branches/lamont_dev/src/compiler/IL/check-il-fn.sml
ViewVC logotype

Diff of /branches/lamont_dev/src/compiler/IL/check-il-fn.sml

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 435, Tue Oct 19 13:14:20 2010 UTC revision 1640, Wed Nov 16 02:19:51 2011 UTC
# Line 17  Line 17 
17    (* returns the signature of an operator as (rng, dom). *)    (* returns the signature of an operator as (rng, dom). *)
18      val sigOf : rator -> ty * ty list      val sigOf : rator -> ty * ty list
19    
20    (* return the type of a CONS, where the argument types    (* return the type of a CONS, where the first argument is the annotated type
21     * are given.  Returns NONE if the argument types are     * and the second argument is the list of argument types.  Returns false if
22     * invalid for the IL.     * there is a type error.
23     *)     *)
24      val typeOfCons : ty list -> ty option      val typeOfCons : ty * ty list -> bool
25    
26    end    end
27    
# Line 58  Line 58 
58    
59          fun join inputs = List.foldl VSet.union bottom inputs          fun join inputs = List.foldl VSet.union bottom inputs
60    
61          fun transfer (input, IL.ND{kind, ...}) = (case kind          fun transfer (input, nd as IL.ND{kind, ...}) = (case kind
62                 of IL.NULL => raise Fail "unexpected NULL"                 of IL.JOIN{phis, ...} => let
63                  | IL.JOIN{phis, ...} => let                    (* add the lhs of the phi node.  We do not remove the rhs variables, since
64                    (* add the lhs of the phi node, while removing the rhs variables *)                     * after value numbering, they may have further uses.
65                      fun doPhi ((y, xs), vs) =                     *)
66                            VSet.add(                      fun doPhi ((y, _), vs) = VSet.add(vs, y)
67                              VSet.difference(vs, VSet.fromList xs),                      val output = List.foldl doPhi input (!phis)
                             y)  
                     in  
                       List.foldl doPhi input (!phis)  
                     end  
                 | IL.BLOCK{body, ...} => let  
                     fun doAssign ((y, _), vs) = VSet.add(vs, y)  
68                      in                      in
69                        List.foldl doAssign input (!body)                        output
70                      end                      end
71                    | IL.ASSIGN{stm=(y, _), ...} => VSet.add(input, y)
72                    | IL.MASSIGN{stm=(ys, _, _), ...} => VSet.addList(input, ys)
73                  | _ => input                  | _ => input
74                 (* end case *))                 (* end case *))
75    
# Line 89  Line 85 
85        end)        end)
86    
87      datatype token      datatype token
88        = NL | S of string | V of IL.var | VTYS of IL.var list | TY of Ty.ty | TYS of Ty.ty list        = NL | S of string | A of Atom.atom | V of IL.var | VTYS of IL.var list
89          | TY of Ty.ty | TYS of Ty.ty list
90    
91      fun error errBuf toks = let      fun error errBuf toks = let
92            fun tok2str NL = "\n  ** "            fun tok2str NL = "\n  ** "
93              | tok2str (S s) = s              | tok2str (S s) = s
94                | tok2str (A s) = Atom.toString s
95              | tok2str (V x) = V.toString x              | tok2str (V x) = V.toString x
96              | tok2str (VTYS xs) = tok2str(TYS(List.map V.ty xs))              | tok2str (VTYS xs) = tok2str(TYS(List.map V.ty xs))
97              | tok2str (TY ty) = Ty.toString ty              | tok2str (TY ty) = Ty.toString ty
# Line 107  Line 105 
105                :: !errBuf                :: !errBuf
106            end            end
107    
   
108      fun checkAssign errFn ((y, rhs), bvs) = let      fun checkAssign errFn ((y, rhs), bvs) = let
109          (* check a variable use *)          (* check a variable use *)
110            fun checkVar x = if VSet.member(bvs, x)            fun checkVar x = if VSet.member(bvs, x)
# Line 129  Line 126 
126                    ]                    ]
127                  else ();                  else ();
128                case rhs                case rhs
129                 of IL.VAR x => (                 of IL.STATE x =>
130                        if Ty.same(V.ty y, IL.StateVar.ty x)
131                          then ()
132                          else tyError (V.ty y, IL.StateVar.ty x)
133                    | IL.VAR x => (
134                      checkVar x;                      checkVar x;
135                      if Ty.same(V.ty y, V.ty x)                      if Ty.same(V.ty y, V.ty x)
136                        then ()                        then ()
# Line 161  Line 162 
162                              NL, S "found:    ", VTYS xs                              NL, S "found:    ", VTYS xs
163                            ]                            ]
164                      end                      end
165                  | IL.CONS xs => (                  | IL.APPLY(name, xs) => () (* FIXME: need functor parameter for typing name *)
166                    | IL.CONS(ty, xs) => (
167                      List.app checkVar xs;                      List.app checkVar xs;
168                      case OpTy.typeOfCons (List.map V.ty xs)                      if OpTy.typeOfCons (ty, List.map V.ty xs)
169                       of NONE => errFn [S "invalid ", S(IL.assignToString(y, rhs))]                        then if Ty.same(V.ty y, ty)
                       | SOME ty => if Ty.same(V.ty y, ty)  
170                            then ()                            then ()
171                            else tyError (V.ty y, ty)                            else tyError (V.ty y, ty)
172                          else errFn [S "invalid ", S(IL.assignToString(y, rhs))]
173                      (* end case *))                      (* end case *))
174                (* end case *);                (* end case *);
175                VSet.add(bvs, y)                VSet.add(bvs, y)
176              end              end
177    
178        fun checkMAssign errFn (stm as (ys, rator, xs), bvs) = let
179            (* check that a lhs variable is not bound twice *)
180              fun checkBind y = if VSet.member(bvs, y)
181                    then errFn [
182                        S "variable ", V y, S " is bound twice in", NL,
183                        S(IL.massignToString stm)
184                      ]
185                    else ()
186            (* check a variable use *)
187              fun checkVar x = if VSet.member(bvs, x)
188                    then ()
189                    else errFn [
190                        S "variable ", V x, S " is not bound in", NL,
191                        S(IL.massignToString stm)
192                      ]
193              fun tyError (ty1, ty2) = errFn [
194                      S "type mismatch in \"", S(IL.massignToString stm), S "\"",
195                      NL, S "lhs: ", TY ty1, NL, S "rhs: ", TY ty2
196                    ]
197              in
198                (* check that the lhs variables are not bound twice *)
199                  List.app checkBind ys;
200    (* FIXME:
201                (* check the types *)
202                  val (resTys, argTys) = OpTy.sigOf rator
203                  in
204                    List.app checkVar xs;
205                    if ListPair.allEq (fn (y, ty) => Ty.same(V.ty y, ty)) (ys, resTys)
206                      then ()
207                      else tyError (V.ty y, resTy);
208                    if ListPair.allEq (fn (x, ty) => Ty.same(V.ty x, ty)) (xs, argTys)
209                      then ()
210                      else errFn [
211                          S "argument type mismatch in \"", S(IL.massignToString stm), S "\"",
212                          NL, S "expected: ", TYS argTys,
213                          NL, S "found:    ", VTYS xs
214                        ]
215                  end
216    *)
217                  VSet.addList(bvs, ys)
218                end
219    
220      fun checkPhi errFn bvs (y, xs) = let      fun checkPhi errFn bvs (y, xs) = let
221            val ty = V.ty y            val ty = V.ty y
222            in            in
# Line 192  Line 236 
236                  ]                  ]
237            end            end
238    
239      fun check (phase, IL.Program{globals, globalInit, actors}) = let      fun check (phase, IL.Program{props, globalInit, initially, strands}) = let
240            val errBuf = ref []            val errBuf = ref []
241            val errFn = error errBuf            val errFn = error errBuf
242            fun final () = (case !errBuf            fun final () = (case !errBuf
# Line 204  Line 248 
248                  (* end case *))                  (* end case *))
249            val checkPhi = checkPhi errFn            val checkPhi = checkPhi errFn
250            val checkAssign = checkAssign errFn            val checkAssign = checkAssign errFn
251            fun checkStmt (vs, stm) = let            val checkMAssign = checkMAssign errFn
252              fun checkCFG (vs, cfg) = let
253                  val bvs = VSet.fromList vs                  val bvs = VSet.fromList vs
254                (* compute the variables available on entry to each block *)                (* compute the variables available on entry to each block *)
255                  val nodes = Avail.analyse (bvs, stm)                  val nodes = Avail.analyse (bvs, cfg)
256                  fun checkNd (nd as IL.ND{kind, ...}) = (case kind                  fun checkNd (nd as IL.ND{kind, ...}) = (case kind
257                         of IL.NULL => raise Fail "unexpected NULL"                         of IL.NULL => errFn [S "unexpected ", S(IL.Node.toString nd)]
258                          | IL.JOIN{phis, ...} =>                          | IL.JOIN{phis, ...} =>
259                              List.app (checkPhi (VSet.union(Avail.inValue nd, bvs))) (!phis)                              List.app (checkPhi (VSet.union(Avail.inValue nd, bvs))) (!phis)
260                          | IL.COND{cond, ...} =>                          | IL.COND{cond, ...} =>
# Line 217  Line 262 
262                              orelse VSet.member(bvs, cond)                              orelse VSet.member(bvs, cond)
263                                then ()                                then ()
264                                else errFn [S "unbound variable ", V cond, S " in conditional"]                                else errFn [S "unbound variable ", V cond, S " in conditional"]
265                          | IL.BLOCK{body, ...} =>                          | IL.ASSIGN{stm, ...} =>
266                              ignore (List.foldl checkAssign (VSet.union(Avail.inValue nd, bvs)) (!body))                              ignore (checkAssign (stm, VSet.union(Avail.inValue nd, bvs)))
267                          | IL.NEW{actor, args, ...} => let                          | IL.MASSIGN{stm, ...} =>
268                                ignore (checkMAssign (stm, VSet.union(Avail.inValue nd, bvs)))
269                            | IL.NEW{strand, args, ...} => let
270                              val bvs = VSet.union(Avail.inValue nd, bvs)                              val bvs = VSet.union(Avail.inValue nd, bvs)
271                            (* check a variable use *)                            (* check a variable use *)
272                              fun checkVar x = if VSet.member(bvs, x)                              fun checkVar x = if VSet.member(bvs, x)
273                                    then ()                                    then ()
274                                    else errFn [                                    else errFn [
275                                        S "variable ", V x, S " is not bound in new ",                                        S "variable ", V x, S " is not bound in new ",
276                                        S(Atom.toString actor)                                        S(Atom.toString strand)
277                                      ]                                      ]
278                              in                              in
279                                List.app checkVar args                                List.app checkVar args
280                              end                              end
281                            | IL.SAVE{lhs, rhs, ...} => let
282                                val bvs = VSet.union(Avail.inValue nd, bvs)
283                                in
284                                  if VSet.member(bvs, rhs)
285                                    then ()
286                                    else errFn [
287                                        S "variable ", V rhs, S " is not bound in save ",
288                                        S(IL.StateVar.toString lhs)
289                                      ];
290                                  if Ty.same(IL.StateVar.ty lhs, V.ty rhs)
291                                    then ()
292                                    else errFn [
293                                        S "type mismatch in \"", S(IL.StateVar.toString lhs),
294                                        S " = ", S(V.toString rhs), S "\"",
295                                        NL, S "lhs: ", TY(IL.StateVar.ty lhs),
296                                        NL, S "rhs: ", TY(V.ty rhs)
297                                      ]
298                                end
299                          | _ => ()                          | _ => ()
300                        (* end case *))                        (* end case *))
301                  in                  in
# Line 238  Line 303 
303                  (* cleanup *)                  (* cleanup *)
304                    Avail.scrub nodes                    Avail.scrub nodes
305                  end                  end
306          (* check an actor definition *)          (* the globals are those variables that are live at the exit of the global initialization *)
307            fun checkActor (IL.Actor{params, state, stateInit, methods, ...}) = let            val globals = IL.CFG.liveAtExit globalInit
308                  fun checkMethod (IL.Method{stateIn, body, ...}) =          (* check a strand definition *)
309                        checkStmt (globals@stateIn, body)            fun checkStrand (IL.Strand{name, params, state, stateInit, methods}) = let
310                    val nStateVars = List.length state
311                    val extraVars = params @ globals
312                    fun checkMethod (IL.Method{name, body, ...}) = checkCFG (extraVars, body)
313    (*DEBUG*)handle ex => raise ex
314                  in                  in
315                    checkStmt (globals@params, stateInit);                    checkCFG (extraVars, stateInit)
316    (*DEBUG*)handle ex => raise ex;
317                    List.app checkMethod methods                    List.app checkMethod methods
318                  end                  end
319            (* handle exceptions *)
320              fun onExn exn = errFn [S "uncaught exception: ", S(exnMessage exn)]
321            in            in
322            (* check the global part *)            (* check the global part *)
323              checkStmt ([], globalInit);              checkCFG ([], globalInit) handle ex => onExn ex;
324            (* check the actors *)  (* FIXME: need to check initially *)
325              List.app checkActor actors;            (* check the strands *)
326                (List.app checkStrand strands) handle ex => onExn ex;
327            (* check for errors *)            (* check for errors *)
328              final()              final()
329            end            end

Legend:
Removed from v.435  
changed lines
  Added in v.1640

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0