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

Side by Side Diff: frog/leg/compile_time_constants.dart

Issue 9427012: Allow binary operators on compile-time-constants. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 10 months 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 | frog/leg/compiler.dart » ('j') | frog/leg/tree/nodes.dart » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 /** 5 /**
6 * The [CompileTimeConstantHandler] keeps track of compile-time constants, 6 * The [CompileTimeConstantHandler] keeps track of compile-time constants,
7 * initializations of global and static fields, and default values of 7 * initializations of global and static fields, and default values of
8 * optional parameters. 8 * optional parameters.
9 */ 9 */
10 class CompileTimeConstantHandler extends CompilerTask { 10 class CompileTimeConstantHandler extends CompilerTask {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 && element.modifiers.isFinal(); 89 && element.modifiers.isFinal();
90 }); 90 });
91 } 91 }
92 92
93 StringBuffer writeJsCodeForVariable(StringBuffer buffer, 93 StringBuffer writeJsCodeForVariable(StringBuffer buffer,
94 VariableElement element) { 94 VariableElement element) {
95 var value = initialVariableValues[element]; 95 var value = initialVariableValues[element];
96 if (value === null) { 96 if (value === null) {
97 buffer.add("(void 0)"); 97 buffer.add("(void 0)");
98 } else if (value is num) { 98 } else if (value is num) {
99 buffer.add("($value)"); 99 if (value.isNaN()) {
100 buffer.add("(0/0)");
101 } else if (value == double.INFINITY) {
102 buffer.add("(1/0)");
103 } else if (value == -double.INFINITY) {
104 buffer.add("(-1/0)");
105 } else {
106 buffer.add("($value)");
107 }
100 } else if (value === true) { 108 } else if (value === true) {
101 buffer.add("true"); 109 buffer.add("true");
102 } else if (value === false) { 110 } else if (value === false) {
103 buffer.add("false"); 111 buffer.add("false");
104 } else if (value is DartString) { 112 } else if (value is DartString) {
105 buffer.add("'"); 113 buffer.add("'");
106 writeEscapedString(value, buffer, (reason) { 114 writeEscapedString(value, buffer, (reason) {
107 compiler.cancel("failed to write escaped string: $value"); 115 compiler.cancel("failed to write escaped string: $value");
108 }); 116 });
109 buffer.add("'"); 117 buffer.add("'");
110 } else { 118 } else {
111 // TODO(floitsch): support more values. 119 // TODO(floitsch): support more values.
112 compiler.unimplemented("CompileTimeConstantHandler" + 120 compiler.unimplemented("CompileTimeConstantHandler" +
113 "writeJsCodeForVariable", 121 "writeJsCodeForVariable",
114 node: element.parseNode(compiler)); 122 element: element);
115 } 123 }
116 return buffer; 124 return buffer;
117 } 125 }
118 126
119 /** 127 /**
120 * Write the contents of the quoted string to a [StringBuffer] in 128 * Write the contents of the quoted string to a [StringBuffer] in
121 * a form that is valid as JavaScript string literal content. 129 * a form that is valid as JavaScript string literal content.
122 * The string is assumed quoted by single quote characters. 130 * The string is assumed quoted by single quote characters.
123 */ 131 */
124 static void writeEscapedString(DartString string, 132 static void writeEscapedString(DartString string,
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 } 197 }
190 198
191 visitLiteral(Literal literal) { 199 visitLiteral(Literal literal) {
192 if (literal is LiteralString) { 200 if (literal is LiteralString) {
193 assert(literal.asLiteralString().isValidated()); 201 assert(literal.asLiteralString().isValidated());
194 return literal.asLiteralString().dartString; 202 return literal.asLiteralString().dartString;
195 } 203 }
196 return literal.value; 204 return literal.value;
197 } 205 }
198 206
207 // TODO(floitsch): provide better error-messages.
199 visitSend(Send send) { 208 visitSend(Send send) {
200 Element element = definitions[send]; 209 Element element = definitions[send];
201 if (element !== null && element.kind == ElementKind.FIELD) { 210 if (Elements.isStaticOrTopLevelField(element)) {
202 if (element.isInstanceMember() || 211 if (element.modifiers === null ||
203 element.modifiers === null ||
204 !element.modifiers.isFinal()) { 212 !element.modifiers.isFinal()) {
205 error(element); 213 error(send);
206 } 214 }
207 return constantHandler.compileVariable(element); 215 return constantHandler.compileVariable(element);
216 } else if (send.isPrefix) {
217 assert(send.isOperator);
218 var receiverValue = evaluate(send.receiver);
219 Operator op = send.selector;
220 switch (op.source.stringValue) {
221 case "-":
222 if (receiverValue is !num) error(send);
223 return -receiverValue;
224 case "~":
225 if (receiverValue is !int) error(send);
226 return ~receiverValue;
227 case "!":
228 if (receiverValue is !bool) error(send);
229 return !receiverValue;
230 default: error(send);
ngeoffray 2012/02/21 11:22:09 new line after default?
floitsch 2012/02/22 10:17:51 Done.
231 }
232 } else if (send.isOperator && !send.isPostfix) {
233 assert(send.argumentCount() == 1);
234 var left = evaluate(send.receiver);
235 var right = evaluate(send.argumentsNode.nodes.head);
236 String op = send.selector.asOperator().source.stringValue;
237
238 if (op == "==" || op == "===") {
239 // We use == instead of === so that non-canonicalized DartStrings can
240 // use their equality operator.
241 return left == right;
242 } else if (op == "!=" || op == "!==") {
243 // We use == instead of === so that non-canonicalized DartStrings can
ngeoffray 2012/02/21 11:22:09 Remove comment, or adjust it to !=.
floitsch 2012/02/22 10:17:51 Done.
244 // use their equality operator.
245 return left != right;
246 }
247 if (left is num && right is num) {
248 switch (op) {
249 case "+": return left + right;
250 case "-": return left - right;
251 case "*": return left * right;
252 case "/": return left / right;
253 case "~/":
254 case "%":
255 if (left is int && right is int && right == 0) {
256 error(send);
257 }
258 return op == "~/" ? left ~/ right : left % right;
259 case "<": return left < right;
260 case "<=": return left <= right;
261 case ">": return left > right;
262 case ">=": return left >= right;
263 }
264 }
265 if (left is int && right is int) {
266 switch (op) {
267 case "|": return left | right;
268 case "&": return left & right;
269 case "<<":
270 // TODO(floitsch): find a better way to guard against shifts to the
271 // left.
272 if (right > 100) error(send);
273 if (right < 0) error(send);
274 return left << right;
275 case ">>":
276 if (right < 0) error(send);
277 return left >> right;
278 case "^": return left ^ right;
279 }
280 }
281 if (left is DartString) {
282 DartString dartString = left;
283 if (op == "+") {
284 if (right is DartString) {
285 return new ConsDartString(dartString, right);
ngeoffray 2012/02/21 11:22:09 Could we have operator+ defined in DartString? (li
floitsch 2012/02/22 10:17:51 let's keep it without +.
286 } else if (right is num ||
287 right is bool ||
288 right === null) {
289 return new ConsDartString(left,
ngeoffray 2012/02/21 11:22:09 Please move ConsDartString from ssa nodes to ast n
floitsch 2012/02/22 10:17:51 Done.
290 new DartString.literal(right.toString()));
291 } else {
292 error(send);
293 }
294 } else if (op == "[]" && right is int) {
ngeoffray 2012/02/21 11:22:09 Is "op == '[]'" equivalent to send.isIndex?
floitsch 2012/02/22 10:17:51 Done.
295 if (0 <= right && right < left.length) {
296 Iterator iterator = dartString.iterator();
297 for (int i = 0; i < right; i++) iterator.next();
298 String oneCharString = new String.fromCharCodes([iterator.next()]);
299 return new DartString.literal(oneCharString);
300 } else {
301 error(send);
302 }
303 }
304 }
305 } else if (send.isPropertyAccess) {
306 Identifier selector = send.selector.asIdentifier();
307 if (selector == null) error(send);
308 if (selector.source != const SourceString("length")) error(send);
309 var receiver = evaluate(send.receiver);
310 if (receiver is DartString) {
311 DartString dartString = receiver;
312 return dartString.length;
313 }
314 compiler.unimplemented(
315 "CompileTimeConstantEvaluator 'length' property-lookup on non-string",
316 node: send);
208 } 317 }
209 return super.visitSend(send); 318 return super.visitSend(send);
210 } 319 }
211 320
212 error(Element element) { 321 visitSendSet(SendSet node) {
322 error(node);
323 }
324
325 error(Node node) {
213 // TODO(floitsch): get the list of constants that are currently compiled 326 // TODO(floitsch): get the list of constants that are currently compiled
214 // and present some kind of stack-trace. 327 // and present some kind of stack-trace.
215 MessageKind kind = MessageKind.NOT_A_COMPILE_TIME_CONSTANT; 328 MessageKind kind = MessageKind.NOT_A_COMPILE_TIME_CONSTANT;
216 List arguments = [element.name]; 329 compiler.reportError(node, new CompileTimeConstantError(kind, const []));
217 Node node = element.parseNode(compiler);
218 compiler.reportError(node, new CompileTimeConstantError(kind, arguments));
219 } 330 }
220 } 331 }
OLDNEW
« no previous file with comments | « no previous file | frog/leg/compiler.dart » ('j') | frog/leg/tree/nodes.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698