[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