Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart

Issue 765753002: Refactor the CPS SExprStringifier. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | pkg/compiler/lib/src/use_unused_api.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library dart2js.ir_nodes_sexpr; 5 library dart2js.ir_nodes_sexpr;
6 6
7 import '../util/util.dart'; 7 import '../util/util.dart';
8 import 'cps_ir_nodes.dart'; 8 import 'cps_ir_nodes.dart';
9 9
10 /// Generate a Lisp-like S-expression representation of an IR node as a string. 10 /// Generate a Lisp-like S-expression representation of an IR node as a string.
11 class SExpressionStringifier extends Visitor<String> with Indentation { 11 class SExpressionStringifier extends Visitor<String> with Indentation {
12 final Map<Definition, String> names = <Definition, String>{}; 12 final _Namer namer = new _Namer();
13 13
14 int _valueCounter = 0; 14 String newValueName(Node node) => namer.defineValueName(node);
15 int _continuationCounter = 0; 15 String newContinuationName(Node node) => namer.defineContinuationName(node);
16 16
17 String newValueName() => 'v${_valueCounter++}'; 17 String access(Reference<Definition> r) => namer.getName(r.definition);
18 String newContinuationName() => 'k${_continuationCounter++}'; 18
19 String visitParameter(Parameter node) {
20 return namer.useElementName(node);
21 }
19 22
20 String visitFunctionDefinition(FunctionDefinition node) { 23 String visitFunctionDefinition(FunctionDefinition node) {
21 String name = node.element.name; 24 String name = node.element.name;
22 names[node.returnContinuation] = 'return'; 25 namer.useReturnName(node.returnContinuation);
23 String parameters = node.parameters 26 String parameters = node.parameters.map(visit).join(' ');
24 .map((Parameter p) {
25 String name = p.hint.name;
26 names[p] = name;
27 return name;
28 })
29 .join(' ');
30 String body = indentBlock(() => visit(node.body)); 27 String body = indentBlock(() => visit(node.body));
31 return '$indentation(FunctionDefinition $name ($parameters return)\n' 28 return '$indentation(FunctionDefinition $name ($parameters return)\n'
32 '$body)'; 29 '$body)';
33 } 30 }
34 31
35 String visitLetPrim(LetPrim node) { 32 String visitLetPrim(LetPrim node) {
36 String name = newValueName(); 33 String name = newValueName(node.primitive);
37 names[node.primitive] = name;
38 String value = visit(node.primitive); 34 String value = visit(node.primitive);
39 String body = visit(node.body); 35 String body = visit(node.body);
40 return '$indentation(LetPrim $name $value)\n$body'; 36 return '$indentation(LetPrim $name $value)\n$body';
41 } 37 }
42 38
43 String visitLetCont(LetCont node) { 39 String visitLetCont(LetCont node) {
44 String cont = newContinuationName(); 40 String cont = newContinuationName(node.continuation);
45 names[node.continuation] = cont; 41 // TODO(karlklose): this should be changed to `.map(visit).join(' ')` and
42 // should recurse to [visit]. Currently we can't do that, because the
43 // unstringifier_test produces [LetConts] with dummy arguments on them.
46 String parameters = node.continuation.parameters 44 String parameters = node.continuation.parameters
47 .map((Parameter p) { 45 .map((p) => ' ${newValueName(p)}')
48 String name = newValueName(); 46 .join('');
49 names[p] = name;
50 return ' $name';
51 })
52 .join('');
53 String contBody = indentBlock(() => visit(node.continuation.body)); 47 String contBody = indentBlock(() => visit(node.continuation.body));
54 String body = visit(node.body); 48 String body = visit(node.body);
55 String op = node.continuation.isRecursive ? 'LetCont*' : 'LetCont'; 49 String op = node.continuation.isRecursive ? 'LetCont*' : 'LetCont';
56 return '$indentation($op ($cont$parameters)\n' 50 return '$indentation($op ($cont$parameters)\n'
57 '$contBody)\n' 51 '$contBody)\n'
58 '$body'; 52 '$body';
59 } 53 }
60 54
61 String formatArguments(Invoke node) { 55 String formatArguments(Invoke node) {
62 int positionalArgumentCount = node.selector.positionalArgumentCount; 56 int positionalArgumentCount = node.selector.positionalArgumentCount;
63 List<String> args = new List<String>(); 57 List<String> args = new List<String>();
64 args.addAll(node.arguments.getRange(0, positionalArgumentCount) 58 args.addAll(
65 .map((v) => names[v.definition])); 59 node.arguments.getRange(0, positionalArgumentCount).map(access));
66 for (int i = 0; i < node.selector.namedArgumentCount; ++i) { 60 for (int i = 0; i < node.selector.namedArgumentCount; ++i) {
67 String name = node.selector.namedArguments[i]; 61 String name = node.selector.namedArguments[i];
68 Definition arg = node.arguments[positionalArgumentCount + i].definition; 62 Definition arg = node.arguments[positionalArgumentCount + i].definition;
69 args.add("($name: $arg)"); 63 args.add("($name: $arg)");
70 } 64 }
71 return args.join(' '); 65 return args.join(' ');
72 } 66 }
73 67
74 String visitInvokeStatic(InvokeStatic node) { 68 String visitInvokeStatic(InvokeStatic node) {
75 String name = node.target.name; 69 String name = node.target.name;
76 String cont = names[node.continuation.definition]; 70 String cont = access(node.continuation);
77 String args = formatArguments(node); 71 String args = formatArguments(node);
78 return '$indentation(InvokeStatic $name $args $cont)'; 72 return '$indentation(InvokeStatic $name $args $cont)';
79 } 73 }
80 74
81 String visitInvokeMethod(InvokeMethod node) { 75 String visitInvokeMethod(InvokeMethod node) {
82 String name = node.selector.name; 76 String name = node.selector.name;
83 String rcv = names[node.receiver.definition]; 77 String rcv = access(node.receiver);
84 String cont = names[node.continuation.definition]; 78 String cont = access(node.continuation);
85 String args = formatArguments(node); 79 String args = formatArguments(node);
86 return '$indentation(InvokeMethod $rcv $name $args $cont)'; 80 return '$indentation(InvokeMethod $rcv $name $args $cont)';
87 } 81 }
88 82
89 String visitInvokeSuperMethod(InvokeSuperMethod node) { 83 String visitInvokeSuperMethod(InvokeSuperMethod node) {
90 String name = node.selector.name; 84 String name = node.selector.name;
91 String cont = names[node.continuation.definition]; 85 String cont = access(node.continuation);
92 String args = formatArguments(node); 86 String args = formatArguments(node);
93 return '$indentation(InvokeSuperMethod $name $args $cont)'; 87 return '$indentation(InvokeSuperMethod $name $args $cont)';
94 } 88 }
95 89
96 String visitInvokeConstructor(InvokeConstructor node) { 90 String visitInvokeConstructor(InvokeConstructor node) {
97 String callName; 91 String callName;
98 if (node.target.name.isEmpty) { 92 if (node.target.name.isEmpty) {
99 callName = '${node.type}'; 93 callName = '${node.type}';
100 } else { 94 } else {
101 callName = '${node.type}.${node.target.name}'; 95 callName = '${node.type}.${node.target.name}';
102 } 96 }
103 String cont = names[node.continuation.definition]; 97 String cont = access(node.continuation);
104 String args = formatArguments(node); 98 String args = formatArguments(node);
105 return '$indentation(InvokeConstructor $callName $args $cont)'; 99 return '$indentation(InvokeConstructor $callName $args $cont)';
106 } 100 }
107 101
108 String visitConcatenateStrings(ConcatenateStrings node) { 102 String visitConcatenateStrings(ConcatenateStrings node) {
109 String cont = names[node.continuation.definition]; 103 String cont = access(node.continuation);
110 String args = node.arguments.map((v) => names[v.definition]).join(' '); 104 String args = node.arguments.map(access).join(' ');
111 return '$indentation(ConcatenateStrings $args $cont)'; 105 return '$indentation(ConcatenateStrings $args $cont)';
112 } 106 }
113 107
114 String visitInvokeContinuation(InvokeContinuation node) { 108 String visitInvokeContinuation(InvokeContinuation node) {
115 String cont = names[node.continuation.definition]; 109 String cont = access(node.continuation);
116 String args = node.arguments.map((v) => names[v.definition]).join(' '); 110 String args = node.arguments.map(access).join(' ');
117 String op = 111 String op =
118 node.isRecursive ? 'InvokeContinuation*' : 'InvokeContinuation'; 112 node.isRecursive ? 'InvokeContinuation*' : 'InvokeContinuation';
119 return '$indentation($op $cont $args)'; 113 return '$indentation($op $cont $args)';
120 } 114 }
121 115
122 String visitBranch(Branch node) { 116 String visitBranch(Branch node) {
123 String condition = visit(node.condition); 117 String condition = visit(node.condition);
124 String trueCont = names[node.trueContinuation.definition]; 118 String trueCont = access(node.trueContinuation);
125 String falseCont = names[node.falseContinuation.definition]; 119 String falseCont = access(node.falseContinuation);
126 return '$indentation(Branch $condition $trueCont $falseCont)'; 120 return '$indentation(Branch $condition $trueCont $falseCont)';
127 } 121 }
128 122
129 String visitConstant(Constant node) { 123 String visitConstant(Constant node) {
130 return '(Constant ${node.expression.value.toStructuredString()})'; 124 return '(Constant ${node.expression.value.toStructuredString()})';
131 } 125 }
132 126
133 String visitThis(This node) { 127 String visitThis(This node) {
134 return '(This)'; 128 return '(This)';
135 } 129 }
136 130
137 String visitReifyTypeVar(ReifyTypeVar node) { 131 String visitReifyTypeVar(ReifyTypeVar node) {
138 return '$indentation(ReifyTypeVar ${node.typeVariable.name})'; 132 return '$indentation(ReifyTypeVar ${node.typeVariable.name})';
139 } 133 }
140 134
141 String visitCreateFunction(CreateFunction node) { 135 String visitCreateFunction(CreateFunction node) {
142 String function = indentBlock(() => visit(node.definition)); 136 String function = indentBlock(() => visit(node.definition));
143 return '(CreateFunction\n$function)'; 137 return '(CreateFunction\n$function)';
144 } 138 }
145 139
146 String visitParameter(Parameter node) {
147 // Parameters are visited directly in visitLetCont.
148 return '(Unexpected Parameter)';
149 }
150
151 String visitContinuation(Continuation node) { 140 String visitContinuation(Continuation node) {
152 // Continuations are visited directly in visitLetCont. 141 // Continuations are visited directly in visitLetCont.
153 return '(Unexpected Continuation)'; 142 return '(Unexpected Continuation)';
154 } 143 }
155 144
156 String visitGetClosureVariable(GetClosureVariable node) { 145 String visitGetClosureVariable(GetClosureVariable node) {
157 return '(GetClosureVariable ${node.variable.name})'; 146 return '(GetClosureVariable ${node.variable.name})';
158 } 147 }
159 148
160 String visitSetClosureVariable(SetClosureVariable node) { 149 String visitSetClosureVariable(SetClosureVariable node) {
161 String value = names[node.value.definition]; 150 String value = access(node.value);
162 String body = indentBlock(() => visit(node.body)); 151 String body = indentBlock(() => visit(node.body));
163 return '$indentation(SetClosureVariable ${node.variable.name} $value\n' 152 return '$indentation(SetClosureVariable ${node.variable.name} $value\n'
164 '$body)'; 153 '$body)';
165 } 154 }
166 155
167 String visitTypeOperator(TypeOperator node) { 156 String visitTypeOperator(TypeOperator node) {
168 String receiver = names[node.receiver.definition]; 157 String receiver = access(node.receiver);
169 String cont = names[node.continuation.definition]; 158 String cont = access(node.continuation);
170 String operator = node.isTypeTest ? 'is' : 'as'; 159 String operator = node.isTypeTest ? 'is' : 'as';
171 return '$indentation(TypeOperator $operator $receiver ${node.type} $cont)'; 160 return '$indentation(TypeOperator $operator $receiver ${node.type} $cont)';
172 } 161 }
173 162
174 String visitLiteralList(LiteralList node) { 163 String visitLiteralList(LiteralList node) {
175 String values = node.values.map((v) => names[v.definition]).join(' '); 164 String values = node.values.map(access).join(' ');
176 return '(LiteralList ($values))'; 165 return '(LiteralList ($values))';
177 } 166 }
178 167
179 String visitLiteralMap(LiteralMap node) { 168 String visitLiteralMap(LiteralMap node) {
180 String keys = node.entries.map((e) => names[e.key.definition]).join(' '); 169 String keys = node.entries.map((e) => access(e.key)).join(' ');
181 String values = 170 String values = node.entries.map((e) => access(e.value)).join(' ');
182 node.entries.map((e) => names[e.value.definition]).join(' ');
183 return '(LiteralMap ($keys) ($values))'; 171 return '(LiteralMap ($keys) ($values))';
184 } 172 }
185 173
186 String visitDeclareFunction(DeclareFunction node) { 174 String visitDeclareFunction(DeclareFunction node) {
187 String function = indentBlock(() => visit(node.definition)); 175 String function = indentBlock(() => visit(node.definition));
188 String body = indentBlock(() => visit(node.body)); 176 String body = indentBlock(() => visit(node.body));
189 return '$indentation(DeclareFunction ${node.variable.name} =\n' 177 return '$indentation(DeclareFunction ${node.variable.name} =\n'
190 '$function in\n' 178 '$function in\n'
191 '$body)'; 179 '$body)';
192 } 180 }
193 181
194 String visitIsTrue(IsTrue node) { 182 String visitIsTrue(IsTrue node) {
195 String value = names[node.value.definition]; 183 String value = access(node.value);
196 return '(IsTrue $value)'; 184 return '(IsTrue $value)';
197 } 185 }
198 186
199 String visitIdentical(Identical node) { 187 String visitIdentical(Identical node) {
200 String left = names[node.left.definition]; 188 String left = access(node.left);
201 String right = names[node.right.definition]; 189 String right = access(node.right);
202 return '(Identical $left $right)'; 190 return '(Identical $left $right)';
203 } 191 }
204 } 192 }
193
194 class _Namer {
195 final Map<Node, String> _names = <Node, String>{};
196 int _valueCounter = 0;
197 int _continuationCounter = 0;
198
199 String useElementName(Parameter parameter) {
200 assert(!_names.containsKey(parameter));
201 return _names[parameter] = parameter.hint.name;
202 }
203
204 String defineContinuationName(Node node) {
205 assert(!_names.containsKey(node));
206 return _names[node] = 'k${_continuationCounter++}';
207 }
208
209 String defineValueName(Node node) {
210 assert(!_names.containsKey(node));
211 return _names[node] = 'v${_valueCounter++}';
212 }
213
214 String useReturnName(Continuation node) {
215 assert(!_names.containsKey(node) || _names[node] == 'return');
216 return _names[node] = 'return';
217 }
218
219 String getName(Node node) {
220 assert(_names.containsKey(node));
221 return _names[node];
222 }
223 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/use_unused_api.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698