LEFT | RIGHT |
1 /* File automatically generated by Parser/asdl_ct.py. */ | 1 /* File automatically generated by Parser/asdl_ct.py. */ |
2 #include "Python.h" | 2 #include "Python.h" |
3 #include "Python-ast.h" | 3 #include "Python-ast.h" |
4 | 4 |
5 /* Don't create constants with len() greater than this when | 5 /* Don't create constants with len() greater than this when |
6 folding binary operations. */ | 6 folding binary operations. */ |
7 #define MAX_CONST_SIZE 20 | 7 #define MAX_CONST_SIZE 20 |
8 | 8 |
9 #define MOVE_NODE(TO, FROM) (memcpy((TO), (FROM), sizeof(struct _expr))) | 9 #define MOVE_NODE(TO, FROM) (memcpy((TO), (FROM), sizeof(struct _expr))) |
10 | 10 |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 } | 131 } |
132 PyErr_Clear(); | 132 PyErr_Clear(); |
133 } | 133 } |
134 else if (size > MAX_CONST_SIZE) { | 134 else if (size > MAX_CONST_SIZE) { |
135 Py_DECREF(newval); | 135 Py_DECREF(newval); |
136 return 1; | 136 return 1; |
137 } | 137 } |
138 return make_lit(node, newval, arena); | 138 return make_lit(node, newval, arena); |
139 } | 139 } |
140 | 140 |
141 static PyObject *make_const_tuple(asdl_seq *elts, int make_set) | 141 static int is_lit_seq(asdl_seq *elts) |
142 { | 142 { |
143 PyObject *newval; | |
144 int i; | 143 int i; |
145 | |
146 for (i = 0; i < asdl_seq_LEN(elts); i++) { | 144 for (i = 0; i < asdl_seq_LEN(elts); i++) { |
147 expr_ty e = (expr_ty)asdl_seq_GET(elts, i); | 145 expr_ty e = (expr_ty)asdl_seq_GET(elts, i); |
148 if (e->kind != Lit_kind) | 146 if (e->kind != Lit_kind) |
149 return NULL; | 147 return 0; |
150 } | 148 } |
| 149 return 1; |
| 150 } |
| 151 |
| 152 static PyObject *make_const_tuple(asdl_seq *elts, int make_set) |
| 153 { |
| 154 PyObject *newval; |
| 155 int i; |
| 156 |
| 157 if (!is_lit_seq(elts)) |
| 158 return NULL; |
151 | 159 |
152 newval = PyTuple_New(asdl_seq_LEN(elts)); | 160 newval = PyTuple_New(asdl_seq_LEN(elts)); |
153 if (newval == NULL) | 161 if (newval == NULL) |
154 return NULL; | 162 return NULL; |
155 | 163 |
156 for (i = 0; i < asdl_seq_LEN(elts); i++) { | 164 for (i = 0; i < asdl_seq_LEN(elts); i++) { |
157 expr_ty e = (expr_ty)asdl_seq_GET(elts, i); | 165 expr_ty e = (expr_ty)asdl_seq_GET(elts, i); |
158 Py_INCREF(e->v.Lit.v); | 166 Py_INCREF(e->v.Lit.v); |
159 PyTuple_SET_ITEM(newval, i, e->v.Lit.v); | 167 PyTuple_SET_ITEM(newval, i, e->v.Lit.v); |
160 } | 168 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 ops = node->v.Compare.ops; | 219 ops = node->v.Compare.ops; |
212 args = node->v.Compare.comparators; | 220 args = node->v.Compare.comparators; |
213 /* TODO: optimize cases with literal arguments. */ | 221 /* TODO: optimize cases with literal arguments. */ |
214 for (i = 0; i < asdl_seq_LEN(ops); i++) { | 222 for (i = 0; i < asdl_seq_LEN(ops); i++) { |
215 int op; | 223 int op; |
216 expr_ty arg; | 224 expr_ty arg; |
217 asdl_seq *elts; | 225 asdl_seq *elts; |
218 | 226 |
219 op = asdl_seq_GET(ops, i); | 227 op = asdl_seq_GET(ops, i); |
220 arg = (expr_ty)asdl_seq_GET(args, i); | 228 arg = (expr_ty)asdl_seq_GET(args, i); |
221 /* Change literal list or set in 'in' or 'not in' into | 229 /* Change literal list or set/dict in 'in' or 'not in' into |
222 tuple or frozenset respectively. */ | 230 tuple or frozenset respectively. */ |
223 /* TODO: do the same when list or set is used as iterable | 231 /* TODO: do the same when list or set is used as iterable |
224 in for loop and comprehensions? */ | 232 in for loop and comprehensions? */ |
225 if (op != In && op != NotIn) | 233 if (op != In && op != NotIn) |
226 continue; | 234 continue; |
227 if (arg->kind == List_kind) | 235 if (arg->kind == List_kind) |
228 elts = arg->v.List.elts; | 236 elts = arg->v.List.elts; |
229 else if (arg->kind == Set_kind) | 237 else if (arg->kind == Set_kind) |
230 elts = arg->v.Set.elts; | 238 elts = arg->v.Set.elts; |
| 239 else if (arg->kind == Dict_kind) { |
| 240 /* Do not discard values if they can have side effects. */ |
| 241 if (!is_lit_seq(arg->v.Dict.values)) |
| 242 continue; |
| 243 elts = arg->v.Dict.keys; |
| 244 } |
231 else continue; | 245 else continue; |
232 | 246 |
233 newval = make_const_tuple(elts, arg->kind == Set_kind); | 247 newval = make_const_tuple(elts, arg->kind != List_kind); |
234 make_lit(arg, newval, arena); | 248 make_lit(arg, newval, arena); |
235 } | 249 } |
236 return 1; | 250 return 1; |
237 } | 251 } |
| 252 |
| 253 /* TODO: optimize BoolOp */ |
238 | 254 |
239 static int astfold_slice(slice_ty node_, PyArena* ctx_); | 255 static int astfold_slice(slice_ty node_, PyArena* ctx_); |
240 static int astfold_keyword(keyword_ty node_, PyArena* ctx_); | 256 static int astfold_keyword(keyword_ty node_, PyArena* ctx_); |
241 static int astfold_expr(expr_ty node_, PyArena* ctx_); | 257 static int astfold_expr(expr_ty node_, PyArena* ctx_); |
242 static int astfold_stmt(stmt_ty node_, PyArena* ctx_); | 258 static int astfold_stmt(stmt_ty node_, PyArena* ctx_); |
243 static int astfold_excepthandler(excepthandler_ty node_, PyArena* ctx_); | 259 static int astfold_excepthandler(excepthandler_ty node_, PyArena* ctx_); |
244 static int astfold_comprehension(comprehension_ty node_, PyArena* ctx_); | 260 static int astfold_comprehension(comprehension_ty node_, PyArena* ctx_); |
245 static int astfold_arg(arg_ty node_, PyArena* ctx_); | 261 static int astfold_arg(arg_ty node_, PyArena* ctx_); |
246 static int astfold_mod(mod_ty node_, PyArena* ctx_); | 262 static int astfold_mod(mod_ty node_, PyArena* ctx_); |
247 static int astfold_arguments(arguments_ty node_, PyArena* ctx_); | 263 static int astfold_arguments(arguments_ty node_, PyArena* ctx_); |
| 264 |
248 #define CALL(FUNC, TYPE, ARG) \ | 265 #define CALL(FUNC, TYPE, ARG) \ |
249 if (!FUNC((ARG), ctx_)) \ | 266 if (!FUNC((ARG), ctx_)) \ |
250 return 0; | 267 return 0; |
251 | 268 |
252 #define CALL_OPT(FUNC, TYPE, ARG) \ | 269 #define CALL_OPT(FUNC, TYPE, ARG) \ |
253 if ((ARG) != NULL && !FUNC((ARG), ctx_)) \ | 270 if ((ARG) != NULL && !FUNC((ARG), ctx_)) \ |
254 return 0; | 271 return 0; |
255 | 272 |
256 #define CALL_SEQ(FUNC, TYPE, ARG) { \ | 273 #define CALL_SEQ(FUNC, TYPE, ARG) { \ |
257 int i; \ | 274 int i; \ |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 | 535 |
519 #undef CALL | 536 #undef CALL |
520 #undef CALL_OPT | 537 #undef CALL_OPT |
521 #undef CALL_SEQ | 538 #undef CALL_SEQ |
522 | 539 |
523 int _PyAST_Optimize(mod_ty mod, PyArena *arena) | 540 int _PyAST_Optimize(mod_ty mod, PyArena *arena) |
524 { | 541 { |
525 return astfold_mod(mod, arena); | 542 return astfold_mod(mod, arena); |
526 } | 543 } |
527 | 544 |
LEFT | RIGHT |