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

SCM Repository

[diderot] Diff of /branches/vis15/src/compiler/typechecker/check-stmt.sml
ViewVC logotype

Diff of /branches/vis15/src/compiler/typechecker/check-stmt.sml

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

revision 4606, Wed Sep 21 23:07:58 2016 UTC revision 4607, Thu Sep 22 02:17:46 2016 UTC
# Line 103  Line 103 
103     * by simplify.     * by simplify.
104     *)     *)
105      fun chkCtlFlow (cxt, scope, stm) = let      fun chkCtlFlow (cxt, scope, stm) = let
106            val (inFun, inCreateOrUpdate, inGlobalBlock, funName) = (case scope            fun inFun () = (case scope of E.FunctionScope _ => true | _ => false)
107                   of E.FunctionScope(_, f) => (true, false, false, Atom.toString f)            fun funName () = let val E.FunctionScope(_, f) = scope in S(Atom.toString f) end
108                    | E.MethodScope(_, StrandUtil.Start) => (false, true, false, "")            fun inCreateOrMeth () = (case scope
109                    | E.MethodScope(_, StrandUtil.Update) => (false, true, false, "")                   of E.MethodScope(_, StrandUtil.Start) => true
110                    | E.CreateScope => (false, true, false, "")                    | E.MethodScope(_, StrandUtil.Update) => true
111                    | E.StartScope => (false, true, true, "")                    | E.CreateScope => true
112                    | E.UpdateScope => (false, true, true, "")                    | _ => false
                   | _ => (false, false, false, "")  
113                  (* end case *))                  (* end case *))
114              fun inUpdate () = (case scope
115                     of E.MethodScope(_, StrandUtil.Update) => true
116                      | E.UpdateScope => true
117                      | _ => false
118                    (* end case *))
119              fun inStartOrUpdateMethod () = (case scope
120                     of E.MethodScope _ => true | _ => false)
121            val hasDieOrStabilize = ref false            val hasDieOrStabilize = ref false
122          (* checks a statement for correct control flow; it returns false if control may          (* checks a statement for correct control flow; it returns false if control may
123           * flow from the statement to the next in a sequence and true if control cannot           * flow from the statement to the next in a sequence and true if control cannot
# Line 138  Line 144 
144                    chk' (stms, false)                    chk' (stms, false)
145                  end                  end
146              | chk (cxt, hasSucc, isJoin, unreachable, PT.S_IfThen(_, stm)) = (              | chk (cxt, hasSucc, isJoin, unreachable, PT.S_IfThen(_, stm)) = (
147                  if inFun andalso not hasSucc andalso not unreachable                  if inFun() andalso not hasSucc andalso not unreachable
148                    then err(cxt, [                    then err(cxt, [
149                          S "Missing return statement in tail position of function ", S funName                          S "Missing return statement in tail position of function ", funName()
150                      ])                      ])
151                    else ();                    else ();
152                  ignore (chk (cxt, hasSucc, true, unreachable, stm));                  ignore (chk (cxt, hasSucc, true, unreachable, stm));
# Line 159  Line 165 
165                  ignore (chk (cxt, hasSucc, true, unreachable, stm));                  ignore (chk (cxt, hasSucc, true, unreachable, stm));
166                  false)                  false)
167              | chk (cxt, _, _, _, PT.S_New _) = (              | chk (cxt, _, _, _, PT.S_New _) = (
168                  if not inCreateOrUpdate                  case scope
169                    then err(cxt, [S "\"new\" statement outside of start/update method"])                   of E.MethodScope(_, StrandUtil.Start) => ()
170                    else ();                    | E.MethodScope(_, StrandUtil.Update) => ()
171                      | _ => err(cxt, [S "\"new\" statement outside of start/update method"])
172                    (* end case *);
173                  false)                  false)
174              | chk (cxt, hasSucc, isJoin, unreachable, PT.S_Continue) = (              | chk (cxt, hasSucc, isJoin, unreachable, PT.S_Continue) = (
175  (* QUESTION: should we allow "continue" in loops? *)  (* QUESTION: should we allow "continue" in loops? *)
176                  if not inCreateOrUpdate                  case scope
177                    then err(cxt, [S "\"continue\" statment outside of start/update method"])                   of E.MethodScope(_, StrandUtil.Update) => ()
178                  else if hasSucc andalso not isJoin andalso not unreachable                    | E.UpdateScope => ()
179                      | _ => if hasSucc andalso not isJoin andalso not unreachable
180                    then warn(cxt, [S "statements following \"continue\" statment are unreachable"])                    then warn(cxt, [S "statements following \"continue\" statment are unreachable"])
181                        else ()
182                    (* end case *);
183                    true)
184                | chk (cxt, hasSucc, isJoin, unreachable, PT.S_Stabilize) = let
185                  (* check strand stabilize *)
186                    fun chkStabilize () = (
187                          if (not unreachable) then hasDieOrStabilize := true else ();
188                          if hasSucc andalso not isJoin andalso not unreachable
189                            then warn(cxt, [
190                                S "statements following \"stabilize\" statment are unreachable"
191                              ])
192                    else ();                    else ();
193                  true)                  true)
194              | chk (cxt, hasSucc, isJoin, unreachable, PT.S_Stabilize) = if inGlobalBlock                  in
195                    then false (* global stabilize_all; note that this is _not_ an exit *)                    case scope
196                  else if not inCreateOrUpdate                     of E.MethodScope(_, StrandUtil.Start) => chkStabilize ()
197                    then (err(cxt, [                      | E.MethodScope(_, StrandUtil.Update) => chkStabilize ()
198                        | E.StartScope => false (* global stabilize_all; _not_ an exit *)
199                        | E.UpdateScope => false (* global stabilize_all; _not_ an exit *)
200                        | _ => (err(cxt, [
201                        S "\"stabilize\" statment outside of start/update method/block"                        S "\"stabilize\" statment outside of start/update method/block"
202                      ]);                      ]);
203                      false)                      false)
204                    else ( (* strand stabilize *)                    (* end case *)
205                    end
206                | chk (cxt, hasSucc, isJoin, unreachable, PT.S_Die) =  let
207                  (* check strand die *)
208                    fun chkDie () = (
209                      if (not unreachable) then hasDieOrStabilize := true else ();                      if (not unreachable) then hasDieOrStabilize := true else ();
210                      if hasSucc andalso not isJoin andalso not unreachable                      if hasSucc andalso not isJoin andalso not unreachable
211                        then warn(cxt, [S "statements following \"stabilize\" statment are unreachable"])                          then warn(cxt, [
212                        else ();                              S "statements following \"die\" statment are unreachable"
213                      true)                            ])
             | chk (cxt, hasSucc, isJoin, unreachable, PT.S_Die) = (  
                 if (not unreachable) then hasDieOrStabilize := true else ();  
                 if not inCreateOrUpdate orelse inGlobalBlock  
                   then err(cxt, [S "\"die\" statment outside of start/update method"])  
                 else if hasSucc andalso not isJoin andalso not unreachable  
                   then warn(cxt, [S "statements following \"die\" statment are unreachable"])  
214                    else ();                    else ();
215                  true)                  true)
216                    in
217                      case scope
218                       of E.MethodScope(_, StrandUtil.Start) => chkDie ()
219                        | E.MethodScope(_, StrandUtil.Update) => chkDie ()
220                        | E.StartScope => false (* global stabilize_all; _not_ an exit *)
221                        | E.UpdateScope => false (* global stabilize_all; _not_ an exit *)
222                        | _ => (err(cxt, [
223                              S "\"die\" statment outside of start/update method/block"
224                            ]);
225                            false)
226                      (* end case *)
227                    end
228              | chk (cxt, hasSucc, isJoin, unreachable, PT.S_Return _) = (              | chk (cxt, hasSucc, isJoin, unreachable, PT.S_Return _) = (
229                  if not inFun                  if not(inFun())
230                    then err(cxt, [S "\"return\" statment outside of function body"])                    then err(cxt, [S "\"return\" statment outside of function body"])
231                  else if hasSucc andalso not isJoin andalso not unreachable                  else if hasSucc andalso not isJoin andalso not unreachable
232                    then warn(cxt, [S "statements following \"return\" statment are unreachable"])                    then warn(cxt, [S "statements following \"return\" statment are unreachable"])
233                    else ();                    else ();
234                  true)                  true)
235              | chk (cxt, hasSucc, isJoin, unreachable, _) = (              | chk (cxt, hasSucc, isJoin, unreachable, _) = (
236                  if inFun andalso not hasSucc andalso not unreachable                  if inFun() andalso not hasSucc andalso not unreachable
237                    then err(cxt, [                    then err(cxt, [
238                          S "Missing return statement in tail position of function ", S funName                          S "Missing return statement in tail position of function ", funName()
239                      ])                      ])
240                    else ();                    else ();
241                  false)                  false)

Legend:
Removed from v.4606  
changed lines
  Added in v.4607

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