[Jython-checkins] jython: Dictionary Comprehensions.

frank.wierzbicki jython-checkins at python.org
Sun Mar 11 23:34:54 CET 2012


http://hg.python.org/jython/rev/a4fc69ee524b
changeset:   6317:a4fc69ee524b
user:        Frank Wierzbicki <fwierzbicki at gmail.com>
date:        Sun Mar 11 15:34:46 2012 -0700
summary:
  Dictionary Comprehensions.

files:
  grammar/Python.g                            |  16 ++-
  src/org/python/antlr/GrammarActions.java    |  13 ++-
  src/org/python/compiler/CodeCompiler.java   |  42 ++++++++-
  src/org/python/compiler/ScopesCompiler.java |  10 ++
  4 files changed, 67 insertions(+), 14 deletions(-)


diff --git a/grammar/Python.g b/grammar/Python.g
--- a/grammar/Python.g
+++ b/grammar/Python.g
@@ -102,6 +102,7 @@
 import org.python.antlr.ast.Continue;
 import org.python.antlr.ast.Delete;
 import org.python.antlr.ast.Dict;
+import org.python.antlr.ast.DictComp;
 import org.python.antlr.ast.Ellipsis;
 import org.python.antlr.ast.ErrorMod;
 import org.python.antlr.ast.ExceptHandler;
@@ -1977,10 +1978,17 @@
     : 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])*
-               {
-                   etype = new Dict($lcurly, actions.castExprs($k), actions.castExprs($v));
-               }
+               ( comp_for[gens]
+                 {
+                     Collections.reverse(gens);
+                     List<comprehension> c = gens;
+                     etype = new DictComp($dictorsetmaker.start, actions.castExpr($k.get(0)), actions.castExpr($v.get(0)), c);
+                 }
+               | (options {k=2;}:COMMA k+=test[expr_contextType.Load] COLON v+=test[expr_contextType.Load])*
+                 {
+                     etype = new Dict($lcurly, actions.castExprs($k), actions.castExprs($v));
+                 }
+               )
              |(COMMA k+=test[expr_contextType.Load])*
               {
                   etype = new Set($lcurly, actions.castExprs($k));
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
@@ -23,6 +23,7 @@
 import org.python.antlr.ast.BinOp;
 import org.python.antlr.ast.BoolOp;
 import org.python.antlr.ast.Call;
+import org.python.antlr.ast.DictComp;
 import org.python.antlr.ast.ExtSlice;
 import org.python.antlr.ast.For;
 import org.python.antlr.ast.FunctionDef;
@@ -332,9 +333,15 @@
             ListComp lc = (ListComp)tree;
             recurseSetContext(lc.getInternalElt(), context);
         } else if (tree instanceof SetComp) {
-            SetComp lc = (SetComp)tree;
-            recurseSetContext(lc.getInternalElt(), context);
-        } else if (!(tree instanceof ListComp) && (!(tree instanceof SetComp))) {
+            SetComp sc = (SetComp)tree;
+            recurseSetContext(sc.getInternalElt(), context);
+        } else if (tree instanceof DictComp) {
+            DictComp dc = (DictComp)tree;
+            recurseSetContext(dc.getInternalKey(), context);
+            recurseSetContext(dc.getInternalValue(), context);
+        } else if (!(tree instanceof ListComp) &&
+                  (!(tree instanceof DictComp)) &&
+                  (!(tree instanceof SetComp))) {
             for (int i=0; i<tree.getChildCount(); i++) {
                 recurseSetContext(tree.getChild(i), context);
             }
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
@@ -26,6 +26,7 @@
 import org.python.antlr.ast.Continue;
 import org.python.antlr.ast.Delete;
 import org.python.antlr.ast.Dict;
+import org.python.antlr.ast.DictComp;
 import org.python.antlr.ast.Ellipsis;
 import org.python.antlr.ast.ExceptHandler;
 import org.python.antlr.ast.Exec;
@@ -2136,7 +2137,10 @@
         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);
+        java.util.List<expr> args = new ArrayList<expr>();
+        args.add(node.getInternalElt());
+
+        finishComp(node, args, node.getInternalGenerators(), tmp_append);
 
         return null;
     }
@@ -2156,20 +2160,44 @@
         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);
+        java.util.List<expr> args = new ArrayList<expr>();
+        args.add(node.getInternalElt());
+
+        finishComp(node, args, node.getInternalGenerators(), tmp_append);
 
         return null;
     }
 
-    private void finishComp(expr node, expr elt, java.util.List<comprehension> generators,
+    @Override
+    public Object visitDictComp(DictComp node) throws Exception {
+        code.new_(p(PyDictionary.class));
+
+        code.dup();
+        code.invokespecial(p(PyDictionary.class), "<init>", sig(Void.TYPE));
+
+        code.dup();
+
+        code.ldc("__setitem__");
+
+        code.invokevirtual(p(PyDictionary.class), "__getattr__", sig(PyObject.class, String.class));
+        String tmp_append = "_{" + node.getLine() + "_" + node.getCharPositionInLine() + "}";
+
+        java.util.List<expr> args = new ArrayList<expr>();
+        args.add(node.getInternalKey());
+        args.add(node.getInternalValue());
+
+        finishComp(node, args, node.getInternalGenerators(), tmp_append);
+
+        return null;
+    }
+
+
+    private void finishComp(expr node, java.util.List<expr> args, 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(elt);
         stmt n = new Expr(node, new Call(node, new Name(node, tmp_append, expr_contextType.Load),
-                args,
-                new ArrayList<keyword>(), null, null));
+                args, new ArrayList<keyword>(), null, null));
 
         for (int i = generators.size() - 1; i >= 0; i--) {
             comprehension lc = generators.get(i);
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
@@ -5,6 +5,7 @@
 import org.python.antlr.Visitor;
 import org.python.antlr.PythonTree;
 import org.python.antlr.ast.ClassDef;
+import org.python.antlr.ast.DictComp;
 import org.python.antlr.ast.Exec;
 import org.python.antlr.ast.Expression;
 import org.python.antlr.ast.FunctionDef;
@@ -294,6 +295,15 @@
     }
 
     @Override
+    public Object visitDictComp(DictComp 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