mirror of
https://github.com/python/cpython.git
synced 2025-09-27 02:39:58 +00:00
SF patch 1547796 by Georg Brandl -- set literals.
This commit is contained in:
parent
ecfd0b2f3b
commit
86e58e239e
22 changed files with 229 additions and 72 deletions
|
@ -501,6 +501,10 @@ the resulting tuple onto the stack.
|
||||||
Works as \code{BUILD_TUPLE}, but creates a list.
|
Works as \code{BUILD_TUPLE}, but creates a list.
|
||||||
\end{opcodedesc}
|
\end{opcodedesc}
|
||||||
|
|
||||||
|
\begin{opcodedesc}{BUILD_SET}{count}
|
||||||
|
Works as \code{BUILD_TUPLE}, but creates a set.
|
||||||
|
\end{opcodedesc}
|
||||||
|
|
||||||
\begin{opcodedesc}{BUILD_MAP}{zero}
|
\begin{opcodedesc}{BUILD_MAP}{zero}
|
||||||
Pushes a new empty dictionary object onto the stack. The argument is
|
Pushes a new empty dictionary object onto the stack. The argument is
|
||||||
ignored and set to zero by the compiler.
|
ignored and set to zero by the compiler.
|
||||||
|
|
|
@ -101,7 +101,7 @@ factor: ('+'|'-'|'~') factor | power
|
||||||
power: atom trailer* ['**' factor]
|
power: atom trailer* ['**' factor]
|
||||||
atom: ('(' [yield_expr|testlist_gexp] ')' |
|
atom: ('(' [yield_expr|testlist_gexp] ')' |
|
||||||
'[' [listmaker] ']' |
|
'[' [listmaker] ']' |
|
||||||
'{' [dictmaker] '}' |
|
'{' [dictsetmaker] '}' |
|
||||||
NAME | NUMBER | STRING+)
|
NAME | NUMBER | STRING+)
|
||||||
listmaker: test ( list_for | (',' test)* [','] )
|
listmaker: test ( list_for | (',' test)* [','] )
|
||||||
testlist_gexp: test ( gen_for | (',' test)* [','] )
|
testlist_gexp: test ( gen_for | (',' test)* [','] )
|
||||||
|
@ -112,7 +112,7 @@ subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]
|
||||||
sliceop: ':' [test]
|
sliceop: ':' [test]
|
||||||
exprlist: expr (',' expr)* [',']
|
exprlist: expr (',' expr)* [',']
|
||||||
testlist: test (',' test)* [',']
|
testlist: test (',' test)* [',']
|
||||||
dictmaker: test ':' test (',' test ':' test)* [',']
|
dictsetmaker: (test ':' test (',' test ':' test)* [',']) | (test (',' test)* [','])
|
||||||
|
|
||||||
classdef: 'class' NAME ['(' [testlist] ')'] ':' suite
|
classdef: 'class' NAME ['(' [testlist] ')'] ':' suite
|
||||||
|
|
||||||
|
|
|
@ -184,10 +184,10 @@ struct _stmt {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum _expr_kind {BoolOp_kind=1, BinOp_kind=2, UnaryOp_kind=3, Lambda_kind=4,
|
enum _expr_kind {BoolOp_kind=1, BinOp_kind=2, UnaryOp_kind=3, Lambda_kind=4,
|
||||||
IfExp_kind=5, Dict_kind=6, ListComp_kind=7,
|
IfExp_kind=5, Dict_kind=6, Set_kind=7, ListComp_kind=8,
|
||||||
GeneratorExp_kind=8, Yield_kind=9, Compare_kind=10,
|
GeneratorExp_kind=9, Yield_kind=10, Compare_kind=11,
|
||||||
Call_kind=11, Num_kind=12, Str_kind=13, Attribute_kind=14,
|
Call_kind=12, Num_kind=13, Str_kind=14, Attribute_kind=15,
|
||||||
Subscript_kind=15, Name_kind=16, List_kind=17, Tuple_kind=18};
|
Subscript_kind=16, Name_kind=17, List_kind=18, Tuple_kind=19};
|
||||||
struct _expr {
|
struct _expr {
|
||||||
enum _expr_kind kind;
|
enum _expr_kind kind;
|
||||||
union {
|
union {
|
||||||
|
@ -223,6 +223,10 @@ struct _expr {
|
||||||
asdl_seq *values;
|
asdl_seq *values;
|
||||||
} Dict;
|
} Dict;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
asdl_seq *elts;
|
||||||
|
} Set;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
expr_ty elt;
|
expr_ty elt;
|
||||||
asdl_seq *generators;
|
asdl_seq *generators;
|
||||||
|
@ -399,6 +403,7 @@ expr_ty IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int
|
||||||
col_offset, PyArena *arena);
|
col_offset, PyArena *arena);
|
||||||
expr_ty Dict(asdl_seq * keys, asdl_seq * values, int lineno, int col_offset,
|
expr_ty Dict(asdl_seq * keys, asdl_seq * values, int lineno, int col_offset,
|
||||||
PyArena *arena);
|
PyArena *arena);
|
||||||
|
expr_ty Set(asdl_seq * elts, int lineno, int col_offset, PyArena *arena);
|
||||||
expr_ty ListComp(expr_ty elt, asdl_seq * generators, int lineno, int
|
expr_ty ListComp(expr_ty elt, asdl_seq * generators, int lineno, int
|
||||||
col_offset, PyArena *arena);
|
col_offset, PyArena *arena);
|
||||||
expr_ty GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int
|
expr_ty GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int
|
||||||
|
|
|
@ -69,7 +69,7 @@
|
||||||
#define sliceop 324
|
#define sliceop 324
|
||||||
#define exprlist 325
|
#define exprlist 325
|
||||||
#define testlist 326
|
#define testlist 326
|
||||||
#define dictmaker 327
|
#define dictsetmaker 327
|
||||||
#define classdef 328
|
#define classdef 328
|
||||||
#define arglist 329
|
#define arglist 329
|
||||||
#define argument 330
|
#define argument 330
|
||||||
|
|
|
@ -97,11 +97,12 @@ extern "C" {
|
||||||
#define LOAD_NAME 101 /* Index in name list */
|
#define LOAD_NAME 101 /* Index in name list */
|
||||||
#define BUILD_TUPLE 102 /* Number of tuple items */
|
#define BUILD_TUPLE 102 /* Number of tuple items */
|
||||||
#define BUILD_LIST 103 /* Number of list items */
|
#define BUILD_LIST 103 /* Number of list items */
|
||||||
#define BUILD_MAP 104 /* Always zero for now */
|
#define BUILD_SET 104 /* Number of set items */
|
||||||
#define LOAD_ATTR 105 /* Index in name list */
|
#define BUILD_MAP 105 /* Always zero for now */
|
||||||
#define COMPARE_OP 106 /* Comparison operator */
|
#define LOAD_ATTR 106 /* Index in name list */
|
||||||
#define IMPORT_NAME 107 /* Index in name list */
|
#define COMPARE_OP 107 /* Comparison operator */
|
||||||
#define IMPORT_FROM 108 /* Index in name list */
|
#define IMPORT_NAME 108 /* Index in name list */
|
||||||
|
#define IMPORT_FROM 109 /* Index in name list */
|
||||||
|
|
||||||
#define JUMP_FORWARD 110 /* Number of bytes to skip */
|
#define JUMP_FORWARD 110 /* Number of bytes to skip */
|
||||||
#define JUMP_IF_FALSE 111 /* "" */
|
#define JUMP_IF_FALSE 111 /* "" */
|
||||||
|
|
|
@ -542,7 +542,6 @@ class Function(Node):
|
||||||
self.kwargs = 1
|
self.kwargs = 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def getChildren(self):
|
def getChildren(self):
|
||||||
children = []
|
children = []
|
||||||
children.append(self.decorators)
|
children.append(self.decorators)
|
||||||
|
@ -572,6 +571,7 @@ class GenExpr(Node):
|
||||||
self.argnames = ['.0']
|
self.argnames = ['.0']
|
||||||
self.varargs = self.kwargs = None
|
self.varargs = self.kwargs = None
|
||||||
|
|
||||||
|
|
||||||
def getChildren(self):
|
def getChildren(self):
|
||||||
return self.code,
|
return self.code,
|
||||||
|
|
||||||
|
@ -589,7 +589,6 @@ class GenExprFor(Node):
|
||||||
self.lineno = lineno
|
self.lineno = lineno
|
||||||
self.is_outmost = False
|
self.is_outmost = False
|
||||||
|
|
||||||
|
|
||||||
def getChildren(self):
|
def getChildren(self):
|
||||||
children = []
|
children = []
|
||||||
children.append(self.assign)
|
children.append(self.assign)
|
||||||
|
@ -766,7 +765,6 @@ class Lambda(Node):
|
||||||
self.kwargs = 1
|
self.kwargs = 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def getChildren(self):
|
def getChildren(self):
|
||||||
children = []
|
children = []
|
||||||
children.append(self.argnames)
|
children.append(self.argnames)
|
||||||
|
@ -1091,6 +1089,22 @@ class RightShift(Node):
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "RightShift((%s, %s))" % (repr(self.left), repr(self.right))
|
return "RightShift((%s, %s))" % (repr(self.left), repr(self.right))
|
||||||
|
|
||||||
|
class Set(Node):
|
||||||
|
def __init__(self, items, lineno=None):
|
||||||
|
self.items = items
|
||||||
|
self.lineno = lineno
|
||||||
|
|
||||||
|
def getChildren(self):
|
||||||
|
return tuple(flatten(self.items))
|
||||||
|
|
||||||
|
def getChildNodes(self):
|
||||||
|
nodelist = []
|
||||||
|
nodelist.extend(flatten_nodes(self.items))
|
||||||
|
return tuple(nodelist)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "Set(%s)" % (repr(self.items),)
|
||||||
|
|
||||||
class Slice(Node):
|
class Slice(Node):
|
||||||
def __init__(self, expr, flags, lower, upper, lineno=None):
|
def __init__(self, expr, flags, lower, upper, lineno=None):
|
||||||
self.expr = expr
|
self.expr = expr
|
||||||
|
|
|
@ -793,6 +793,8 @@ class StackDepthTracker:
|
||||||
return -count+1
|
return -count+1
|
||||||
def BUILD_LIST(self, count):
|
def BUILD_LIST(self, count):
|
||||||
return -count+1
|
return -count+1
|
||||||
|
def BUILD_SET(self, count):
|
||||||
|
return -count+1
|
||||||
def CALL_FUNCTION(self, argc):
|
def CALL_FUNCTION(self, argc):
|
||||||
hi, lo = divmod(argc, 256)
|
hi, lo = divmod(argc, 256)
|
||||||
return -(lo + hi * 2)
|
return -(lo + hi * 2)
|
||||||
|
|
|
@ -1241,6 +1241,12 @@ class CodeGenerator:
|
||||||
self.visit(elt)
|
self.visit(elt)
|
||||||
self.emit('BUILD_LIST', len(node.nodes))
|
self.emit('BUILD_LIST', len(node.nodes))
|
||||||
|
|
||||||
|
def visitSet(self, node):
|
||||||
|
self.set_lineno(node)
|
||||||
|
for elt in node.items:
|
||||||
|
self.visit(elt)
|
||||||
|
self.emit('BUILD_SET', len(node.items))
|
||||||
|
|
||||||
def visitSliceobj(self, node):
|
def visitSliceobj(self, node):
|
||||||
for child in node.nodes:
|
for child in node.nodes:
|
||||||
self.visit(child)
|
self.visit(child)
|
||||||
|
|
|
@ -738,7 +738,7 @@ class Transformer:
|
||||||
def atom_lbrace(self, nodelist):
|
def atom_lbrace(self, nodelist):
|
||||||
if nodelist[1][0] == token.RBRACE:
|
if nodelist[1][0] == token.RBRACE:
|
||||||
return Dict((), lineno=nodelist[0][2])
|
return Dict((), lineno=nodelist[0][2])
|
||||||
return self.com_dictmaker(nodelist[1])
|
return self.com_dictsetmaker(nodelist[1])
|
||||||
|
|
||||||
def atom_backquote(self, nodelist):
|
def atom_backquote(self, nodelist):
|
||||||
return Backquote(self.com_node(nodelist[1]))
|
return Backquote(self.com_node(nodelist[1]))
|
||||||
|
@ -1182,9 +1182,16 @@ class Transformer:
|
||||||
assert node[0] == symbol.gen_iter
|
assert node[0] == symbol.gen_iter
|
||||||
return node[1]
|
return node[1]
|
||||||
|
|
||||||
def com_dictmaker(self, nodelist):
|
def com_dictsetmaker(self, nodelist):
|
||||||
# dictmaker: test ':' test (',' test ':' value)* [',']
|
# dictsetmaker: (test ':' test (',' test ':' value)* [',']) | (test (',' test)* [','])
|
||||||
items = []
|
items = []
|
||||||
|
if nodelist[2] != ':':
|
||||||
|
# it's a set
|
||||||
|
for i in range(1, len(nodelist), 2):
|
||||||
|
items.append(self.com_node(nodelist[i]))
|
||||||
|
return Set(items, lineno=items[0].lineno)
|
||||||
|
else:
|
||||||
|
# it's a dict
|
||||||
for i in range(1, len(nodelist), 4):
|
for i in range(1, len(nodelist), 4):
|
||||||
items.append((self.com_node(nodelist[i]),
|
items.append((self.com_node(nodelist[i]),
|
||||||
self.com_node(nodelist[i+2])))
|
self.com_node(nodelist[i+2])))
|
||||||
|
|
|
@ -137,12 +137,13 @@ hasconst.append(100)
|
||||||
name_op('LOAD_NAME', 101) # Index in name list
|
name_op('LOAD_NAME', 101) # Index in name list
|
||||||
def_op('BUILD_TUPLE', 102) # Number of tuple items
|
def_op('BUILD_TUPLE', 102) # Number of tuple items
|
||||||
def_op('BUILD_LIST', 103) # Number of list items
|
def_op('BUILD_LIST', 103) # Number of list items
|
||||||
def_op('BUILD_MAP', 104) # Always zero for now
|
def_op('BUILD_SET', 104) # Number of set items
|
||||||
name_op('LOAD_ATTR', 105) # Index in name list
|
def_op('BUILD_MAP', 105) # Always zero for now
|
||||||
def_op('COMPARE_OP', 106) # Comparison operator
|
name_op('LOAD_ATTR', 106) # Index in name list
|
||||||
hascompare.append(106)
|
def_op('COMPARE_OP', 107) # Comparison operator
|
||||||
name_op('IMPORT_NAME', 107) # Index in name list
|
hascompare.append(107)
|
||||||
name_op('IMPORT_FROM', 108) # Index in name list
|
name_op('IMPORT_NAME', 108) # Index in name list
|
||||||
|
name_op('IMPORT_FROM', 109) # Index in name list
|
||||||
|
|
||||||
jrel_op('JUMP_FORWARD', 110) # Number of bytes to skip
|
jrel_op('JUMP_FORWARD', 110) # Number of bytes to skip
|
||||||
jrel_op('JUMP_IF_FALSE', 111) # ""
|
jrel_op('JUMP_IF_FALSE', 111) # ""
|
||||||
|
|
|
@ -685,8 +685,8 @@ print L
|
||||||
|
|
||||||
|
|
||||||
print 'atoms'
|
print 'atoms'
|
||||||
### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictmaker] '}' | NAME | NUMBER | STRING
|
### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictsetmaker] '}' | NAME | NUMBER | STRING
|
||||||
### dictmaker: test ':' test (',' test ':' test)* [',']
|
### dictsetmaker: (test ':' test (',' test ':' test)* [',']) | (test (',' test)* [','])
|
||||||
|
|
||||||
x = (1)
|
x = (1)
|
||||||
x = (1 or 2 or 3)
|
x = (1 or 2 or 3)
|
||||||
|
@ -706,6 +706,11 @@ x = {'one': 1, 'two': 2}
|
||||||
x = {'one': 1, 'two': 2,}
|
x = {'one': 1, 'two': 2,}
|
||||||
x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6}
|
x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6}
|
||||||
|
|
||||||
|
x = {'one'}
|
||||||
|
x = {'one', 1,}
|
||||||
|
x = {'one', 'two', 'three'}
|
||||||
|
x = {2, 3, 4,}
|
||||||
|
|
||||||
x = x
|
x = x
|
||||||
x = 'x'
|
x = 'x'
|
||||||
x = 123
|
x = 123
|
||||||
|
|
|
@ -261,6 +261,11 @@ class TestSet(TestJointOps):
|
||||||
t = self.thetype(s)
|
t = self.thetype(s)
|
||||||
self.assertNotEqual(id(s), id(t))
|
self.assertNotEqual(id(s), id(t))
|
||||||
|
|
||||||
|
def test_set_literal(self):
|
||||||
|
s = set([1,2,3])
|
||||||
|
t = {1,2,3}
|
||||||
|
self.assertEqual(s, t)
|
||||||
|
|
||||||
def test_hash(self):
|
def test_hash(self):
|
||||||
self.assertRaises(TypeError, hash, self.s)
|
self.assertRaises(TypeError, hash, self.s)
|
||||||
|
|
||||||
|
@ -626,7 +631,7 @@ class TestBasicOpsEmpty(TestBasicOps):
|
||||||
self.set = set(self.values)
|
self.set = set(self.values)
|
||||||
self.dup = set(self.values)
|
self.dup = set(self.values)
|
||||||
self.length = 0
|
self.length = 0
|
||||||
self.repr = "set([])"
|
self.repr = "{}"
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -637,7 +642,7 @@ class TestBasicOpsSingleton(TestBasicOps):
|
||||||
self.set = set(self.values)
|
self.set = set(self.values)
|
||||||
self.dup = set(self.values)
|
self.dup = set(self.values)
|
||||||
self.length = 1
|
self.length = 1
|
||||||
self.repr = "set([3])"
|
self.repr = "{3}"
|
||||||
|
|
||||||
def test_in(self):
|
def test_in(self):
|
||||||
self.failUnless(3 in self.set)
|
self.failUnless(3 in self.set)
|
||||||
|
@ -654,7 +659,7 @@ class TestBasicOpsTuple(TestBasicOps):
|
||||||
self.set = set(self.values)
|
self.set = set(self.values)
|
||||||
self.dup = set(self.values)
|
self.dup = set(self.values)
|
||||||
self.length = 1
|
self.length = 1
|
||||||
self.repr = "set([(0, 'zero')])"
|
self.repr = "{(0, 'zero')}"
|
||||||
|
|
||||||
def test_in(self):
|
def test_in(self):
|
||||||
self.failUnless((0, "zero") in self.set)
|
self.failUnless((0, "zero") in self.set)
|
||||||
|
|
|
@ -530,6 +530,9 @@ set_tp_print(PySetObject *so, FILE *fp, int flags)
|
||||||
char *emit = ""; /* No separator emitted on first pass */
|
char *emit = ""; /* No separator emitted on first pass */
|
||||||
char *separator = ", ";
|
char *separator = ", ";
|
||||||
|
|
||||||
|
if (so->ob_type == &PySet_Type)
|
||||||
|
fprintf(fp, "{");
|
||||||
|
else
|
||||||
fprintf(fp, "%s([", so->ob_type->tp_name);
|
fprintf(fp, "%s([", so->ob_type->tp_name);
|
||||||
while (set_next(so, &pos, &entry)) {
|
while (set_next(so, &pos, &entry)) {
|
||||||
fputs(emit, fp);
|
fputs(emit, fp);
|
||||||
|
@ -537,6 +540,9 @@ set_tp_print(PySetObject *so, FILE *fp, int flags)
|
||||||
if (PyObject_Print(entry->key, fp, 0) != 0)
|
if (PyObject_Print(entry->key, fp, 0) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (so->ob_type == &PySet_Type)
|
||||||
|
fputs("}", fp);
|
||||||
|
else
|
||||||
fputs("])", fp);
|
fputs("])", fp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -554,8 +560,15 @@ set_repr(PySetObject *so)
|
||||||
if (listrepr == NULL)
|
if (listrepr == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (so->ob_type == &PySet_Type) {
|
||||||
|
char *s = PyString_AS_STRING(listrepr);
|
||||||
|
s += 1;
|
||||||
|
s[strlen(s)-1] = 0;
|
||||||
|
result = PyString_FromFormat("{%s}", s);
|
||||||
|
} else {
|
||||||
result = PyString_FromFormat("%s(%s)", so->ob_type->tp_name,
|
result = PyString_FromFormat("%s(%s)", so->ob_type->tp_name,
|
||||||
PyString_AS_STRING(listrepr));
|
PyString_AS_STRING(listrepr));
|
||||||
|
}
|
||||||
Py_DECREF(listrepr);
|
Py_DECREF(listrepr);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@ module Python version "$Revision$"
|
||||||
| Lambda(arguments args, expr body)
|
| Lambda(arguments args, expr body)
|
||||||
| IfExp(expr test, expr body, expr orelse)
|
| IfExp(expr test, expr body, expr orelse)
|
||||||
| Dict(expr* keys, expr* values)
|
| Dict(expr* keys, expr* values)
|
||||||
|
| Set(expr* elts)
|
||||||
| ListComp(expr elt, comprehension* generators)
|
| ListComp(expr elt, comprehension* generators)
|
||||||
| GeneratorExp(expr elt, comprehension* generators)
|
| GeneratorExp(expr elt, comprehension* generators)
|
||||||
-- the grammar constrains where yield expressions can occur
|
-- the grammar constrains where yield expressions can occur
|
||||||
|
|
|
@ -178,6 +178,10 @@ static char *Dict_fields[]={
|
||||||
"keys",
|
"keys",
|
||||||
"values",
|
"values",
|
||||||
};
|
};
|
||||||
|
static PyTypeObject *Set_type;
|
||||||
|
static char *Set_fields[]={
|
||||||
|
"elts",
|
||||||
|
};
|
||||||
static PyTypeObject *ListComp_type;
|
static PyTypeObject *ListComp_type;
|
||||||
static char *ListComp_fields[]={
|
static char *ListComp_fields[]={
|
||||||
"elt",
|
"elt",
|
||||||
|
@ -517,6 +521,8 @@ static int init_types(void)
|
||||||
if (!IfExp_type) return 0;
|
if (!IfExp_type) return 0;
|
||||||
Dict_type = make_type("Dict", expr_type, Dict_fields, 2);
|
Dict_type = make_type("Dict", expr_type, Dict_fields, 2);
|
||||||
if (!Dict_type) return 0;
|
if (!Dict_type) return 0;
|
||||||
|
Set_type = make_type("Set", expr_type, Set_fields, 1);
|
||||||
|
if (!Set_type) return 0;
|
||||||
ListComp_type = make_type("ListComp", expr_type, ListComp_fields, 2);
|
ListComp_type = make_type("ListComp", expr_type, ListComp_fields, 2);
|
||||||
if (!ListComp_type) return 0;
|
if (!ListComp_type) return 0;
|
||||||
GeneratorExp_type = make_type("GeneratorExp", expr_type,
|
GeneratorExp_type = make_type("GeneratorExp", expr_type,
|
||||||
|
@ -1434,6 +1440,22 @@ Dict(asdl_seq * keys, asdl_seq * values, int lineno, int col_offset, PyArena
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expr_ty
|
||||||
|
Set(asdl_seq * elts, int lineno, int col_offset, PyArena *arena)
|
||||||
|
{
|
||||||
|
expr_ty p;
|
||||||
|
p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
|
||||||
|
if (!p) {
|
||||||
|
PyErr_NoMemory();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
p->kind = Set_kind;
|
||||||
|
p->v.Set.elts = elts;
|
||||||
|
p->lineno = lineno;
|
||||||
|
p->col_offset = col_offset;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
expr_ty
|
expr_ty
|
||||||
ListComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset,
|
ListComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset,
|
||||||
PyArena *arena)
|
PyArena *arena)
|
||||||
|
@ -2424,6 +2446,15 @@ ast2obj_expr(void* _o)
|
||||||
goto failed;
|
goto failed;
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
break;
|
break;
|
||||||
|
case Set_kind:
|
||||||
|
result = PyType_GenericNew(Set_type, NULL, NULL);
|
||||||
|
if (!result) goto failed;
|
||||||
|
value = ast2obj_list(o->v.Set.elts, ast2obj_expr);
|
||||||
|
if (!value) goto failed;
|
||||||
|
if (PyObject_SetAttrString(result, "elts", value) == -1)
|
||||||
|
goto failed;
|
||||||
|
Py_DECREF(value);
|
||||||
|
break;
|
||||||
case ListComp_kind:
|
case ListComp_kind:
|
||||||
result = PyType_GenericNew(ListComp_type, NULL, NULL);
|
result = PyType_GenericNew(ListComp_type, NULL, NULL);
|
||||||
if (!result) goto failed;
|
if (!result) goto failed;
|
||||||
|
@ -3069,6 +3100,7 @@ init_ast(void)
|
||||||
return;
|
return;
|
||||||
if (PyDict_SetItemString(d, "IfExp", (PyObject*)IfExp_type) < 0) return;
|
if (PyDict_SetItemString(d, "IfExp", (PyObject*)IfExp_type) < 0) return;
|
||||||
if (PyDict_SetItemString(d, "Dict", (PyObject*)Dict_type) < 0) return;
|
if (PyDict_SetItemString(d, "Dict", (PyObject*)Dict_type) < 0) return;
|
||||||
|
if (PyDict_SetItemString(d, "Set", (PyObject*)Set_type) < 0) return;
|
||||||
if (PyDict_SetItemString(d, "ListComp", (PyObject*)ListComp_type) < 0)
|
if (PyDict_SetItemString(d, "ListComp", (PyObject*)ListComp_type) < 0)
|
||||||
return;
|
return;
|
||||||
if (PyDict_SetItemString(d, "GeneratorExp",
|
if (PyDict_SetItemString(d, "GeneratorExp",
|
||||||
|
|
24
Python/ast.c
24
Python/ast.c
|
@ -394,6 +394,7 @@ set_context(expr_ty e, expr_context_ty ctx, const node *n)
|
||||||
expr_name = "list comprehension";
|
expr_name = "list comprehension";
|
||||||
break;
|
break;
|
||||||
case Dict_kind:
|
case Dict_kind:
|
||||||
|
case Set_kind:
|
||||||
case Num_kind:
|
case Num_kind:
|
||||||
case Str_kind:
|
case Str_kind:
|
||||||
expr_name = "literal";
|
expr_name = "literal";
|
||||||
|
@ -1187,7 +1188,7 @@ static expr_ty
|
||||||
ast_for_atom(struct compiling *c, const node *n)
|
ast_for_atom(struct compiling *c, const node *n)
|
||||||
{
|
{
|
||||||
/* atom: '(' [yield_expr|testlist_gexp] ')' | '[' [listmaker] ']'
|
/* atom: '(' [yield_expr|testlist_gexp] ')' | '[' [listmaker] ']'
|
||||||
| '{' [dictmaker] '}' | NAME | NUMBER | STRING+
|
| '{' [dictsetmaker] '}' | NAME | NUMBER | STRING+
|
||||||
*/
|
*/
|
||||||
node *ch = CHILD(n, 0);
|
node *ch = CHILD(n, 0);
|
||||||
|
|
||||||
|
@ -1242,11 +1243,29 @@ ast_for_atom(struct compiling *c, const node *n)
|
||||||
else
|
else
|
||||||
return ast_for_listcomp(c, ch);
|
return ast_for_listcomp(c, ch);
|
||||||
case LBRACE: {
|
case LBRACE: {
|
||||||
/* dictmaker: test ':' test (',' test ':' test)* [','] */
|
/* dictsetmaker: test ':' test (',' test ':' test)* [','] |
|
||||||
|
* test (',' test)* [','] */
|
||||||
int i, size;
|
int i, size;
|
||||||
asdl_seq *keys, *values;
|
asdl_seq *keys, *values;
|
||||||
|
|
||||||
ch = CHILD(n, 1);
|
ch = CHILD(n, 1);
|
||||||
|
if (NCH(ch) == 1 || (NCH(ch) > 0 && STR(CHILD(ch, 1))[0] == ',')) {
|
||||||
|
/* it's a set */
|
||||||
|
size = (NCH(ch) + 1) / 2; /* +1 in case no trailing comma */
|
||||||
|
keys = asdl_seq_new(size, c->c_arena);
|
||||||
|
if (!keys)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < NCH(ch); i += 2) {
|
||||||
|
expr_ty expression;
|
||||||
|
expression = ast_for_expr(c, CHILD(ch, i));
|
||||||
|
if (!expression)
|
||||||
|
return NULL;
|
||||||
|
asdl_seq_SET(keys, i / 2, expression);
|
||||||
|
}
|
||||||
|
return Set(keys, LINENO(n), n->n_col_offset, c->c_arena);
|
||||||
|
} else {
|
||||||
|
/* it's a dict */
|
||||||
size = (NCH(ch) + 1) / 4; /* +1 in case no trailing comma */
|
size = (NCH(ch) + 1) / 4; /* +1 in case no trailing comma */
|
||||||
keys = asdl_seq_new(size, c->c_arena);
|
keys = asdl_seq_new(size, c->c_arena);
|
||||||
if (!keys)
|
if (!keys)
|
||||||
|
@ -1273,6 +1292,7 @@ ast_for_atom(struct compiling *c, const node *n)
|
||||||
}
|
}
|
||||||
return Dict(keys, values, LINENO(n), n->n_col_offset, c->c_arena);
|
return Dict(keys, values, LINENO(n), n->n_col_offset, c->c_arena);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
PyErr_Format(PyExc_SystemError, "unhandled atom %d", TYPE(ch));
|
PyErr_Format(PyExc_SystemError, "unhandled atom %d", TYPE(ch));
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -1945,6 +1945,24 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BUILD_SET:
|
||||||
|
x = PySet_New(NULL);
|
||||||
|
if (x != NULL) {
|
||||||
|
for (; --oparg >= 0;) {
|
||||||
|
w = POP();
|
||||||
|
if (err == 0)
|
||||||
|
err = PySet_Add(x, w);
|
||||||
|
Py_DECREF(w);
|
||||||
|
}
|
||||||
|
if (err != 0) {
|
||||||
|
Py_DECREF(x);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
PUSH(x);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case BUILD_MAP:
|
case BUILD_MAP:
|
||||||
x = PyDict_New();
|
x = PyDict_New();
|
||||||
PUSH(x);
|
PUSH(x);
|
||||||
|
|
|
@ -851,6 +851,7 @@ opcode_stack_effect(int opcode, int oparg)
|
||||||
return 1;
|
return 1;
|
||||||
case BUILD_TUPLE:
|
case BUILD_TUPLE:
|
||||||
case BUILD_LIST:
|
case BUILD_LIST:
|
||||||
|
case BUILD_SET:
|
||||||
return 1-oparg;
|
return 1-oparg;
|
||||||
case BUILD_MAP:
|
case BUILD_MAP:
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -2955,6 +2956,11 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
|
||||||
ADDOP(c, STORE_SUBSCR);
|
ADDOP(c, STORE_SUBSCR);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case Set_kind:
|
||||||
|
n = asdl_seq_LEN(e->v.Set.elts);
|
||||||
|
VISIT_SEQ(c, expr, e->v.Set.elts);
|
||||||
|
ADDOP_I(c, BUILD_SET, n);
|
||||||
|
break;
|
||||||
case ListComp_kind:
|
case ListComp_kind:
|
||||||
return compiler_listcomp(c, e);
|
return compiler_listcomp(c, e);
|
||||||
case GeneratorExp_kind:
|
case GeneratorExp_kind:
|
||||||
|
|
|
@ -1500,26 +1500,42 @@ static state states_70[3] = {
|
||||||
static arc arcs_71_0[1] = {
|
static arc arcs_71_0[1] = {
|
||||||
{26, 1},
|
{26, 1},
|
||||||
};
|
};
|
||||||
static arc arcs_71_1[1] = {
|
static arc arcs_71_1[3] = {
|
||||||
{21, 2},
|
{21, 2},
|
||||||
|
{27, 3},
|
||||||
|
{0, 1},
|
||||||
};
|
};
|
||||||
static arc arcs_71_2[1] = {
|
static arc arcs_71_2[1] = {
|
||||||
{26, 3},
|
{26, 4},
|
||||||
};
|
};
|
||||||
static arc arcs_71_3[2] = {
|
static arc arcs_71_3[2] = {
|
||||||
{27, 4},
|
{26, 5},
|
||||||
{0, 3},
|
{0, 3},
|
||||||
};
|
};
|
||||||
static arc arcs_71_4[2] = {
|
static arc arcs_71_4[2] = {
|
||||||
{26, 1},
|
{27, 6},
|
||||||
{0, 4},
|
{0, 4},
|
||||||
};
|
};
|
||||||
static state states_71[5] = {
|
static arc arcs_71_5[2] = {
|
||||||
|
{27, 3},
|
||||||
|
{0, 5},
|
||||||
|
};
|
||||||
|
static arc arcs_71_6[2] = {
|
||||||
|
{26, 7},
|
||||||
|
{0, 6},
|
||||||
|
};
|
||||||
|
static arc arcs_71_7[1] = {
|
||||||
|
{21, 2},
|
||||||
|
};
|
||||||
|
static state states_71[8] = {
|
||||||
{1, arcs_71_0},
|
{1, arcs_71_0},
|
||||||
{1, arcs_71_1},
|
{3, arcs_71_1},
|
||||||
{1, arcs_71_2},
|
{1, arcs_71_2},
|
||||||
{2, arcs_71_3},
|
{2, arcs_71_3},
|
||||||
{2, arcs_71_4},
|
{2, arcs_71_4},
|
||||||
|
{2, arcs_71_5},
|
||||||
|
{2, arcs_71_6},
|
||||||
|
{1, arcs_71_7},
|
||||||
};
|
};
|
||||||
static arc arcs_72_0[1] = {
|
static arc arcs_72_0[1] = {
|
||||||
{157, 1},
|
{157, 1},
|
||||||
|
@ -1911,7 +1927,7 @@ static dfa dfas[84] = {
|
||||||
"\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\140\010\311\000\000"},
|
"\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\140\010\311\000\000"},
|
||||||
{326, "testlist", 0, 3, states_70,
|
{326, "testlist", 0, 3, states_70,
|
||||||
"\000\040\010\000\000\000\000\000\000\000\000\000\000\020\004\000\140\010\311\000\000"},
|
"\000\040\010\000\000\000\000\000\000\000\000\000\000\020\004\000\140\010\311\000\000"},
|
||||||
{327, "dictmaker", 0, 5, states_71,
|
{327, "dictsetmaker", 0, 8, states_71,
|
||||||
"\000\040\010\000\000\000\000\000\000\000\000\000\000\020\004\000\140\010\311\000\000"},
|
"\000\040\010\000\000\000\000\000\000\000\000\000\000\020\004\000\140\010\311\000\000"},
|
||||||
{328, "classdef", 0, 8, states_72,
|
{328, "classdef", 0, 8, states_72,
|
||||||
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\040\000"},
|
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\040\000"},
|
||||||
|
|
|
@ -66,9 +66,10 @@ extern time_t PyOS_GetLastModificationTime(char *, FILE *);
|
||||||
storing constants that should have been removed)
|
storing constants that should have been removed)
|
||||||
Python 3000: 3000
|
Python 3000: 3000
|
||||||
3010 (removed UNARY_CONVERT)
|
3010 (removed UNARY_CONVERT)
|
||||||
|
3020 (added BUILD_SET)
|
||||||
.
|
.
|
||||||
*/
|
*/
|
||||||
#define MAGIC (3010 | ((long)'\r'<<16) | ((long)'\n'<<24))
|
#define MAGIC (3020 | ((long)'\r'<<16) | ((long)'\n'<<24))
|
||||||
|
|
||||||
/* Magic word as global; note that _PyImport_Init() can change the
|
/* Magic word as global; note that _PyImport_Init() can change the
|
||||||
value of this global to accommodate for alterations of how the
|
value of this global to accommodate for alterations of how the
|
||||||
|
|
|
@ -50,11 +50,11 @@ GenExprFor: assign, iter, ifs!
|
||||||
GenExprIf: test
|
GenExprIf: test
|
||||||
List: nodes!
|
List: nodes!
|
||||||
Dict: items!
|
Dict: items!
|
||||||
|
Set: items!
|
||||||
Not: expr
|
Not: expr
|
||||||
Compare: expr, ops!
|
Compare: expr, ops!
|
||||||
Name: name*
|
Name: name*
|
||||||
Global: names*
|
Global: names*
|
||||||
Backquote: expr
|
|
||||||
Getattr: expr, attrname*
|
Getattr: expr, attrname*
|
||||||
CallFunc: node, args!, star_args& = None, dstar_args& = None
|
CallFunc: node, args!, star_args& = None, dstar_args& = None
|
||||||
Keyword: name*, expr
|
Keyword: name*, expr
|
||||||
|
@ -97,7 +97,7 @@ init(Lambda):
|
||||||
self.kwargs = 1
|
self.kwargs = 1
|
||||||
|
|
||||||
init(GenExpr):
|
init(GenExpr):
|
||||||
self.argnames = ['[outmost-iterable]']
|
self.argnames = ['.0']
|
||||||
self.varargs = self.kwargs = None
|
self.varargs = self.kwargs = None
|
||||||
|
|
||||||
init(GenExprFor):
|
init(GenExprFor):
|
||||||
|
|
|
@ -235,7 +235,7 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
This file is automatically generated by Tools/compiler/astgen.py
|
This file is automatically generated by Tools/compiler/astgen.py
|
||||||
"""
|
"""
|
||||||
from consts import CO_VARARGS, CO_VARKEYWORDS
|
from compiler.consts import CO_VARARGS, CO_VARKEYWORDS
|
||||||
|
|
||||||
def flatten(seq):
|
def flatten(seq):
|
||||||
l = []
|
l = []
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue