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

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

Issue 9642001: Make string juxtaposition combine properly with string interpolations. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed review comments. Created 8 years, 9 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/scanner/listener.dart » ('j') | frog/leg/scanner/listener.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 class Constant implements Hashable { 5 class Constant implements Hashable {
6 const Constant(); 6 const Constant();
7 7
8 bool isNull() => false; 8 bool isNull() => false;
9 /** [isInt] implies [isNum]. */ 9 /** [isInt] implies [isNum]. */
10 bool isInt() => false; 10 bool isInt() => false;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 abstract void writeJsCode(StringBuffer buffer, ConstantHandler handler); 52 abstract void writeJsCode(StringBuffer buffer, ConstantHandler handler);
53 } 53 }
54 54
55 class PrimitiveConstant extends Constant { 55 class PrimitiveConstant extends Constant {
56 abstract get value(); 56 abstract get value();
57 const PrimitiveConstant(); 57 const PrimitiveConstant();
58 58
59 bool operator ==(var other) { 59 bool operator ==(var other) {
60 if (other is !PrimitiveConstant) return false; 60 if (other is !PrimitiveConstant) return false;
61 PrimitiveConstant otherPrimitive = other; 61 PrimitiveConstant otherPrimitive = other;
62 // We use == instead of === so that DartStrings compare correctly. 62 // We use == instead of === so that DartStrings compare correctly.
63 return value == otherPrimitive.value; 63 return value == otherPrimitive.value;
64 } 64 }
65 65
66 String toString() => value.toString(); 66 String toString() => value.toString();
67 } 67 }
68 68
69 class NullConstant extends PrimitiveConstant { 69 class NullConstant extends PrimitiveConstant {
70 const NullConstant(); 70 const NullConstant();
71 bool isNull() => true; 71 bool isNull() => true;
72 get value() => null; 72 get value() => null;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 if (other.isInt()) { 112 if (other.isInt()) {
113 int right = rightNum; 113 int right = rightNum;
114 switch (op) { 114 switch (op) {
115 case "+": return new IntConstant(value + right); 115 case "+": return new IntConstant(value + right);
116 case "-": return new IntConstant(value - right); 116 case "-": return new IntConstant(value - right);
117 case "*": return new IntConstant(value * right); 117 case "*": return new IntConstant(value * right);
118 case "%": return new IntConstant(value % right); 118 case "%": return new IntConstant(value % right);
119 case "~/": return new IntConstant(value ~/ right); 119 case "~/": return new IntConstant(value ~/ right);
120 case "|": return new IntConstant(value | right); 120 case "|": return new IntConstant(value | right);
121 case "&": return new IntConstant(value & right); 121 case "&": return new IntConstant(value & right);
122 case "^": return new IntConstant(value ^ right); 122 case "^": return new IntConstant(value ^ right);
123 case "<<": 123 case "<<":
124 // TODO(floitsch): find a better way to guard against shifts to the 124 // TODO(floitsch): find a better way to guard against shifts to the
125 // left. 125 // left.
126 if (right > 100) return null; 126 if (right > 100) return null;
127 if (right < 0) return null; 127 if (right < 0) return null;
128 return new IntConstant(value << right); 128 return new IntConstant(value << right);
129 case ">>": 129 case ">>":
130 if (right < 0) return null; 130 if (right < 0) return null;
131 return new IntConstant(value >> right); 131 return new IntConstant(value >> right);
132 } 132 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 bool isDouble() => true; 164 bool isDouble() => true;
165 165
166 void writeJsCode(StringBuffer buffer, ConstantHandler handler) { 166 void writeJsCode(StringBuffer buffer, ConstantHandler handler) {
167 if (value.isNaN()) { 167 if (value.isNaN()) {
168 buffer.add("(0/0)"); 168 buffer.add("(0/0)");
169 } else if (value == double.INFINITY) { 169 } else if (value == double.INFINITY) {
170 buffer.add("(1/0)"); 170 buffer.add("(1/0)");
171 } else if (value == -double.INFINITY) { 171 } else if (value == -double.INFINITY) {
172 buffer.add("(-1/0)"); 172 buffer.add("(-1/0)");
173 } else { 173 } else {
174 buffer.add("($value)"); 174 buffer.add("($value)");
175 } 175 }
176 } 176 }
177 177
178 DoubleConstant unaryFold(String op) { 178 DoubleConstant unaryFold(String op) {
179 if (op == "-") return new DoubleConstant(-value); 179 if (op == "-") return new DoubleConstant(-value);
180 return null; 180 return null;
181 } 181 }
182 182
183 Constant binaryFold(String op, Constant other) { 183 Constant binaryFold(String op, Constant other) {
184 if (other.isNum()) { 184 if (other.isNum()) {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 ConstantHandler.writeEscapedString(value, buffer, (reason) { 262 ConstantHandler.writeEscapedString(value, buffer, (reason) {
263 throw new CompilerCancelledException(reason); 263 throw new CompilerCancelledException(reason);
264 }); 264 });
265 buffer.add("'"); 265 buffer.add("'");
266 } 266 }
267 267
268 Constant binaryFold(String op, Constant other) { 268 Constant binaryFold(String op, Constant other) {
269 if (other.isString() && op == "+") { 269 if (other.isString() && op == "+") {
270 StringConstant otherString = other; 270 StringConstant otherString = other;
271 DartString right = otherString.value; 271 DartString right = otherString.value;
272 return new StringConstant(new ConsDartString(value, right)); 272 return new StringConstant(new DartString.cons(value, right));
273 } 273 }
274 // Visit super in case the [op] was "==", "===", "!=" or "!===". 274 // Visit super in case the [op] was "==", "===", "!=" or "!===".
275 return super.binaryFold(op, other); 275 return super.binaryFold(op, other);
276 } 276 }
277 277
278 bool operator ==(var other) { 278 bool operator ==(var other) {
279 if (other is !StringConstant) return false; 279 if (other is !StringConstant) return false;
280 StringConstant otherString = other; 280 StringConstant otherString = other;
281 return (_hashCode == otherString._hashCode) && (value == otherString.value); 281 return (_hashCode == otherString._hashCode) && (value == otherString.value);
282 } 282 }
283 283
284 int hashCode() => _hashCode; 284 int hashCode() => _hashCode;
285 } 285 }
286 286
287 class ObjectConstant extends Constant { 287 class ObjectConstant extends Constant {
288 final Type type; 288 final Type type;
289 289
290 ObjectConstant(this.type); 290 ObjectConstant(this.type);
291 } 291 }
292 292
293 class ListConstant extends ObjectConstant { 293 class ListConstant extends ObjectConstant {
294 final List<Constant> entries; 294 final List<Constant> entries;
295 int _hashCode; 295 int _hashCode;
296 296
297 ListConstant(Type type, this.entries) : super(type) { 297 ListConstant(Type type, this.entries) : super(type) {
298 // TODO(floitsch): create a better hash. 298 // TODO(floitsch): create a better hash.
299 int hash = 0; 299 int hash = 0;
300 for (Constant input in entries) hash ^= input.hashCode(); 300 for (Constant input in entries) hash ^= input.hashCode();
301 _hashCode = hash; 301 _hashCode = hash;
302 } 302 }
303 bool isList() => true; 303 bool isList() => true;
304 304
305 void writeJsCode(StringBuffer buffer, ConstantHandler handler) { 305 void writeJsCode(StringBuffer buffer, ConstantHandler handler) {
306 // TODO(floitsch): we should not need to go through the compiler to make 306 // TODO(floitsch): we should not need to go through the compiler to make
307 // the list constant. 307 // the list constant.
308 String isolatePrototype = "${handler.compiler.namer.ISOLATE}.prototype"; 308 String isolatePrototype = "${handler.compiler.namer.ISOLATE}.prototype";
(...skipping 26 matching lines...) Expand all
335 335
336 int hashCode() => _hashCode; 336 int hashCode() => _hashCode;
337 } 337 }
338 338
339 class ConstructedConstant extends ObjectConstant { 339 class ConstructedConstant extends ObjectConstant {
340 final List<Constant> fields; 340 final List<Constant> fields;
341 int _hashCode; 341 int _hashCode;
342 342
343 ConstructedConstant(Type type, this.fields) : super(type) { 343 ConstructedConstant(Type type, this.fields) : super(type) {
344 assert(type !== null); 344 assert(type !== null);
345 // TODO(floitsch): create a better hash. 345 // TODO(floitsch): create a better hash.
346 int hash = 0; 346 int hash = 0;
347 for (Constant field in fields) { 347 for (Constant field in fields) {
348 hash ^= field.hashCode(); 348 hash ^= field.hashCode();
349 } 349 }
350 hash ^= type.element.hashCode(); 350 hash ^= type.element.hashCode();
351 _hashCode = hash; 351 _hashCode = hash;
352 } 352 }
353 bool isConstructedObject() => true; 353 bool isConstructedObject() => true;
354 354
355 void writeJsCode(StringBuffer buffer, ConstantHandler handler) { 355 void writeJsCode(StringBuffer buffer, ConstantHandler handler) {
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 List<Constant> getConstantsForEmission() { 516 List<Constant> getConstantsForEmission() {
517 return compiledConstants.getKeys(); 517 return compiledConstants.getKeys();
518 } 518 }
519 519
520 String getNameForConstant(Constant constant) { 520 String getNameForConstant(Constant constant) {
521 return compiledConstants[constant]; 521 return compiledConstants[constant];
522 } 522 }
523 523
524 StringBuffer writeJsCode(StringBuffer buffer, Constant value) { 524 StringBuffer writeJsCode(StringBuffer buffer, Constant value) {
525 value.writeJsCode(buffer, this); 525 value.writeJsCode(buffer, this);
526 return buffer; 526 return buffer;
527 } 527 }
528 528
529 StringBuffer writeJsCodeForVariable(StringBuffer buffer, 529 StringBuffer writeJsCodeForVariable(StringBuffer buffer,
530 VariableElement element) { 530 VariableElement element) {
531 if (!initialVariableValues.containsKey(element)) { 531 if (!initialVariableValues.containsKey(element)) {
532 buffer.add("(void 0)"); 532 buffer.add("(void 0)");
533 return buffer; 533 return buffer;
534 // TODO(floitsch): reenable the following lines, once we fixed the rest 534 // TODO(floitsch): reenable the following lines, once we fixed the rest
535 // of the compiler. 535 // of the compiler.
536 /* 536 /*
537 compiler.internalError("No initial value for given element", 537 compiler.internalError("No initial value for given element",
538 element: element); 538 element: element);
539 */ 539 */
540 } 540 }
541 Constant constant = initialVariableValues[element]; 541 Constant constant = initialVariableValues[element];
542 if (constant.isObject()) { 542 if (constant.isObject()) {
543 String name = compiledConstants[constant]; 543 String name = compiledConstants[constant];
544 buffer.add("${compiler.namer.ISOLATE}.prototype.$name"); 544 buffer.add("${compiler.namer.ISOLATE}.prototype.$name");
545 } else { 545 } else {
546 writeJsCode(buffer, constant); 546 writeJsCode(buffer, constant);
547 } 547 }
548 return buffer; 548 return buffer;
549 } 549 }
550 550
551 /** 551 /**
552 * Write the contents of the quoted string to a [StringBuffer] in 552 * Write the contents of the quoted string to a [StringBuffer] in
553 * a form that is valid as JavaScript string literal content. 553 * a form that is valid as JavaScript string literal content.
554 * The string is assumed quoted by single quote characters. 554 * The string is assumed quoted by single quote characters.
555 */ 555 */
556 static void writeEscapedString(DartString string, 556 static void writeEscapedString(DartString string,
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 622
623 visitNode(Node node) { 623 visitNode(Node node) {
624 compiler.unimplemented("CompileTimeConstantEvaluator", node: node); 624 compiler.unimplemented("CompileTimeConstantEvaluator", node: node);
625 } 625 }
626 626
627 Constant visitLiteralBool(LiteralBool node) { 627 Constant visitLiteralBool(LiteralBool node) {
628 // TODO(floitsch): make BoolConstant a factory and cache the two values 628 // TODO(floitsch): make BoolConstant a factory and cache the two values
629 // there. 629 // there.
630 return node.value ? const BoolConstant(true) : const BoolConstant(false); 630 return node.value ? const BoolConstant(true) : const BoolConstant(false);
631 } 631 }
632 632
633 Constant visitLiteralDouble(LiteralDouble node) { 633 Constant visitLiteralDouble(LiteralDouble node) {
634 return new DoubleConstant(node.value); 634 return new DoubleConstant(node.value);
635 } 635 }
636 636
637 Constant visitLiteralInt(LiteralInt node) { 637 Constant visitLiteralInt(LiteralInt node) {
638 return new IntConstant(node.value); 638 return new IntConstant(node.value);
639 } 639 }
640 640
641 Constant visitLiteralList(LiteralList node) { 641 Constant visitLiteralList(LiteralList node) {
642 if (!node.isConst()) error(node); 642 if (!node.isConst()) error(node);
643 List arguments = []; 643 List arguments = [];
644 for (Link<Node> link = node.elements.nodes; 644 for (Link<Node> link = node.elements.nodes;
645 !link.isEmpty(); 645 !link.isEmpty();
646 link = link.tail) { 646 link = link.tail) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
718 arguments); 718 arguments);
719 } 719 }
720 720
721 error(Node node) { 721 error(Node node) {
722 // TODO(floitsch): get the list of constants that are currently compiled 722 // TODO(floitsch): get the list of constants that are currently compiled
723 // and present some kind of stack-trace. 723 // and present some kind of stack-trace.
724 MessageKind kind = MessageKind.NOT_A_COMPILE_TIME_CONSTANT; 724 MessageKind kind = MessageKind.NOT_A_COMPILE_TIME_CONSTANT;
725 compiler.reportError(node, new CompileTimeConstantError(kind, const [])); 725 compiler.reportError(node, new CompileTimeConstantError(kind, const []));
726 } 726 }
727 } 727 }
OLDNEW
« no previous file with comments | « no previous file | frog/leg/scanner/listener.dart » ('j') | frog/leg/scanner/listener.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698