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

Side by Side Diff: frog/gen.dart

Issue 8802028: fix set index bug in frog. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 9 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 | frog/minfrog » ('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) 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 1160 matching lines...) Expand 10 before | Expand all | Expand 10 after
1171 visitTypedValue(Expression node, Type expectedType) { 1171 visitTypedValue(Expression node, Type expectedType) {
1172 return visitValue(node).convertTo(this, expectedType, node); 1172 return visitValue(node).convertTo(this, expectedType, node);
1173 } 1173 }
1174 1174
1175 visitVoid(Expression node) { 1175 visitVoid(Expression node) {
1176 // TODO(jmesserly): should we generalize this? 1176 // TODO(jmesserly): should we generalize this?
1177 if (node is PostfixExpression) { 1177 if (node is PostfixExpression) {
1178 var value = visitPostfixExpression(node, /*isVoid:*/true); 1178 var value = visitPostfixExpression(node, /*isVoid:*/true);
1179 value.checkFirstClass(node.span); 1179 value.checkFirstClass(node.span);
1180 return value; 1180 return value;
1181 } else if (node is BinaryExpression) {
1182 var value = visitBinaryExpression(node, /*isVoid:*/true);
Jennifer Messerly 2011/12/06 01:06:39 you could actually pass "isVoid:true" now :)
1183 value.checkFirstClass(node.span);
1184 return value;
1181 } 1185 }
1182 // TODO(jimhug): Some level of warnings for non-void things here? 1186 // TODO(jimhug): Some level of warnings for non-void things here?
1183 return visitValue(node); 1187 return visitValue(node);
1184 } 1188 }
1185 1189
1186 // ******************* Statements ******************* 1190 // ******************* Statements *******************
1187 1191
1188 bool visitDietStatement(DietStatement node) { 1192 bool visitDietStatement(DietStatement node) {
1189 var parser = new Parser(node.span.file, startOffset: node.span.start); 1193 var parser = new Parser(node.span.file, startOffset: node.span.start);
1190 visitStatementsInBlock(parser.block()); 1194 visitStatementsInBlock(parser.block());
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after
1742 1746
1743 return target.invoke(this, name, position, _makeArgs(node.arguments)); 1747 return target.invoke(this, name, position, _makeArgs(node.arguments));
1744 } 1748 }
1745 1749
1746 visitIndexExpression(IndexExpression node) { 1750 visitIndexExpression(IndexExpression node) {
1747 var target = visitValue(node.target); 1751 var target = visitValue(node.target);
1748 var index = visitValue(node.index); 1752 var index = visitValue(node.index);
1749 return target.invoke(this, ':index', node, new Arguments(null, [index])); 1753 return target.invoke(this, ':index', node, new Arguments(null, [index]));
1750 } 1754 }
1751 1755
1752 visitBinaryExpression(BinaryExpression node) { 1756 visitBinaryExpression(BinaryExpression node, [bool isVoid = false]) {
1753 final kind = node.op.kind; 1757 final kind = node.op.kind;
1754 // TODO(jimhug): Ensure these have same semantics as JS! 1758 // TODO(jimhug): Ensure these have same semantics as JS!
1755 if (kind == TokenKind.AND || kind == TokenKind.OR) { 1759 if (kind == TokenKind.AND || kind == TokenKind.OR) {
1756 var x = visitTypedValue(node.x, world.nonNullBool); 1760 var x = visitTypedValue(node.x, world.nonNullBool);
1757 var y = visitTypedValue(node.y, world.nonNullBool); 1761 var y = visitTypedValue(node.y, world.nonNullBool);
1758 final code = '${x.code} ${node.op} ${y.code}'; 1762 final code = '${x.code} ${node.op} ${y.code}';
1759 if (x.isConst && y.isConst) { 1763 if (x.isConst && y.isConst) {
1760 var value = (kind == TokenKind.AND) 1764 var value = (kind == TokenKind.AND)
1761 ? x.actualValue && y.actualValue : x.actualValue || y.actualValue; 1765 ? x.actualValue && y.actualValue : x.actualValue || y.actualValue;
1762 return new EvaluatedValue(world.nonNullBool, value, '$value', 1766 return new EvaluatedValue(world.nonNullBool, value, '$value',
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1809 var name = TokenKind.binaryMethodName(node.op.kind); 1813 var name = TokenKind.binaryMethodName(node.op.kind);
1810 if (node.op.kind == TokenKind.NE) { 1814 if (node.op.kind == TokenKind.NE) {
1811 name = ':ne'; 1815 name = ':ne';
1812 } 1816 }
1813 if (name == null) { 1817 if (name == null) {
1814 world.internalError('unimplemented binary op ${node.op}', node.span); 1818 world.internalError('unimplemented binary op ${node.op}', node.span);
1815 return; 1819 return;
1816 } 1820 }
1817 return x.invoke(this, name, node, new Arguments(null, [y])); 1821 return x.invoke(this, name, node, new Arguments(null, [y]));
1818 } else { 1822 } else {
1819 return _visitAssign(assignKind, node.x, node.y, node, null); 1823 return _visitAssign(assignKind, node.x, node.y, node, null, isVoid);
1820 } 1824 }
1821 } 1825 }
1822 1826
1823 /** 1827 /**
1824 * Visits an assignment expression. 1828 * Visits an assignment expression.
1825 * Note: captureOriginal can optionally capture the original value of the 1829 * Note: captureOriginal can optionally capture the original value of the
1826 * left side. This is used by postfix expressions to ensure they return the 1830 * left side. This is used by postfix expressions to ensure they return the
1827 * original value, before it has been modified. 1831 * original value, before it has been modified.
1828 */ 1832 */
1829 _visitAssign(int kind, Expression xn, Expression yn, Node position, 1833 _visitAssign(int kind, Expression xn, Expression yn, Node position,
1830 Value captureOriginal(Value right)) { 1834 Value captureOriginal(Value right), [bool isVoid = false]) {
1831 1835
1832 if (captureOriginal == null) { 1836 if (captureOriginal == null) {
1833 captureOriginal = (x) => x; 1837 captureOriginal = (x) => x;
1834 } 1838 }
1835 1839
1836 // TODO(jimhug): The usual battle with making assign impl not look ugly. 1840 // TODO(jimhug): The usual battle with making assign impl not look ugly.
1837 if (xn is VarExpression) { 1841 if (xn is VarExpression) {
1838 return _visitVarAssign(kind, xn, yn, position, captureOriginal); 1842 return _visitVarAssign(kind, xn, yn, position, captureOriginal);
1839 } else if (xn is IndexExpression) { 1843 } else if (xn is IndexExpression) {
1840 return _visitIndexAssign(kind, xn, yn, position, captureOriginal); 1844 return _visitIndexAssign(kind, xn, yn, position, captureOriginal, isVoid);
1841 } else if (xn is DotExpression) { 1845 } else if (xn is DotExpression) {
1842 return _visitDotAssign(kind, xn, yn, position, captureOriginal); 1846 return _visitDotAssign(kind, xn, yn, position, captureOriginal);
1843 } else { 1847 } else {
1844 world.error('illegal lhs', xn.span); 1848 world.error('illegal lhs', xn.span);
1845 } 1849 }
1846 } 1850 }
1847 1851
1848 // TODO(jmesserly): it'd be nice if we didn't have to deal directly with 1852 // TODO(jmesserly): it'd be nice if we didn't have to deal directly with
1849 // MemberSets here and in visitVarExpression. 1853 // MemberSets here and in visitVarExpression.
1850 _visitVarAssign(int kind, VarExpression xn, Expression yn, Node position, 1854 _visitVarAssign(int kind, VarExpression xn, Expression yn, Node position,
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1921 } else { 1925 } else {
1922 var right = x; 1926 var right = x;
1923 right = captureOriginal(right); 1927 right = captureOriginal(right);
1924 y = right.invoke(this, TokenKind.binaryMethodName(kind), 1928 y = right.invoke(this, TokenKind.binaryMethodName(kind),
1925 position, new Arguments(null, [y])); 1929 position, new Arguments(null, [y]));
1926 return new Value(y.type, '${x.code} = ${y.code}', position.span); 1930 return new Value(y.type, '${x.code} = ${y.code}', position.span);
1927 } 1931 }
1928 } 1932 }
1929 1933
1930 _visitIndexAssign(int kind, IndexExpression xn, Expression yn, Node position, 1934 _visitIndexAssign(int kind, IndexExpression xn, Expression yn, Node position,
1931 Value captureOriginal(Value right)) { 1935 Value captureOriginal(Value right), [bool isVoid = false]) {
1932 var target = visitValue(xn.target); 1936 var target = visitValue(xn.target);
1933 var index = visitValue(xn.index); 1937 var index = visitValue(xn.index);
1934 var y = visitValue(yn); 1938 var y = visitValue(yn);
1935 1939
1936 var tmptarget = target; 1940 var tmptarget = target;
1937 var tmpindex = index; 1941 var tmpindex = index;
1938 if (kind != 0) { 1942 if (kind != 0) {
1939 tmptarget = getTemp(target); 1943 tmptarget = getTemp(target);
1940 tmpindex = getTemp(index); 1944 tmpindex = getTemp(index);
1941 index = assignTemp(tmpindex, index); 1945 index = assignTemp(tmpindex, index);
1942 var right = tmptarget.invoke(this, ':index', 1946 var right = tmptarget.invoke(this, ':index',
1943 position, new Arguments(null, [tmpindex])); 1947 position, new Arguments(null, [tmpindex]));
1944 right = captureOriginal(right); 1948 right = captureOriginal(right);
1945 y = right.invoke(this, TokenKind.binaryMethodName(kind), 1949 y = right.invoke(this, TokenKind.binaryMethodName(kind),
1946 position, new Arguments(null, [y])); 1950 position, new Arguments(null, [y]));
1947 } 1951 }
1952
1953 var tmpy = null;
1954 // If the assignment is an expression statement (x[i] = y;) it is translated
1955 // as (x.$setindex(i, y)), otherwise as (x.$setindex(i, t = y), t).
1956 if (!isVoid) {
1957 tmpy = getTemp(y);
1958 y = assignTemp(tmpy, y);
1959 }
1948 var ret = assignTemp(tmptarget, target).invoke(this, ':setindex', 1960 var ret = assignTemp(tmptarget, target).invoke(this, ':setindex',
1949 position, new Arguments(null, [index, y])); 1961 position, new Arguments(null, [index, y]));
1962 if (tmpy != null) {
1963 ret = new Value(ret.type, '(${ret.code}, ${tmpy.code})', ret.span);
1964 if (tmpy != y) freeTemp(tmpy);
1965 }
1950 if (tmptarget != target) freeTemp(tmptarget); 1966 if (tmptarget != target) freeTemp(tmptarget);
1951 if (tmpindex != index) freeTemp(tmpindex); 1967 if (tmpindex != index) freeTemp(tmpindex);
1952 return ret; 1968 return ret;
1953 } 1969 }
1954 1970
1955 _visitDotAssign(int kind, DotExpression xn, Expression yn, Node position, 1971 _visitDotAssign(int kind, DotExpression xn, Expression yn, Node position,
1956 Value captureOriginal(Value right)) { 1972 Value captureOriginal(Value right)) {
1957 1973
1958 // This is not visitValue because types are assignable through . 1974 // This is not visitValue because types are assignable through .
1959 var target = xn.self.visit(this); 1975 var target = xn.self.visit(this);
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after
2449 result.add(new Value(world.varType, '\$$i', null, /*needsTemp:*/false)); 2465 result.add(new Value(world.varType, '\$$i', null, /*needsTemp:*/false));
2450 } 2466 }
2451 for (int i = bareCount; i < length; i++) { 2467 for (int i = bareCount; i < length; i++) {
2452 var name = getName(i); 2468 var name = getName(i);
2453 if (name == null) name = '\$$i'; 2469 if (name == null) name = '\$$i';
2454 result.add(new Value(world.varType, name, null, /*needsTemp:*/false)); 2470 result.add(new Value(world.varType, name, null, /*needsTemp:*/false));
2455 } 2471 }
2456 return new Arguments(nodes, result); 2472 return new Arguments(nodes, result);
2457 } 2473 }
2458 } 2474 }
OLDNEW
« no previous file with comments | « no previous file | frog/minfrog » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698