| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 * Top level generator object for writing code and keeping track of | 6 * Top level generator object for writing code and keeping track of |
| 7 * dependencies. | 7 * dependencies. |
| 8 * | 8 * |
| 9 * Should have two compilation models, but only one implemented so far. | 9 * Should have two compilation models, but only one implemented so far. |
| 10 * | 10 * |
| (...skipping 990 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1001 world.gen.genMethod(meth, this); | 1001 world.gen.genMethod(meth, this); |
| 1002 return meth; | 1002 return meth; |
| 1003 } | 1003 } |
| 1004 | 1004 |
| 1005 visitBool(Expression node) { | 1005 visitBool(Expression node) { |
| 1006 // Boolean conversions in if/while/do/for/conditions require non-null bool. | 1006 // Boolean conversions in if/while/do/for/conditions require non-null bool. |
| 1007 | 1007 |
| 1008 // TODO(jmesserly): why do we have this rule? It seems inconsistent with | 1008 // TODO(jmesserly): why do we have this rule? It seems inconsistent with |
| 1009 // the rest of the type system, and just causes bogus asserts unless all | 1009 // the rest of the type system, and just causes bogus asserts unless all |
| 1010 // bools are initialized to false. | 1010 // bools are initialized to false. |
| 1011 return visitValue(node).convertToNonNullBool(this, node); | 1011 return visitValue(node).convertTo(this, world.nonNullBool, node); |
| 1012 } | 1012 } |
| 1013 | 1013 |
| 1014 visitValue(Expression node) { | 1014 visitValue(Expression node) { |
| 1015 if (node == null) return null; | 1015 if (node == null) return null; |
| 1016 | 1016 |
| 1017 var value = node.visit(this); | 1017 var value = node.visit(this); |
| 1018 value.checkFirstClass(node.span); | 1018 value.checkFirstClass(node.span); |
| 1019 return value; | 1019 return value; |
| 1020 } | 1020 } |
| 1021 | 1021 |
| (...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1590 if (kind == TokenKind.AND || kind == TokenKind.OR) { | 1590 if (kind == TokenKind.AND || kind == TokenKind.OR) { |
| 1591 var x = visitValue(node.x); | 1591 var x = visitValue(node.x); |
| 1592 var y = visitValue(node.y); | 1592 var y = visitValue(node.y); |
| 1593 final code = '${x.code} ${node.op} ${y.code}'; | 1593 final code = '${x.code} ${node.op} ${y.code}'; |
| 1594 if (x.isConst && y.isConst) { | 1594 if (x.isConst && y.isConst) { |
| 1595 var value = (kind == TokenKind.AND) | 1595 var value = (kind == TokenKind.AND) |
| 1596 ? x.actualValue && y.actualValue : x.actualValue || y.actualValue; | 1596 ? x.actualValue && y.actualValue : x.actualValue || y.actualValue; |
| 1597 return new EvaluatedValue(x.type, value, '$value', node.span); | 1597 return new EvaluatedValue(x.type, value, '$value', node.span); |
| 1598 } | 1598 } |
| 1599 var ret = new Value(Type.union(x.type, y.type), code, node.span); | 1599 var ret = new Value(Type.union(x.type, y.type), code, node.span); |
| 1600 return ret.convertToNonNullBool(this, node); | 1600 return ret.convertTo(this, world.nonNullBool, node); |
| 1601 } else if (kind == TokenKind.EQ_STRICT || kind == TokenKind.NE_STRICT) { | 1601 } else if (kind == TokenKind.EQ_STRICT || kind == TokenKind.NE_STRICT) { |
| 1602 var x = visitValue(node.x); | 1602 var x = visitValue(node.x); |
| 1603 var y = visitValue(node.y); | 1603 var y = visitValue(node.y); |
| 1604 if (x.isConst && y.isConst) { | 1604 if (x.isConst && y.isConst) { |
| 1605 var value = kind == TokenKind.EQ_STRICT | 1605 var value = kind == TokenKind.EQ_STRICT |
| 1606 // Note: it is ok to use == and not === here since all of these | 1606 // Note: it is ok to use == and not === here since all of these |
| 1607 // constant comparisons are applied to doubles, bool, or strings. | 1607 // constant comparisons are applied to doubles, bool, or strings. |
| 1608 // We need it for the compile-time evaluator because | 1608 // We need it for the compile-time evaluator because |
| 1609 // (9).toDouble() === 9.0 is false in dartvm. | 1609 // (9).toDouble() === 9.0 is false in dartvm. |
| 1610 ? x.actualValue == y.actualValue : x.actualValue != y.actualValue; | 1610 ? x.actualValue == y.actualValue : x.actualValue != y.actualValue; |
| 1611 return new EvaluatedValue(world.boolType, value, "$value", node.span); | 1611 return new EvaluatedValue(world.nonNullBool, value, "$value", |
| 1612 node.span); |
| 1612 } | 1613 } |
| 1613 if (x.code == 'null' || y.code == 'null') { | 1614 if (x.code == 'null' || y.code == 'null') { |
| 1614 // Switching to == ensures that null and undefined are interchangable. | 1615 // Switching to == ensures that null and undefined are interchangable. |
| 1615 final op = node.op.toString().substring(0,2); | 1616 final op = node.op.toString().substring(0,2); |
| 1616 return new Value(world.boolType, '${x.code} $op ${y.code}', node.span); | 1617 return new Value(world.nonNullBool, '${x.code} $op ${y.code}', |
| 1618 node.span); |
| 1617 } else { | 1619 } else { |
| 1618 // TODO(jimhug): Resolve issue with undefined and null here. | 1620 // TODO(jimhug): Resolve issue with undefined and null here. |
| 1619 return new Value(world.boolType, '${x.code} ${node.op} ${y.code}', | 1621 return new Value(world.nonNullBool, '${x.code} ${node.op} ${y.code}', |
| 1620 node.span); | 1622 node.span); |
| 1621 } | 1623 } |
| 1622 } | 1624 } |
| 1623 | 1625 |
| 1624 final assignKind = TokenKind.kindFromAssign(node.op.kind); | 1626 final assignKind = TokenKind.kindFromAssign(node.op.kind); |
| 1625 if (assignKind == -1) { | 1627 if (assignKind == -1) { |
| 1626 final x = visitValue(node.x); | 1628 final x = visitValue(node.x); |
| 1627 final y = visitValue(node.y); | 1629 final y = visitValue(node.y); |
| 1628 var name = TokenKind.binaryMethodName(node.op.kind); | 1630 var name = TokenKind.binaryMethodName(node.op.kind); |
| 1629 if (node.op.kind == TokenKind.NE) { | 1631 if (node.op.kind == TokenKind.NE) { |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1801 new TypeReference(node.span, world.numType), '1', node.span); | 1803 new TypeReference(node.span, world.numType), '1', node.span); |
| 1802 | 1804 |
| 1803 return _visitAssign(kind, node.self, operand, node, null); | 1805 return _visitAssign(kind, node.self, operand, node, null); |
| 1804 } | 1806 } |
| 1805 case TokenKind.NOT: | 1807 case TokenKind.NOT: |
| 1806 // TODO(jimhug): Issue #359 seeks to clarify this behavior. | 1808 // TODO(jimhug): Issue #359 seeks to clarify this behavior. |
| 1807 if (value.type.isBool && value.isConst) { | 1809 if (value.type.isBool && value.isConst) { |
| 1808 var newVal = !value.actualValue; | 1810 var newVal = !value.actualValue; |
| 1809 return new EvaluatedValue(value.type, newVal, '${newVal}', node.span); | 1811 return new EvaluatedValue(value.type, newVal, '${newVal}', node.span); |
| 1810 } else { | 1812 } else { |
| 1811 var newVal = value.convertToNonNullBool(this, node); | 1813 var newVal = value.convertTo(this, world.nonNullBool, node); |
| 1812 return new Value(world.boolType, '!${newVal.code}', node.span); | 1814 return new Value(newVal.type, '!${newVal.code}', node.span); |
| 1813 } | 1815 } |
| 1814 | 1816 |
| 1815 case TokenKind.ADD: | 1817 case TokenKind.ADD: |
| 1816 // TODO(jimhug): Issue #359 seeks to clarify this behavior. | 1818 // TODO(jimhug): Issue #359 seeks to clarify this behavior. |
| 1817 return value.convertTo(this, world.numType, node); | 1819 return value.convertTo(this, world.numType, node); |
| 1818 | 1820 |
| 1819 case TokenKind.SUB: | 1821 case TokenKind.SUB: |
| 1820 case TokenKind.BIT_NOT: | 1822 case TokenKind.BIT_NOT: |
| 1821 if (node.op.kind == TokenKind.BIT_NOT) { | 1823 if (node.op.kind == TokenKind.BIT_NOT) { |
| 1822 return value.invoke(this, '\$bit_not', node, Arguments.EMPTY); | 1824 return value.invoke(this, '\$bit_not', node, Arguments.EMPTY); |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2226 result.add(new Value(world.varType, '\$$i', null, /*needsTemp:*/false)); | 2228 result.add(new Value(world.varType, '\$$i', null, /*needsTemp:*/false)); |
| 2227 } | 2229 } |
| 2228 for (int i = bareCount; i < length; i++) { | 2230 for (int i = bareCount; i < length; i++) { |
| 2229 var name = getName(i); | 2231 var name = getName(i); |
| 2230 if (name == null) name = '\$$i'; | 2232 if (name == null) name = '\$$i'; |
| 2231 result.add(new Value(world.varType, name, null, /*needsTemp:*/false)); | 2233 result.add(new Value(world.varType, name, null, /*needsTemp:*/false)); |
| 2232 } | 2234 } |
| 2233 return new Arguments(nodes, result); | 2235 return new Arguments(nodes, result); |
| 2234 } | 2236 } |
| 2235 } | 2237 } |
| OLD | NEW |