40 |
| S.E_Cons args => [(lhs, IL.CONS(List.map (lookup env) args))] |
| S.E_Cons args => [(lhs, IL.CONS(List.map (lookup env) args))] |
41 |
(* end case *)) |
(* end case *)) |
42 |
|
|
43 |
fun cvtBlock (env, S.Block stms) = |
(* convert a Simple AST block to an IL statement. We return the statement that represents the |
44 |
|
* block, plus the environment mapping Simple AST variables to their current SSA representations |
45 |
(* convert a statement, where env is the mapping from Simple AST variables to |
* and the set of Simple AST variables that were assigned to in the block. |
|
* their current SSA name, assigned is the set of AST variables assigned to |
|
|
* in the current context, and stm is the statement to convert. |
|
46 |
*) |
*) |
47 |
and cvtStmt (env, assigned, stm, preStms, k) = (case stm |
fun cvtBlock (env, S.Block stms) = let |
48 |
of S.S_Assign(x, e) => let |
fun toBlock (env, assigned, [], assignments) = |
49 |
|
(IL.mkBLOCK{succ=IL.dummy, body=List.rev assignments}, env, assigned) |
50 |
|
| toBlock (env, assigned, S.S_Assign(x, e)::rest, assignments) = let |
51 |
val x' = newVar x |
val x' = newVar x |
52 |
val stms = cvtExp(env, x', e) |
val stms = cvtExp(env, x', e) |
53 |
val assigned = VSet.add(assigned, x) |
val assigned = VSet.add(assigned, x) |
54 |
val env = VMap.insert(env, x, x') |
val env = VMap.insert(env, x, x') |
55 |
in |
in |
56 |
k (env, assigned, stm::preStms) |
cvt (env, assigned, rest, stms@assignments) |
57 |
|
end |
58 |
|
| toBlock (env, assigned, stms, assignments) = let |
59 |
|
val (succ, env, assigned) = toStmt (env, assigned, stms) |
60 |
|
val blk = IL.mkBLOCK{succ=succ, body=List.rev assignments} |
61 |
|
in |
62 |
|
IL.addPred (succ, blk); |
63 |
|
(blk, env, assigned) |
64 |
end |
end |
65 |
|
and toStmt (env, assigned, []) = |
66 |
|
(IL.mkBLOCK{succ=IL.dummy, body=[]}, env, assigned) |
67 |
|
| toStmt (env, assigned, stms as stmt::rest) = (case stm |
68 |
|
of S.S_Assign => toBlock (env, assigned, stms) |
69 |
| S.S_IfThenElse(x, b1, b2) => let |
| S.S_IfThenElse(x, b1, b2) => let |
70 |
val x' = lookup env x |
val x' = lookup env x |
71 |
val (b1, env1, assigned1) = block(env, b1) |
val (s1, env1, assigned1) = block(env, b1) |
72 |
val (b2, env2, assigned2) = block(env, b2) |
val (s2, env2, assigned2) = block(env, b2) |
73 |
val assigned = VSet.union(assigned1, assigned2) |
val assigned = VSet.union(assigned1, assigned2) |
74 |
val (env, phis) = let |
val (env, phis) = let |
75 |
fun mkPhi (x, (env, phis) = let |
fun mkPhi (x, (env, phis) = let |
82 |
in |
in |
83 |
VSet.foldl mkPhi (env, []) assigned |
VSet.foldl mkPhi (env, []) assigned |
84 |
end |
end |
85 |
|
val stm = IL.mkIF{cond=x', thenBranch=s1, elseBranch=s2} |
86 |
|
in |
87 |
|
case rest |
88 |
|
of [] => (stm, env, assigned) |
89 |
|
| _ => let |
90 |
|
val (join, env, assigned) = toStmt (env, assigned, rest) |
91 |
|
in |
92 |
|
IL.addPred (join, stm); |
93 |
|
IL.setSucc (stm, join); |
94 |
|
(stm, env, assigned) |
95 |
|
end |
96 |
|
(* end case *) |
97 |
|
end |
98 |
|
| S.S_New(name, xs) => let |
99 |
|
val xs' = List.map (lookup env) xs |
100 |
|
in |
101 |
|
case rest |
102 |
|
of [] => (IL.mkNEW{actor=name, args=xs', succ=IL.dummy}, env, assigned) |
103 |
|
| _ => let |
104 |
|
val (succ, env, assigned) = toStmt (env, assigned, rest) |
105 |
|
val stm = IL.mkNEW{actor=name, args=xs', succ=succ} |
106 |
in |
in |
107 |
|
IL.addPred (succ, stm); |
108 |
|
(stm, env, assigned) |
109 |
end |
end |
110 |
| S.S_New(name, xs) => |
| S.S_Die => (IL.mkDIE(), assigned, stms) |
111 |
| S.S_Die => |
| S.S_Stabilize => (IL.mkSTABILIZE(), assigned, stms) |
|
| S.S_Stabilize => |
|
112 |
(* end case *)) |
(* end case *)) |
113 |
|
in |
114 |
|
toStmt (env, VSet.empty, stms) |
115 |
|
end |
116 |
|
|
|
fun newBlock (??, stm) = |
|
|
|
|
|
and nextStmt (env, assigned, stm, ??) = |
|
|
|
|
|
and join (env |
|
117 |
fun translate (S.Program{globals, globaInit, actors}) = ?? |
fun translate (S.Program{globals, globaInit, actors}) = ?? |
118 |
|
|
119 |
end |
end |