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

Unified 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: Update status file.wq 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | frog/leg/compiler.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: frog/leg/compile_time_constants.dart
diff --git a/frog/leg/compile_time_constants.dart b/frog/leg/compile_time_constants.dart
index 9a55ecbd1dadd4f473264dc9866855c2ec86f0b0..9171fe296d39fe9dba274e9e68626471da69e87d 100644
--- a/frog/leg/compile_time_constants.dart
+++ b/frog/leg/compile_time_constants.dart
@@ -96,7 +96,15 @@ class CompileTimeConstantHandler extends CompilerTask {
if (value === null) {
buffer.add("(void 0)");
} else if (value is num) {
- buffer.add("($value)");
+ if (value.isNaN()) {
+ buffer.add("(0/0)");
+ } else if (value == double.INFINITY) {
+ buffer.add("(1/0)");
+ } else if (value == -double.INFINITY) {
+ buffer.add("(-1/0)");
+ } else {
+ buffer.add("($value)");
+ }
} else if (value === true) {
buffer.add("true");
} else if (value === false) {
@@ -111,7 +119,7 @@ class CompileTimeConstantHandler extends CompilerTask {
// TODO(floitsch): support more values.
compiler.unimplemented("CompileTimeConstantHandler" +
"writeJsCodeForVariable",
- node: element.parseNode(compiler));
+ element: element);
}
return buffer;
}
@@ -196,25 +204,94 @@ class CompileTimeConstantEvaluator extends AbstractVisitor {
return literal.value;
}
+ // TODO(floitsch): provide better error-messages.
visitSend(Send send) {
Element element = definitions[send];
- if (element !== null && element.kind == ElementKind.FIELD) {
- if (element.isInstanceMember() ||
- element.modifiers === null ||
+ if (Elements.isStaticOrTopLevelField(element)) {
+ if (element.modifiers === null ||
!element.modifiers.isFinal()) {
- error(element);
+ error(send);
}
return constantHandler.compileVariable(element);
+ } else if (send.isPrefix) {
+ assert(send.isOperator);
+ var receiverValue = evaluate(send.receiver);
+ Operator op = send.selector;
+ switch (op.source.stringValue) {
+ case "-":
+ if (receiverValue is !num) error(send);
+ return -receiverValue;
+ case "~":
+ if (receiverValue is !int) error(send);
+ return ~receiverValue;
+ case "!":
+ if (receiverValue is !bool) error(send);
+ return !receiverValue;
+ default:
+ error(send);
+ }
+ } else if (send.isOperator && !send.isPostfix) {
+ assert(send.argumentCount() == 1);
+ var left = evaluate(send.receiver);
+ var right = evaluate(send.argumentsNode.nodes.head);
+ String op = send.selector.asOperator().source.stringValue;
+
+ if (op == "==" || op == "===") {
+ // We use == instead of === so that non-canonicalized DartStrings can
+ // use their equality operator.
+ return left == right;
+ } else if (op == "!=" || op == "!==") {
+ return left != right;
+ }
+ if (left is num && right is num) {
+ switch (op) {
+ case "+": return left + right;
+ case "-": return left - right;
+ case "*": return left * right;
+ case "/": return left / right;
+ case "~/":
+ case "%":
+ if (left is int && right is int && right == 0) {
+ error(send);
+ }
+ return op == "~/" ? left ~/ right : left % right;
+ case "<": return left < right;
+ case "<=": return left <= right;
+ case ">": return left > right;
+ case ">=": return left >= right;
+ }
+ }
+ if (left is int && right is int) {
+ switch (op) {
+ case "|": return left | right;
+ case "&": return left & right;
+ case "<<":
+ // TODO(floitsch): find a better way to guard against shifts to the
+ // left.
+ if (right > 100) error(send);
+ if (right < 0) error(send);
+ return left << right;
+ case ">>":
+ if (right < 0) error(send);
+ return left >> right;
+ case "^": return left ^ right;
+ }
+ }
+ if (left is DartString && right is DartString && op == "+") {
+ return new ConsDartString(left, right);
+ }
}
return super.visitSend(send);
}
- error(Element element) {
+ visitSendSet(SendSet node) {
+ error(node);
+ }
+
+ error(Node node) {
// TODO(floitsch): get the list of constants that are currently compiled
// and present some kind of stack-trace.
MessageKind kind = MessageKind.NOT_A_COMPILE_TIME_CONSTANT;
- List arguments = [element.name];
- Node node = element.parseNode(compiler);
- compiler.reportError(node, new CompileTimeConstantError(kind, arguments));
+ compiler.reportError(node, new CompileTimeConstantError(kind, const []));
}
}
« no previous file with comments | « no previous file | frog/leg/compiler.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698