8 |
|
|
9 |
functor SSAPPFn (IL : SSA) : sig |
functor SSAPPFn (IL : SSA) : sig |
10 |
|
|
11 |
|
val output : TextIO.outstream * IL.program -> unit |
12 |
|
|
13 |
end = struct |
end = struct |
14 |
|
|
15 |
|
structure Op = IL.Op |
16 |
|
structure Var = IL.Var |
17 |
|
|
18 |
|
fun indent (outS, i) = TextIO.output(outS, StringCvt.padLeft #" " i "") |
19 |
|
fun incIndent (outS, i) = (outS, i+2) |
20 |
|
fun pr ((outS, _), s) = TextIO.output(outS, s) |
21 |
|
fun prl (out, l) = pr(out, concat l) |
22 |
|
|
23 |
|
fun ppRHS (out, IL.VAR x) = pr(out, Var.toString x) |
24 |
|
| ppRHS (out, IL.LIT lit) = pr(out, Literal.toString lit) |
25 |
|
| ppRHS (out, IL.OP(rator, args)) = prl (out, [ |
26 |
|
Op.toString rator, "(", String.concatWith "," (List.map Var.toString args), ")" |
27 |
|
]) |
28 |
|
| ppRHS (out, IL.CONS xs) = |
29 |
|
prl (out, ["[", String.concatWith "," (List.map Var.toString xs), "]"]) |
30 |
|
|
31 |
|
fun labelOf (IL.STM{id, ...}) = "L"^Stamp.toString id |
32 |
|
|
33 |
|
fun ppStmt (out, stm as IL.STM{id, kind, next, ...}) = let |
34 |
|
val out1 = incIndent out |
35 |
|
fun prPhi (y, xs) = ( |
36 |
|
indent out1; |
37 |
|
prl (out1, [ |
38 |
|
Var.toString y, " = phi(", |
39 |
|
String.concatWith "," (List.map Var.toString xs), ")\n" |
40 |
|
])) |
41 |
|
in |
42 |
|
indent out; |
43 |
|
prl (out, [ |
44 |
|
IL.Stmt.toString stm, "(", IL.Node.toString(IL.Stmt.entry stm), "): # preds = [", |
45 |
|
String.concatWith "," (List.map IL.Node.toString (IL.Node.preds(IL.Stmt.entry stm))), |
46 |
|
"]\n" |
47 |
|
]); |
48 |
|
case kind |
49 |
|
of IL.S_SIMPLE(IL.ND{kind, ...}) => (case kind |
50 |
|
of IL.NULL => raise Fail "unexpected S_SIMPLE with NULL node" |
51 |
|
| IL.ENTRY _ => (indent out1; pr(out1, "entry;\n")) |
52 |
|
| IL.JOIN{phis, ...} => List.app prPhi (!phis) |
53 |
|
| IL.COND _ => raise Fail "unexpected S_SIMPLE with COND node" |
54 |
|
| IL.BLOCK{body=ref [], ...} => (indent out1; pr (out, "empty;\n")) |
55 |
|
| IL.BLOCK{body, ...} => ( |
56 |
|
List.app |
57 |
|
(fn (y, rhs) => ( |
58 |
|
indent out1; |
59 |
|
prl(out1, [Var.toString y, " = "]); ppRHS(out1, rhs); pr(out1, ";\n")) |
60 |
|
) (!body)) |
61 |
|
| IL.NEW{actor, args, ...} => ( |
62 |
|
indent out1; |
63 |
|
prl (out1, [ |
64 |
|
"new ", Atom.toString actor, "(", |
65 |
|
String.concatWith "," (List.map Var.toString args), ");\n" |
66 |
|
])) |
67 |
|
| IL.DIE _ => (indent out1; pr(out1, "die;\n")) |
68 |
|
| IL.STABILIZE _ => (indent out1; pr(out1, "stabilize;\n")) |
69 |
|
| IL.EXIT _ => (indent out1; pr(out1, "exit;\n")) |
70 |
|
(* end case *)) |
71 |
|
| IL.S_IF{cond=IL.ND{kind=IL.COND{cond, ...}, ...}, thenBranch, elseBranch} => ( |
72 |
|
indent out1; prl(out1, ["if ", Var.toString cond, " then\n"]); |
73 |
|
ppStmt (incIndent out1, thenBranch); |
74 |
|
indent out1; pr(out1, "else\n"); |
75 |
|
ppStmt (incIndent out1, elseBranch); |
76 |
|
indent out1; pr(out1, "endif;\n")) |
77 |
|
| IL.S_LOOP _ => raise Fail "LOOP" |
78 |
|
(* end case *); |
79 |
|
ppNext (out, next) |
80 |
|
end |
81 |
|
|
82 |
|
and ppNext (out, NONE) = () |
83 |
|
| ppNext (out, SOME stm) = ppStmt (out, stm) |
84 |
|
|
85 |
|
fun ppMethod (out, IL.Method{name, stateIn, stateOut, body}) = let |
86 |
|
val out1 = incIndent out |
87 |
|
fun prVars xs = List.app (fn x => prl(out, [" ", Var.toString x])) xs |
88 |
|
in |
89 |
|
indent out; prl(out, ["method ", Atom.toString name, "\n"]); |
90 |
|
indent out1; pr(out1, "state in: "); prVars stateIn; pr(out1, "\n"); |
91 |
|
ppStmt (incIndent out1, body); |
92 |
|
indent out1; pr(out1, "state out:"); prVars stateOut; pr(out1, "\n"); |
93 |
|
indent out; prl(out, ["end ", Atom.toString name, "\n"]) |
94 |
|
end |
95 |
|
|
96 |
|
and ppActor (out, IL.Actor{name, params, state, stateInit, methods}) = let |
97 |
|
val out1 = incIndent out |
98 |
|
fun prVars xs = List.app (fn x => prl(out, [" ", Var.toString x])) xs |
99 |
|
in |
100 |
|
indent out; |
101 |
|
prl(out, [ |
102 |
|
"actor ", Atom.toString name, " (", |
103 |
|
String.concatWith "," (List.map Var.toString params), ")\n" |
104 |
|
]); |
105 |
|
indent out1; pr(out1, "state: "); prVars state; pr(out1, "\n"); |
106 |
|
ppStmt (incIndent out1, stateInit); |
107 |
|
List.app (fn m => ppMethod(out1, m)) methods; |
108 |
|
indent out; prl(out, ["end ", Atom.toString name, "\n"]) |
109 |
|
end |
110 |
|
|
111 |
|
fun output (outS, IL.Program{globals, globalInit, actors}) = let |
112 |
|
val out = (outS, 0) |
113 |
|
val out1 = incIndent out |
114 |
|
in |
115 |
|
pr (out, "## globals\n"); |
116 |
|
List.app (fn x => (indent out1; prl(out1, ["global ", Var.toString x, "\n"]))) globals; |
117 |
|
pr (out, "## global initialization\n"); |
118 |
|
ppStmt (out1, globalInit); |
119 |
|
pr (out, "## actors\n"); |
120 |
|
List.app (fn actor => ppActor(out1, actor)) actors; |
121 |
|
pr (out, "## end program") |
122 |
|
end |
123 |
|
|
124 |
end |
end |