211 |
*) |
*) |
212 |
| ELSE_BR of T.stm list * T.exp * T.stm list * IL.node_kind |
| ELSE_BR of T.stm list * T.exp * T.stm list * IL.node_kind |
213 |
|
|
214 |
fun trCFG (env, prefix, finish, cfg) = let |
fun trCFG (env, prefix, onExit, onStabilize, cfg) = let |
215 |
fun join (env, [], _, IL.JOIN _) = raise Fail "JOIN with no open if" |
fun join (env, [], _, IL.JOIN _) = raise Fail "JOIN with no open if" |
216 |
| join (env, [], _, _) = raise Fail "no path to exit unimplemented" (* FIXME *) |
| join (env, [], _, _) = raise Fail "no path to exit unimplemented" (* FIXME *) |
217 |
| join (env, THEN_BR(stms1, cond, elseBr)::stk, stms, k) = |
| join (env, THEN_BR(stms1, cond, elseBr)::stk, stms, k) = |
259 |
end |
end |
260 |
| IL.NEW{strand, args, succ, ...} => raise Fail "NEW unimplemented" |
| IL.NEW{strand, args, succ, ...} => raise Fail "NEW unimplemented" |
261 |
| k as IL.DIE _ => join (env, ifStk, T.S_Die :: stms, k) |
| k as IL.DIE _ => join (env, ifStk, T.S_Die :: stms, k) |
262 |
| k as IL.STABILIZE _ => join (env, ifStk, T.S_Stabilize :: stms, k) |
| k as IL.STABILIZE _ => let |
263 |
|
val suffix = onStabilize env |
264 |
|
in |
265 |
|
join (env, ifStk, List.revAppend(suffix, stms), k) |
266 |
|
end |
267 |
| IL.EXIT _ => let |
| IL.EXIT _ => let |
268 |
val suffix = finish env |
val suffix = onExit env |
269 |
in |
in |
270 |
endScope (env, prefix @ List.revAppend(stms, suffix)) |
endScope (env, prefix @ List.revAppend(stms, suffix)) |
271 |
end |
end |
274 |
doNode (env, [], [], CFG.entry cfg) |
doNode (env, [], [], CFG.entry cfg) |
275 |
end |
end |
276 |
|
|
277 |
|
val updateAtom = Atom.atom "update" |
278 |
|
|
279 |
|
(* finish the update method. The stateVars are the target names for the state variables and |
280 |
|
* stateOut is the list of Low IL state variables at the end of the update. |
281 |
|
*) |
282 |
|
fun finishUpdate (stateVars, stateOut, isExit) env = let |
283 |
|
fun saveStateVar (x, x', stms) = let |
284 |
|
val stm = T.S_Assign(x, useVar env x') |
285 |
|
in |
286 |
|
stm :: stms |
287 |
|
end |
288 |
|
val stms = if isExit then [T.S_Exit] else [] |
289 |
|
in |
290 |
|
ListPair.foldrEq saveStateVar stms (stateVars, stateOut) |
291 |
|
end |
292 |
|
|
293 |
fun trMethod (env, stateVars) (IL.Method{name, stateIn, stateOut, body}) = let |
fun trMethod (env, stateVars) (IL.Method{name, stateIn, stateOut, body}) = let |
294 |
fun bindStateVar (x, x', (env, stms)) = let |
fun bindStateVar (x, x', (env, stms)) = let |
295 |
val (env, stms') = bindLocal(env, x, T.E_Var x') |
val (env, stms') = bindLocal(env, x, T.E_Var x') |
297 |
(env, stms' @ stms) |
(env, stms' @ stms) |
298 |
end |
end |
299 |
val (env, stms) = ListPair.foldrEq bindStateVar (env, []) (stateIn, stateVars) |
val (env, stms) = ListPair.foldrEq bindStateVar (env, []) (stateIn, stateVars) |
300 |
|
val (onExit, onStabilize) = if Atom.same(name, updateAtom) |
301 |
|
then (finishUpdate (stateVars, stateOut, true), finishUpdate (stateVars, stateOut, false)) |
302 |
|
else (fn _ => [], fn _ => raise Fail "unexpected stabilize") |
303 |
in |
in |
304 |
T.Method{name = name, body = trCFG (env, stms, fn _ => [], body)} |
T.Method{name = name, body = trCFG (env, stms, onExit, onStabilize, body)} |
305 |
end |
end |
306 |
|
|
307 |
fun trStrand env (IL.Strand{name, params, state, stateInit, methods}) = let |
fun trStrand env (IL.Strand{name, params, state, stateInit, methods}) = let |
319 |
name = name, |
name = name, |
320 |
params = params', |
params = params', |
321 |
state = stateVars, |
state = stateVars, |
322 |
stateInit = trCFG (env, [], finishInit, stateInit), |
stateInit = trCFG (env, [], finishInit, fn _ => raise Fail "unexpected stabilize", stateInit), |
323 |
methods = List.map (trMethod(env, stateVars)) methods |
methods = List.map (trMethod(env, stateVars)) methods |
324 |
} |
} |
325 |
end |
end |
332 |
in |
in |
333 |
T.Program{ |
T.Program{ |
334 |
globals = globals, |
globals = globals, |
335 |
globalInit = trCFG (env, [], fn _ => [], globalInit), |
globalInit = trCFG (env, [], fn _ => [], fn _ => raise Fail "unexpected stabilize", globalInit), |
336 |
strands = List.map (trStrand env) strands |
strands = List.map (trStrand env) strands |
337 |
} |
} |
338 |
end |
end |