[Jython-checkins] jython: Set comprehension.
frank.wierzbicki
jython-checkins at python.org
Fri Mar 9 00:59:47 CET 2012
http://hg.python.org/jython/rev/1370d5c27aa4
changeset: 6315:1370d5c27aa4
user: Frank Wierzbicki <fwierzbicki at gmail.com>
date: Thu Mar 08 15:59:09 2012 -0800
summary:
Set comprehension.
files:
grammar/Python.g | 73 ++++++---
src/org/python/antlr/GrammarActions.java | 6 +-
src/org/python/antlr/ast/AstModule.java | 1 +
src/org/python/compiler/CodeCompiler.java | 36 ++++-
src/org/python/compiler/ScopesCompiler.java | 10 +
5 files changed, 93 insertions(+), 33 deletions(-)
diff --git a/grammar/Python.g b/grammar/Python.g
--- a/grammar/Python.g
+++ b/grammar/Python.g
@@ -132,6 +132,7 @@
import org.python.antlr.ast.Repr;
import org.python.antlr.ast.Return;
import org.python.antlr.ast.Set;
+import org.python.antlr.ast.SetComp;
import org.python.antlr.ast.Slice;
import org.python.antlr.ast.Str;
import org.python.antlr.ast.Subscript;
@@ -1717,7 +1718,10 @@
| LCURLY
(dictorsetmaker
{
- if ($dictorsetmaker.keys != null && $dictorsetmaker.values == null) {
+ if ($dictorsetmaker.etype != null) {
+ etype = $dictorsetmaker.etype;
+ }
+ else if ($dictorsetmaker.keys != null && $dictorsetmaker.values == null) {
etype = new Set($LCURLY, actions.castExprs($dictorsetmaker.keys));
} else {
etype = new Dict($LCURLY, actions.castExprs($dictorsetmaker.keys),
@@ -1783,7 +1787,7 @@
) (COMMA)?
;
-//testlist_gexp: test ( gen_for | (',' test)* [','] )
+//testlist_gexp: test ( comp_for | (',' test)* [','] )
testlist_gexp
@init {
expr etype = null;
@@ -1801,7 +1805,7 @@
etype = new Tuple($testlist_gexp.start, actions.castExprs($t), $expr::ctype);
}
| -> test
- | (gen_for[gens]
+ | (comp_for[gens]
{
Collections.reverse(gens);
List<comprehension> c = gens;
@@ -1971,21 +1975,36 @@
//dictmaker: test ':' test (',' test ':' test)* [',']
dictorsetmaker
- returns [List keys, List values]
+ returns [List keys, List values, expr etype]
+ at init {
+ List gens = new ArrayList();
+}
: k+=test[expr_contextType.Load]
- (COLON v+=test[expr_contextType.Load]
- (options {k=2;}:COMMA k+=test[expr_contextType.Load] COLON v+=test[expr_contextType.Load])*
+ (
+ (COLON v+=test[expr_contextType.Load]
+ (options {k=2;}:COMMA k+=test[expr_contextType.Load] COLON v+=test[expr_contextType.Load])*
+ {
+ $keys = $k;
+ $values= $v;
+ }
+ |(COMMA k+=test[expr_contextType.Load])*
+ {
+ $keys = $k;
+ $values = null;
+ }
+ )
+ (COMMA)?
+ | comp_for[gens]
{
- $keys = $k;
- $values= $v;
+ Collections.reverse(gens);
+ List<comprehension> c = gens;
+ expr e = actions.castExpr($k.get(0));
+ if (e instanceof Context) {
+ ((Context)e).setContext(expr_contextType.Load);
+ }
+ $etype = new SetComp($dictorsetmaker.start, actions.castExpr($k.get(0)), c);
}
- |(COMMA k+=test[expr_contextType.Load])*
- {
- $keys = $k;
- $values = null;
- }
)
- (COMMA)?
;
//classdef: 'class' NAME ['(' [testlist] ')'] ':' suite
@@ -2046,7 +2065,7 @@
}
;
-//argument: test [gen_for] | test '=' test # Really [keyword '='] test
+//argument: test [comp_for] | test '=' test # Really [keyword '='] test
argument
[List arguments, List kws, List gens, boolean first, boolean afterStar] returns [boolean genarg]
: t1=test[expr_contextType.Load]
@@ -2068,10 +2087,10 @@
exprs.add(actions.castExpr($t2.tree));
$kws.add(exprs);
}
- | gen_for[$gens]
+ | comp_for[$gens]
{
if (!first) {
- actions.errorGenExpNotSoleArg($gen_for.tree);
+ actions.errorGenExpNotSoleArg($comp_for.tree);
}
$genarg = true;
Collections.reverse($gens);
@@ -2116,27 +2135,27 @@
}
;
-//gen_iter: gen_for | gen_if
-gen_iter [List gens, List ifs]
- : gen_for[gens]
- | gen_if[gens, ifs]
+//comp_iter: comp_for | comp_if
+comp_iter [List gens, List ifs]
+ : comp_for[gens]
+ | comp_if[gens, ifs]
;
-//gen_for: 'for' exprlist 'in' or_test [gen_iter]
-gen_for [List gens]
+//comp_for: 'for' exprlist 'in' or_test [comp_iter]
+comp_for [List gens]
@init {
List ifs = new ArrayList();
}
- : FOR exprlist[expr_contextType.Store] IN or_test[expr_contextType.Load] gen_iter[gens, ifs]?
+ : FOR exprlist[expr_contextType.Store] IN or_test[expr_contextType.Load] comp_iter[gens, ifs]?
{
Collections.reverse(ifs);
gens.add(new comprehension($FOR, $exprlist.etype, actions.castExpr($or_test.tree), ifs));
}
;
-//gen_if: 'if' old_test [gen_iter]
-gen_if[List gens, List ifs]
- : IF test[expr_contextType.Load] gen_iter[gens, ifs]?
+//comp_if: 'if' old_test [comp_iter]
+comp_if[List gens, List ifs]
+ : IF test[expr_contextType.Load] comp_iter[gens, ifs]?
{
ifs.add(actions.castExpr($test.tree));
}
diff --git a/src/org/python/antlr/GrammarActions.java b/src/org/python/antlr/GrammarActions.java
--- a/src/org/python/antlr/GrammarActions.java
+++ b/src/org/python/antlr/GrammarActions.java
@@ -38,6 +38,7 @@
import org.python.antlr.ast.TryFinally;
import org.python.antlr.ast.Tuple;
import org.python.antlr.ast.Repr;
+import org.python.antlr.ast.SetComp;
import org.python.antlr.ast.Str;
import org.python.antlr.ast.UnaryOp;
import org.python.antlr.ast.While;
@@ -330,7 +331,10 @@
} else if (tree instanceof ListComp) {
ListComp lc = (ListComp)tree;
recurseSetContext(lc.getInternalElt(), context);
- } else if (!(tree instanceof ListComp)) {
+ } else if (tree instanceof SetComp) {
+ SetComp lc = (SetComp)tree;
+ recurseSetContext(lc.getInternalElt(), context);
+ } else if (!(tree instanceof ListComp) && (!(tree instanceof SetComp))) {
for (int i=0; i<tree.getChildCount(); i++) {
recurseSetContext(tree.getChild(i), context);
}
diff --git a/src/org/python/antlr/ast/AstModule.java b/src/org/python/antlr/ast/AstModule.java
--- a/src/org/python/antlr/ast/AstModule.java
+++ b/src/org/python/antlr/ast/AstModule.java
@@ -77,6 +77,7 @@
dict.__setitem__("Raise", Raise.TYPE);
dict.__setitem__("Repr", Repr.TYPE);
dict.__setitem__("Return", Return.TYPE);
+ dict.__setitem__("SetComp", SetComp.TYPE);
dict.__setitem__("Slice", Slice.TYPE);
dict.__setitem__("Str", Str.TYPE);
dict.__setitem__("Subscript", Subscript.TYPE);
diff --git a/src/org/python/compiler/CodeCompiler.java b/src/org/python/compiler/CodeCompiler.java
--- a/src/org/python/compiler/CodeCompiler.java
+++ b/src/org/python/compiler/CodeCompiler.java
@@ -53,6 +53,7 @@
import org.python.antlr.ast.Repr;
import org.python.antlr.ast.Return;
import org.python.antlr.ast.Set;
+import org.python.antlr.ast.SetComp;
import org.python.antlr.ast.Slice;
import org.python.antlr.ast.Str;
import org.python.antlr.ast.Subscript;
@@ -2135,16 +2136,43 @@
code.invokevirtual(p(PyObject.class), "__getattr__", sig(PyObject.class, String.class));
String tmp_append = "_[" + node.getLine() + "_" + node.getCharPositionInLine() + "]";
+ finishComp(node, node.getInternalElt(), node.getInternalGenerators(), tmp_append);
+
+ return null;
+ }
+
+
+ @Override
+ public Object visitSetComp(SetComp node) throws Exception {
+ code.new_(p(PySet.class));
+
+ code.dup();
+ code.invokespecial(p(PySet.class), "<init>", sig(Void.TYPE));
+
+ code.dup();
+
+ code.ldc("add");
+
+ code.invokevirtual(p(PyObject.class), "__getattr__", sig(PyObject.class, String.class));
+ String tmp_append = "_{" + node.getLine() + "_" + node.getCharPositionInLine() + "}";
+
+ finishComp(node, node.getInternalElt(), node.getInternalGenerators(), tmp_append);
+
+ return null;
+ }
+
+ private void finishComp(expr node, expr elt, java.util.List<comprehension> generators,
+ String tmp_append) throws Exception {
set(new Name(node, tmp_append, expr_contextType.Store));
java.util.List<expr> args = new ArrayList<expr>();
- args.add(node.getInternalElt());
+ args.add(elt);
stmt n = new Expr(node, new Call(node, new Name(node, tmp_append, expr_contextType.Load),
args,
new ArrayList<keyword>(), null, null));
- for (int i = node.getInternalGenerators().size() - 1; i >= 0; i--) {
- comprehension lc = node.getInternalGenerators().get(i);
+ for (int i = generators.size() - 1; i >= 0; i--) {
+ comprehension lc = generators.get(i);
for (int j = lc.getInternalIfs().size() - 1; j >= 0; j--) {
java.util.List<stmt> body = new ArrayList<stmt>();
body.add(n);
@@ -2160,8 +2188,6 @@
java.util.List<expr> targets = new ArrayList<expr>();
targets.add(new Name(n, tmp_append, expr_contextType.Del));
visit(new Delete(n, targets));
-
- return null;
}
@Override
diff --git a/src/org/python/compiler/ScopesCompiler.java b/src/org/python/compiler/ScopesCompiler.java
--- a/src/org/python/compiler/ScopesCompiler.java
+++ b/src/org/python/compiler/ScopesCompiler.java
@@ -17,6 +17,7 @@
import org.python.antlr.ast.ListComp;
import org.python.antlr.ast.Name;
import org.python.antlr.ast.Return;
+import org.python.antlr.ast.SetComp;
import org.python.antlr.ast.With;
import org.python.antlr.ast.Yield;
import org.python.antlr.ast.arguments;
@@ -284,6 +285,15 @@
}
@Override
+ public Object visitSetComp(SetComp node) throws Exception {
+ String tmp = "_{" + node.getLine() + "_" + node.getCharPositionInLine()
+ + "}";
+ cur.addBound(tmp);
+ traverse(node);
+ return null;
+ }
+
+ @Override
public Object visitYield(Yield node) throws Exception {
cur.defineAsGenerator(node);
cur.yield_count++;
--
Repository URL: http://hg.python.org/jython
More information about the Jython-checkins
mailing list