@@ -71,24 +71,41 @@ class SExpressionStringifier extends Indentation implements Visitor<String> {
71
71
String visitLetPrim (LetPrim node) {
72
72
String name = newValueName (node.primitive);
73
73
String value = visit (node.primitive);
74
+ String bindings = '($name $value )' ;
75
+ String skip = ' ' * '(LetPrim (' .length;
76
+ while (node.body is LetPrim ) {
77
+ node = node.body;
78
+ name = newValueName (node.primitive);
79
+ value = visit (node.primitive);
80
+ bindings += '\n ${indentation }$skip ($name $value )' ;
81
+ }
74
82
String body = indentBlock (() => visit (node.body));
75
- return '$indentation (LetPrim ($name $value )\n $body )' ;
83
+ return '$indentation (LetPrim ($bindings )\n $body )' ;
84
+ }
85
+
86
+ bool isBranchTarget (Continuation cont) {
87
+ return cont.hasExactlyOneUse && cont.firstRef.parent is Branch ;
76
88
}
77
89
78
90
String visitLetCont (LetCont node) {
79
91
String conts;
80
92
bool first = true ;
93
+ String skip = ' ' * '(LetCont (' .length;
81
94
for (Continuation continuation in node.continuations) {
95
+ // Branch continuations will be printed at their use site.
96
+ if (isBranchTarget (continuation)) continue ;
82
97
if (first) {
83
98
first = false ;
84
99
conts = visit (continuation);
85
100
} else {
86
101
// Each subsequent line is indented additional spaces to align it
87
102
// with the previous continuation.
88
- String indent = '$indentation ${' ' * '(LetCont (' .length }' ;
89
- conts = '$conts \n $indent ${visit (continuation )}' ;
103
+ conts += '\n ${indentation }$skip ${visit (continuation )}' ;
90
104
}
91
105
}
106
+ // If there were no continuations printed, just print the body.
107
+ if (first) return visit (node.body);
108
+
92
109
String body = indentBlock (() => visit (node.body));
93
110
return '$indentation (LetCont ($conts )\n $body )' ;
94
111
}
@@ -191,10 +208,14 @@ class SExpressionStringifier extends Indentation implements Visitor<String> {
191
208
192
209
String visitBranch (Branch node) {
193
210
String condition = access (node.condition);
194
- String trueCont = access (node.trueContinuation);
195
- String falseCont = access (node.falseContinuation);
211
+ assert (isBranchTarget (node.trueContinuation.definition));
212
+ assert (isBranchTarget (node.falseContinuation.definition));
213
+ String trueCont =
214
+ indentBlock (() => visit (node.trueContinuation.definition));
215
+ String falseCont =
216
+ indentBlock (() => visit (node.falseContinuation.definition));
196
217
String strict = node.isStrictCheck ? 'Strict' : 'NonStrict' ;
197
- return '$indentation (Branch $condition $ trueCont $falseCont $ strict )' ;
218
+ return '$indentation (Branch $strict $ condition \n $ trueCont \n $falseCont )' ;
198
219
}
199
220
200
221
String visitUnreachable (Unreachable node) {
@@ -207,11 +228,17 @@ class SExpressionStringifier extends Indentation implements Visitor<String> {
207
228
}
208
229
209
230
String visitContinuation (Continuation node) {
231
+ if (isBranchTarget (node)) {
232
+ assert (node.parameters.isEmpty);
233
+ assert (! node.isRecursive);
234
+ return indentBlock (() => visit (node.body));
235
+ }
210
236
String name = newContinuationName (node);
211
237
if (node.isRecursive) name = 'rec $name ' ;
212
- // TODO(karlklose): this should be changed to `.map(visit).join(' ')` and
213
- // should recurse to [visit]. Currently we can't do that, because the
214
- // unstringifier_test produces [LetConts] with dummy arguments on them.
238
+ // TODO(karlklose): this should be changed to `.map(visit).join(' ')`
239
+ // and should recurse to [visit]. Currently we can't do that, because
240
+ // the unstringifier_test produces [LetConts] with dummy arguments on
241
+ // them.
215
242
String parameters = node.parameters
216
243
.map ((p) => '${decorator (p , newValueName (p ))}' )
217
244
.join (' ' );
0 commit comments