| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1 | /* | 
 | 2 |  * This file includes functions to transform a concrete syntax tree (CST) to | 
| Benjamin Peterson | 832bfe2 | 2011-08-09 16:15:04 -0500 | [diff] [blame] | 3 |  * an abstract syntax tree (AST). The main function is PyAST_FromNode(). | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 4 |  * | 
 | 5 |  */ | 
 | 6 | #include "Python.h" | 
 | 7 | #include "Python-ast.h" | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 8 | #include "node.h" | 
 | 9 | #include "ast.h" | 
 | 10 | #include "token.h" | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 11 |  | 
 | 12 | #include <assert.h> | 
 | 13 |  | 
| Benjamin Peterson | 832bfe2 | 2011-08-09 16:15:04 -0500 | [diff] [blame] | 14 | static int validate_stmts(asdl_seq *); | 
 | 15 | static int validate_exprs(asdl_seq *, expr_context_ty, int); | 
 | 16 | static int validate_nonempty_seq(asdl_seq *, const char *, const char *); | 
 | 17 | static int validate_stmt(stmt_ty); | 
 | 18 | static int validate_expr(expr_ty, expr_context_ty); | 
 | 19 |  | 
 | 20 | static int | 
 | 21 | validate_comprehension(asdl_seq *gens) | 
 | 22 | { | 
 | 23 |     int i; | 
 | 24 |     if (!asdl_seq_LEN(gens)) { | 
 | 25 |         PyErr_SetString(PyExc_ValueError, "comprehension with no generators"); | 
 | 26 |         return 0; | 
 | 27 |     } | 
 | 28 |     for (i = 0; i < asdl_seq_LEN(gens); i++) { | 
 | 29 |         comprehension_ty comp = asdl_seq_GET(gens, i); | 
 | 30 |         if (!validate_expr(comp->target, Store) || | 
 | 31 |             !validate_expr(comp->iter, Load) || | 
 | 32 |             !validate_exprs(comp->ifs, Load, 0)) | 
 | 33 |             return 0; | 
 | 34 |     } | 
 | 35 |     return 1; | 
 | 36 | } | 
 | 37 |  | 
 | 38 | static int | 
 | 39 | validate_slice(slice_ty slice) | 
 | 40 | { | 
 | 41 |     switch (slice->kind) { | 
 | 42 |     case Slice_kind: | 
 | 43 |         return (!slice->v.Slice.lower || validate_expr(slice->v.Slice.lower, Load)) && | 
 | 44 |             (!slice->v.Slice.upper || validate_expr(slice->v.Slice.upper, Load)) && | 
 | 45 |             (!slice->v.Slice.step || validate_expr(slice->v.Slice.step, Load)); | 
 | 46 |     case ExtSlice_kind: { | 
 | 47 |         int i; | 
 | 48 |         if (!validate_nonempty_seq(slice->v.ExtSlice.dims, "dims", "ExtSlice")) | 
 | 49 |             return 0; | 
 | 50 |         for (i = 0; i < asdl_seq_LEN(slice->v.ExtSlice.dims); i++) | 
 | 51 |             if (!validate_slice(asdl_seq_GET(slice->v.ExtSlice.dims, i))) | 
 | 52 |                 return 0; | 
 | 53 |         return 1; | 
 | 54 |     } | 
 | 55 |     case Index_kind: | 
 | 56 |         return validate_expr(slice->v.Index.value, Load); | 
 | 57 |     default: | 
 | 58 |         PyErr_SetString(PyExc_SystemError, "unknown slice node"); | 
 | 59 |         return 0; | 
 | 60 |     } | 
 | 61 | } | 
 | 62 |  | 
 | 63 | static int | 
 | 64 | validate_keywords(asdl_seq *keywords) | 
 | 65 | { | 
 | 66 |     int i; | 
 | 67 |     for (i = 0; i < asdl_seq_LEN(keywords); i++) | 
 | 68 |         if (!validate_expr(((keyword_ty)asdl_seq_GET(keywords, i))->value, Load)) | 
 | 69 |             return 0; | 
 | 70 |     return 1; | 
 | 71 | } | 
 | 72 |  | 
 | 73 | static int | 
 | 74 | validate_args(asdl_seq *args) | 
 | 75 | { | 
 | 76 |     int i; | 
 | 77 |     for (i = 0; i < asdl_seq_LEN(args); i++) { | 
 | 78 |         arg_ty arg = asdl_seq_GET(args, i); | 
 | 79 |         if (arg->annotation && !validate_expr(arg->annotation, Load)) | 
 | 80 |             return 0; | 
 | 81 |     } | 
 | 82 |     return 1; | 
 | 83 | } | 
 | 84 |  | 
 | 85 | static const char * | 
 | 86 | expr_context_name(expr_context_ty ctx) | 
 | 87 | { | 
 | 88 |     switch (ctx) { | 
 | 89 |     case Load: | 
 | 90 |         return "Load"; | 
 | 91 |     case Store: | 
 | 92 |         return "Store"; | 
 | 93 |     case Del: | 
 | 94 |         return "Del"; | 
 | 95 |     case AugLoad: | 
 | 96 |         return "AugLoad"; | 
 | 97 |     case AugStore: | 
 | 98 |         return "AugStore"; | 
 | 99 |     case Param: | 
 | 100 |         return "Param"; | 
 | 101 |     default: | 
 | 102 |         assert(0); | 
 | 103 |         return "(unknown)"; | 
 | 104 |     } | 
 | 105 | } | 
 | 106 |  | 
 | 107 | static int | 
 | 108 | validate_arguments(arguments_ty args) | 
 | 109 | { | 
 | 110 |     if (!validate_args(args->args)) | 
 | 111 |         return 0; | 
 | 112 |     if (args->varargannotation) { | 
 | 113 |         if (!args->vararg) { | 
 | 114 |             PyErr_SetString(PyExc_ValueError, "varargannotation but no vararg on arguments"); | 
 | 115 |             return 0; | 
 | 116 |         } | 
 | 117 |         if (!validate_expr(args->varargannotation, Load)) | 
 | 118 |             return 0; | 
 | 119 |     } | 
 | 120 |     if (!validate_args(args->kwonlyargs)) | 
 | 121 |         return 0; | 
 | 122 |     if (args->kwargannotation) { | 
 | 123 |         if (!args->kwarg) { | 
 | 124 |             PyErr_SetString(PyExc_ValueError, "kwargannotation but no kwarg on arguments"); | 
 | 125 |             return 0; | 
 | 126 |         } | 
 | 127 |         if (!validate_expr(args->kwargannotation, Load)) | 
 | 128 |             return 0; | 
 | 129 |     } | 
 | 130 |     if (asdl_seq_LEN(args->defaults) > asdl_seq_LEN(args->args)) { | 
 | 131 |         PyErr_SetString(PyExc_ValueError, "more positional defaults than args on arguments"); | 
 | 132 |         return 0; | 
 | 133 |     } | 
 | 134 |     if (asdl_seq_LEN(args->kw_defaults) != asdl_seq_LEN(args->kwonlyargs)) { | 
 | 135 |         PyErr_SetString(PyExc_ValueError, "length of kwonlyargs is not the same as " | 
 | 136 |                         "kw_defaults on arguments"); | 
 | 137 |         return 0; | 
 | 138 |     } | 
 | 139 |     return validate_exprs(args->defaults, Load, 0) && validate_exprs(args->kw_defaults, Load, 1); | 
 | 140 | } | 
 | 141 |  | 
 | 142 | static int | 
 | 143 | validate_expr(expr_ty exp, expr_context_ty ctx) | 
 | 144 | { | 
 | 145 |     int check_ctx = 1; | 
 | 146 |     expr_context_ty actual_ctx; | 
 | 147 |  | 
 | 148 |     /* First check expression context. */ | 
 | 149 |     switch (exp->kind) { | 
 | 150 |     case Attribute_kind: | 
 | 151 |         actual_ctx = exp->v.Attribute.ctx; | 
 | 152 |         break; | 
 | 153 |     case Subscript_kind: | 
 | 154 |         actual_ctx = exp->v.Subscript.ctx; | 
 | 155 |         break; | 
 | 156 |     case Starred_kind: | 
 | 157 |         actual_ctx = exp->v.Starred.ctx; | 
 | 158 |         break; | 
 | 159 |     case Name_kind: | 
 | 160 |         actual_ctx = exp->v.Name.ctx; | 
 | 161 |         break; | 
 | 162 |     case List_kind: | 
 | 163 |         actual_ctx = exp->v.List.ctx; | 
 | 164 |         break; | 
 | 165 |     case Tuple_kind: | 
 | 166 |         actual_ctx = exp->v.Tuple.ctx; | 
 | 167 |         break; | 
 | 168 |     default: | 
 | 169 |         if (ctx != Load) { | 
 | 170 |             PyErr_Format(PyExc_ValueError, "expression which can't be " | 
 | 171 |                          "assigned to in %s context", expr_context_name(ctx)); | 
 | 172 |             return 0; | 
 | 173 |         } | 
 | 174 |         check_ctx = 0; | 
 | 175 |     } | 
 | 176 |     if (check_ctx && actual_ctx != ctx) { | 
 | 177 |         PyErr_Format(PyExc_ValueError, "expression must have %s context but has %s instead", | 
 | 178 |                      expr_context_name(ctx), expr_context_name(actual_ctx)); | 
 | 179 |         return 0; | 
 | 180 |     } | 
 | 181 |  | 
 | 182 |     /* Now validate expression. */ | 
 | 183 |     switch (exp->kind) { | 
 | 184 |     case BoolOp_kind: | 
 | 185 |         if (asdl_seq_LEN(exp->v.BoolOp.values) < 2) { | 
 | 186 |             PyErr_SetString(PyExc_ValueError, "BoolOp with less than 2 values"); | 
 | 187 |             return 0; | 
 | 188 |         } | 
 | 189 |         return validate_exprs(exp->v.BoolOp.values, Load, 0); | 
 | 190 |     case BinOp_kind: | 
 | 191 |         return validate_expr(exp->v.BinOp.left, Load) && | 
 | 192 |             validate_expr(exp->v.BinOp.right, Load); | 
 | 193 |     case UnaryOp_kind: | 
 | 194 |         return validate_expr(exp->v.UnaryOp.operand, Load); | 
 | 195 |     case Lambda_kind: | 
 | 196 |         return validate_arguments(exp->v.Lambda.args) && | 
 | 197 |             validate_expr(exp->v.Lambda.body, Load); | 
 | 198 |     case IfExp_kind: | 
 | 199 |         return validate_expr(exp->v.IfExp.test, Load) && | 
 | 200 |             validate_expr(exp->v.IfExp.body, Load) && | 
 | 201 |             validate_expr(exp->v.IfExp.orelse, Load); | 
 | 202 |     case Dict_kind: | 
 | 203 |         if (asdl_seq_LEN(exp->v.Dict.keys) != asdl_seq_LEN(exp->v.Dict.values)) { | 
 | 204 |             PyErr_SetString(PyExc_ValueError, | 
 | 205 |                             "Dict doesn't have the same number of keys as values"); | 
 | 206 |             return 0; | 
 | 207 |         } | 
 | 208 |         return validate_exprs(exp->v.Dict.keys, Load, 0) && | 
 | 209 |             validate_exprs(exp->v.Dict.values, Load, 0); | 
 | 210 |     case Set_kind: | 
 | 211 |         return validate_exprs(exp->v.Set.elts, Load, 0); | 
 | 212 | #define COMP(NAME) \ | 
 | 213 |         case NAME ## _kind: \ | 
 | 214 |             return validate_comprehension(exp->v.NAME.generators) && \ | 
 | 215 |                 validate_expr(exp->v.NAME.elt, Load); | 
 | 216 |     COMP(ListComp) | 
 | 217 |     COMP(SetComp) | 
 | 218 |     COMP(GeneratorExp) | 
 | 219 | #undef COMP | 
 | 220 |     case DictComp_kind: | 
 | 221 |         return validate_comprehension(exp->v.DictComp.generators) && | 
 | 222 |             validate_expr(exp->v.DictComp.key, Load) && | 
 | 223 |             validate_expr(exp->v.DictComp.value, Load); | 
 | 224 |     case Yield_kind: | 
 | 225 |         return !exp->v.Yield.value || validate_expr(exp->v.Yield.value, Load); | 
| Benjamin Peterson | 527c622 | 2012-01-14 08:58:23 -0500 | [diff] [blame] | 226 |     case YieldFrom_kind: | 
 | 227 |         return !exp->v.YieldFrom.value || | 
 | 228 |             validate_expr(exp->v.YieldFrom.value, Load); | 
| Benjamin Peterson | 832bfe2 | 2011-08-09 16:15:04 -0500 | [diff] [blame] | 229 |     case Compare_kind: | 
 | 230 |         if (!asdl_seq_LEN(exp->v.Compare.comparators)) { | 
 | 231 |             PyErr_SetString(PyExc_ValueError, "Compare with no comparators"); | 
 | 232 |             return 0; | 
 | 233 |         } | 
 | 234 |         if (asdl_seq_LEN(exp->v.Compare.comparators) != | 
 | 235 |             asdl_seq_LEN(exp->v.Compare.ops)) { | 
 | 236 |             PyErr_SetString(PyExc_ValueError, "Compare has a different number " | 
 | 237 |                             "of comparators and operands"); | 
 | 238 |             return 0; | 
 | 239 |         } | 
 | 240 |         return validate_exprs(exp->v.Compare.comparators, Load, 0) && | 
 | 241 |             validate_expr(exp->v.Compare.left, Load); | 
 | 242 |     case Call_kind: | 
 | 243 |         return validate_expr(exp->v.Call.func, Load) && | 
 | 244 |             validate_exprs(exp->v.Call.args, Load, 0) && | 
 | 245 |             validate_keywords(exp->v.Call.keywords) && | 
 | 246 |             (!exp->v.Call.starargs || validate_expr(exp->v.Call.starargs, Load)) && | 
 | 247 |             (!exp->v.Call.kwargs || validate_expr(exp->v.Call.kwargs, Load)); | 
 | 248 |     case Num_kind: { | 
 | 249 |         PyObject *n = exp->v.Num.n; | 
 | 250 |         if (!PyLong_CheckExact(n) && !PyFloat_CheckExact(n) && | 
 | 251 |             !PyComplex_CheckExact(n)) { | 
 | 252 |             PyErr_SetString(PyExc_TypeError, "non-numeric type in Num"); | 
 | 253 |             return 0; | 
 | 254 |         } | 
 | 255 |         return 1; | 
 | 256 |     } | 
 | 257 |     case Str_kind: { | 
 | 258 |         PyObject *s = exp->v.Str.s; | 
 | 259 |         if (!PyUnicode_CheckExact(s)) { | 
 | 260 |             PyErr_SetString(PyExc_TypeError, "non-string type in Str"); | 
 | 261 |             return 0; | 
 | 262 |         } | 
 | 263 |         return 1; | 
 | 264 |     } | 
 | 265 |     case Bytes_kind: { | 
 | 266 |         PyObject *b = exp->v.Bytes.s; | 
 | 267 |         if (!PyBytes_CheckExact(b)) { | 
 | 268 |             PyErr_SetString(PyExc_TypeError, "non-bytes type in Bytes"); | 
 | 269 |             return 0; | 
 | 270 |         } | 
 | 271 |         return 1; | 
 | 272 |     } | 
 | 273 |     case Attribute_kind: | 
 | 274 |         return validate_expr(exp->v.Attribute.value, Load); | 
 | 275 |     case Subscript_kind: | 
 | 276 |         return validate_slice(exp->v.Subscript.slice) && | 
 | 277 |             validate_expr(exp->v.Subscript.value, Load); | 
 | 278 |     case Starred_kind: | 
 | 279 |         return validate_expr(exp->v.Starred.value, ctx); | 
 | 280 |     case List_kind: | 
 | 281 |         return validate_exprs(exp->v.List.elts, ctx, 0); | 
 | 282 |     case Tuple_kind: | 
 | 283 |         return validate_exprs(exp->v.Tuple.elts, ctx, 0); | 
 | 284 |     /* These last cases don't have any checking. */ | 
 | 285 |     case Name_kind: | 
 | 286 |     case Ellipsis_kind: | 
 | 287 |         return 1; | 
 | 288 |     default: | 
 | 289 |         PyErr_SetString(PyExc_SystemError, "unexpected expression"); | 
 | 290 |         return 0; | 
 | 291 |     } | 
 | 292 | } | 
 | 293 |  | 
 | 294 | static int | 
 | 295 | validate_nonempty_seq(asdl_seq *seq, const char *what, const char *owner) | 
 | 296 | { | 
 | 297 |     if (asdl_seq_LEN(seq)) | 
 | 298 |         return 1; | 
 | 299 |     PyErr_Format(PyExc_ValueError, "empty %s on %s", what, owner); | 
 | 300 |     return 0; | 
 | 301 | } | 
 | 302 |  | 
 | 303 | static int | 
 | 304 | validate_assignlist(asdl_seq *targets, expr_context_ty ctx) | 
 | 305 | { | 
 | 306 |     return validate_nonempty_seq(targets, "targets", ctx == Del ? "Delete" : "Assign") && | 
 | 307 |         validate_exprs(targets, ctx, 0); | 
 | 308 | } | 
 | 309 |  | 
 | 310 | static int | 
 | 311 | validate_body(asdl_seq *body, const char *owner) | 
 | 312 | { | 
 | 313 |     return validate_nonempty_seq(body, "body", owner) && validate_stmts(body); | 
 | 314 | } | 
 | 315 |  | 
 | 316 | static int | 
 | 317 | validate_stmt(stmt_ty stmt) | 
 | 318 | { | 
 | 319 |     int i; | 
 | 320 |     switch (stmt->kind) { | 
 | 321 |     case FunctionDef_kind: | 
 | 322 |         return validate_body(stmt->v.FunctionDef.body, "FunctionDef") && | 
 | 323 |             validate_arguments(stmt->v.FunctionDef.args) && | 
 | 324 |             validate_exprs(stmt->v.FunctionDef.decorator_list, Load, 0) && | 
 | 325 |             (!stmt->v.FunctionDef.returns || | 
 | 326 |              validate_expr(stmt->v.FunctionDef.returns, Load)); | 
 | 327 |     case ClassDef_kind: | 
 | 328 |         return validate_body(stmt->v.ClassDef.body, "ClassDef") && | 
 | 329 |             validate_exprs(stmt->v.ClassDef.bases, Load, 0) && | 
 | 330 |             validate_keywords(stmt->v.ClassDef.keywords) && | 
 | 331 |             validate_exprs(stmt->v.ClassDef.decorator_list, Load, 0) && | 
 | 332 |             (!stmt->v.ClassDef.starargs || validate_expr(stmt->v.ClassDef.starargs, Load)) && | 
 | 333 |             (!stmt->v.ClassDef.kwargs || validate_expr(stmt->v.ClassDef.kwargs, Load)); | 
 | 334 |     case Return_kind: | 
 | 335 |         return !stmt->v.Return.value || validate_expr(stmt->v.Return.value, Load); | 
 | 336 |     case Delete_kind: | 
 | 337 |         return validate_assignlist(stmt->v.Delete.targets, Del); | 
 | 338 |     case Assign_kind: | 
 | 339 |         return validate_assignlist(stmt->v.Assign.targets, Store) && | 
 | 340 |             validate_expr(stmt->v.Assign.value, Load); | 
 | 341 |     case AugAssign_kind: | 
 | 342 |         return validate_expr(stmt->v.AugAssign.target, Store) && | 
 | 343 |             validate_expr(stmt->v.AugAssign.value, Load); | 
 | 344 |     case For_kind: | 
 | 345 |         return validate_expr(stmt->v.For.target, Store) && | 
 | 346 |             validate_expr(stmt->v.For.iter, Load) && | 
 | 347 |             validate_body(stmt->v.For.body, "For") && | 
 | 348 |             validate_stmts(stmt->v.For.orelse); | 
 | 349 |     case While_kind: | 
 | 350 |         return validate_expr(stmt->v.While.test, Load) && | 
 | 351 |             validate_body(stmt->v.While.body, "While") && | 
 | 352 |             validate_stmts(stmt->v.While.orelse); | 
 | 353 |     case If_kind: | 
 | 354 |         return validate_expr(stmt->v.If.test, Load) && | 
 | 355 |             validate_body(stmt->v.If.body, "If") && | 
 | 356 |             validate_stmts(stmt->v.If.orelse); | 
 | 357 |     case With_kind: | 
 | 358 |         if (!validate_nonempty_seq(stmt->v.With.items, "items", "With")) | 
 | 359 |             return 0; | 
 | 360 |         for (i = 0; i < asdl_seq_LEN(stmt->v.With.items); i++) { | 
 | 361 |             withitem_ty item = asdl_seq_GET(stmt->v.With.items, i); | 
 | 362 |             if (!validate_expr(item->context_expr, Load) || | 
 | 363 |                 (item->optional_vars && !validate_expr(item->optional_vars, Store))) | 
 | 364 |                 return 0; | 
 | 365 |         } | 
 | 366 |         return validate_body(stmt->v.With.body, "With"); | 
 | 367 |     case Raise_kind: | 
 | 368 |         if (stmt->v.Raise.exc) { | 
 | 369 |             return validate_expr(stmt->v.Raise.exc, Load) && | 
 | 370 |                 (!stmt->v.Raise.cause || validate_expr(stmt->v.Raise.cause, Load)); | 
 | 371 |         } | 
 | 372 |         if (stmt->v.Raise.cause) { | 
 | 373 |             PyErr_SetString(PyExc_ValueError, "Raise with cause but no exception"); | 
 | 374 |             return 0; | 
 | 375 |         } | 
 | 376 |         return 1; | 
 | 377 |     case Try_kind: | 
 | 378 |         if (!validate_body(stmt->v.Try.body, "Try")) | 
 | 379 |             return 0; | 
 | 380 |         if (!asdl_seq_LEN(stmt->v.Try.handlers) && | 
 | 381 |             !asdl_seq_LEN(stmt->v.Try.finalbody)) { | 
 | 382 |             PyErr_SetString(PyExc_ValueError, "Try has neither except handlers nor finalbody"); | 
 | 383 |             return 0; | 
 | 384 |         } | 
 | 385 |         if (!asdl_seq_LEN(stmt->v.Try.handlers) && | 
 | 386 |             asdl_seq_LEN(stmt->v.Try.orelse)) { | 
 | 387 |             PyErr_SetString(PyExc_ValueError, "Try has orelse but no except handlers"); | 
 | 388 |             return 0; | 
 | 389 |         } | 
 | 390 |         for (i = 0; i < asdl_seq_LEN(stmt->v.Try.handlers); i++) { | 
 | 391 |             excepthandler_ty handler = asdl_seq_GET(stmt->v.Try.handlers, i); | 
 | 392 |             if ((handler->v.ExceptHandler.type && | 
 | 393 |                  !validate_expr(handler->v.ExceptHandler.type, Load)) || | 
 | 394 |                 !validate_body(handler->v.ExceptHandler.body, "ExceptHandler")) | 
 | 395 |                 return 0; | 
 | 396 |         } | 
 | 397 |         return (!asdl_seq_LEN(stmt->v.Try.finalbody) || | 
 | 398 |                 validate_stmts(stmt->v.Try.finalbody)) && | 
 | 399 |             (!asdl_seq_LEN(stmt->v.Try.orelse) || | 
 | 400 |              validate_stmts(stmt->v.Try.orelse)); | 
 | 401 |     case Assert_kind: | 
 | 402 |         return validate_expr(stmt->v.Assert.test, Load) && | 
 | 403 |             (!stmt->v.Assert.msg || validate_expr(stmt->v.Assert.msg, Load)); | 
 | 404 |     case Import_kind: | 
 | 405 |         return validate_nonempty_seq(stmt->v.Import.names, "names", "Import"); | 
 | 406 |     case ImportFrom_kind: | 
 | 407 |         if (stmt->v.ImportFrom.level < -1) { | 
 | 408 |             PyErr_SetString(PyExc_ValueError, "ImportFrom level less than -1"); | 
 | 409 |             return 0; | 
 | 410 |         } | 
 | 411 |         return validate_nonempty_seq(stmt->v.ImportFrom.names, "names", "ImportFrom"); | 
 | 412 |     case Global_kind: | 
 | 413 |         return validate_nonempty_seq(stmt->v.Global.names, "names", "Global"); | 
 | 414 |     case Nonlocal_kind: | 
 | 415 |         return validate_nonempty_seq(stmt->v.Nonlocal.names, "names", "Nonlocal"); | 
 | 416 |     case Expr_kind: | 
 | 417 |         return validate_expr(stmt->v.Expr.value, Load); | 
 | 418 |     case Pass_kind: | 
 | 419 |     case Break_kind: | 
 | 420 |     case Continue_kind: | 
 | 421 |         return 1; | 
 | 422 |     default: | 
 | 423 |         PyErr_SetString(PyExc_SystemError, "unexpected statement"); | 
 | 424 |         return 0; | 
 | 425 |     } | 
 | 426 | } | 
 | 427 |  | 
 | 428 | static int | 
 | 429 | validate_stmts(asdl_seq *seq) | 
 | 430 | { | 
 | 431 |     int i; | 
 | 432 |     for (i = 0; i < asdl_seq_LEN(seq); i++) { | 
 | 433 |         stmt_ty stmt = asdl_seq_GET(seq, i); | 
 | 434 |         if (stmt) { | 
 | 435 |             if (!validate_stmt(stmt)) | 
 | 436 |                 return 0; | 
 | 437 |         } | 
 | 438 |         else { | 
 | 439 |             PyErr_SetString(PyExc_ValueError, | 
 | 440 |                             "None disallowed in statement list"); | 
 | 441 |             return 0; | 
 | 442 |         } | 
 | 443 |     } | 
 | 444 |     return 1; | 
 | 445 | } | 
 | 446 |  | 
 | 447 | static int | 
 | 448 | validate_exprs(asdl_seq *exprs, expr_context_ty ctx, int null_ok) | 
 | 449 | { | 
 | 450 |     int i; | 
 | 451 |     for (i = 0; i < asdl_seq_LEN(exprs); i++) { | 
 | 452 |         expr_ty expr = asdl_seq_GET(exprs, i); | 
 | 453 |         if (expr) { | 
 | 454 |             if (!validate_expr(expr, ctx)) | 
 | 455 |                 return 0; | 
 | 456 |         } | 
 | 457 |         else if (!null_ok) { | 
 | 458 |             PyErr_SetString(PyExc_ValueError, | 
 | 459 |                             "None disallowed in expression list"); | 
 | 460 |             return 0; | 
 | 461 |         } | 
 | 462 |              | 
 | 463 |     } | 
 | 464 |     return 1; | 
 | 465 | } | 
 | 466 |  | 
 | 467 | int | 
 | 468 | PyAST_Validate(mod_ty mod) | 
 | 469 | { | 
 | 470 |     int res = 0; | 
 | 471 |  | 
 | 472 |     switch (mod->kind) { | 
 | 473 |     case Module_kind: | 
 | 474 |         res = validate_stmts(mod->v.Module.body); | 
 | 475 |         break; | 
 | 476 |     case Interactive_kind: | 
 | 477 |         res = validate_stmts(mod->v.Interactive.body); | 
 | 478 |         break; | 
 | 479 |     case Expression_kind: | 
 | 480 |         res = validate_expr(mod->v.Expression.body, Load); | 
 | 481 |         break; | 
 | 482 |     case Suite_kind: | 
 | 483 |         PyErr_SetString(PyExc_ValueError, "Suite is not valid in the CPython compiler"); | 
 | 484 |         break; | 
 | 485 |     default: | 
 | 486 |         PyErr_SetString(PyExc_SystemError, "impossible module node"); | 
 | 487 |         res = 0; | 
 | 488 |         break; | 
 | 489 |     } | 
 | 490 |     return res; | 
 | 491 | } | 
 | 492 |  | 
| Benjamin Peterson | d3af6e3 | 2012-01-16 09:56:35 -0500 | [diff] [blame] | 493 | /* This is done here, so defines like "test" don't interfere with AST use above. */ | 
| Benjamin Peterson | 832bfe2 | 2011-08-09 16:15:04 -0500 | [diff] [blame] | 494 | #include "grammar.h" | 
 | 495 | #include "parsetok.h" | 
 | 496 | #include "graminit.h" | 
 | 497 |  | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 498 | /* Data structure used internally */ | 
 | 499 | struct compiling { | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 500 |     char *c_encoding; /* source encoding */ | 
 | 501 |     PyArena *c_arena; /* arena for allocating memeory */ | 
| Guido van Rossum | 0d3fb8a | 2007-11-26 23:23:18 +0000 | [diff] [blame] | 502 |     const char *c_filename; /* filename */ | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 503 |     PyObject *c_normalize; /* Normalization function from unicodedata. */ | 
 | 504 |     PyObject *c_normalize_args; /* Normalization argument tuple. */ | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 505 | }; | 
 | 506 |  | 
 | 507 | static asdl_seq *seq_for_testlist(struct compiling *, const node *); | 
 | 508 | static expr_ty ast_for_expr(struct compiling *, const node *); | 
 | 509 | static stmt_ty ast_for_stmt(struct compiling *, const node *); | 
 | 510 | static asdl_seq *ast_for_suite(struct compiling *, const node *); | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 511 | static asdl_seq *ast_for_exprlist(struct compiling *, const node *, | 
 | 512 |                                   expr_context_ty); | 
| Neil Schemenauer | c5dd10a | 2005-10-25 07:54:54 +0000 | [diff] [blame] | 513 | static expr_ty ast_for_testlist(struct compiling *, const node *); | 
| Guido van Rossum | d59da4b | 2007-05-22 18:11:13 +0000 | [diff] [blame] | 514 | static stmt_ty ast_for_classdef(struct compiling *, const node *, asdl_seq *); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 515 |  | 
 | 516 | /* Note different signature for ast_for_call */ | 
 | 517 | static expr_ty ast_for_call(struct compiling *, const node *, expr_ty); | 
 | 518 |  | 
| Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 519 | static PyObject *parsenumber(struct compiling *, const char *); | 
| Christian Heimes | 4d6ec85 | 2008-03-26 22:34:47 +0000 | [diff] [blame] | 520 | static PyObject *parsestr(struct compiling *, const node *n, int *bytesmode); | 
| Thomas Wouters | 00e41de | 2007-02-23 19:56:57 +0000 | [diff] [blame] | 521 | static PyObject *parsestrplus(struct compiling *, const node *n, | 
 | 522 |                               int *bytesmode); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 523 |  | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 524 | #define COMP_GENEXP   0 | 
 | 525 | #define COMP_LISTCOMP 1 | 
 | 526 | #define COMP_SETCOMP  2 | 
 | 527 |  | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 528 | static int | 
 | 529 | init_normalization(struct compiling *c) | 
| Martin v. Löwis | 4738340 | 2007-08-15 07:32:56 +0000 | [diff] [blame] | 530 | { | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 531 |     PyObject *m = PyImport_ImportModuleNoBlock("unicodedata"); | 
 | 532 |     if (!m) | 
 | 533 |         return 0; | 
 | 534 |     c->c_normalize = PyObject_GetAttrString(m, "normalize"); | 
 | 535 |     Py_DECREF(m); | 
 | 536 |     if (!c->c_normalize) | 
 | 537 |         return 0; | 
 | 538 |     c->c_normalize_args = Py_BuildValue("(sN)", "NFKC", Py_None); | 
 | 539 |     PyTuple_SET_ITEM(c->c_normalize_args, 1, NULL); | 
 | 540 |     if (!c->c_normalize_args) { | 
 | 541 |         Py_CLEAR(c->c_normalize); | 
 | 542 |         return 0; | 
 | 543 |     } | 
 | 544 |     return 1; | 
 | 545 | } | 
 | 546 |  | 
 | 547 | static identifier | 
 | 548 | new_identifier(const char* n, struct compiling *c) | 
 | 549 | { | 
| Martin v. Löwis | 5b22213 | 2007-06-10 09:51:05 +0000 | [diff] [blame] | 550 |     PyObject* id = PyUnicode_DecodeUTF8(n, strlen(n), NULL); | 
| Benjamin Peterson | 5eda913 | 2012-01-16 09:47:42 -0500 | [diff] [blame] | 551 |     if (!id) | 
| Benjamin Peterson | 3076006 | 2008-11-25 04:02:28 +0000 | [diff] [blame] | 552 |         return NULL; | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 553 |     /* PyUnicode_DecodeUTF8 should always return a ready string. */ | 
| Benjamin Peterson | 5eda913 | 2012-01-16 09:47:42 -0500 | [diff] [blame] | 554 |     assert(PyUnicode_IS_READY(id)); | 
| Martin v. Löwis | 4738340 | 2007-08-15 07:32:56 +0000 | [diff] [blame] | 555 |     /* Check whether there are non-ASCII characters in the | 
 | 556 |        identifier; if so, normalize to NFKC. */ | 
| Benjamin Peterson | de5827d | 2012-01-16 09:55:53 -0500 | [diff] [blame] | 557 |     if (!PyUnicode_IS_ASCII(id)) { | 
| Martin v. Löwis | d63a3b8 | 2011-09-28 07:41:54 +0200 | [diff] [blame] | 558 |         PyObject *id2; | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 559 |         if (!c->c_normalize && !init_normalization(c)) { | 
| Benjamin Peterson | 0fa35ea | 2012-01-16 09:50:48 -0500 | [diff] [blame] | 560 |             Py_DECREF(id); | 
| Martin v. Löwis | d63a3b8 | 2011-09-28 07:41:54 +0200 | [diff] [blame] | 561 |             return NULL; | 
| Benjamin Peterson | 0fa35ea | 2012-01-16 09:50:48 -0500 | [diff] [blame] | 562 |         } | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 563 |         PyTuple_SET_ITEM(c->c_normalize_args, 1, id); | 
 | 564 |         id2 = PyObject_Call(c->c_normalize, c->c_normalize_args, NULL); | 
| Benjamin Peterson | 0fa35ea | 2012-01-16 09:50:48 -0500 | [diff] [blame] | 565 |         Py_DECREF(id); | 
| Martin v. Löwis | d63a3b8 | 2011-09-28 07:41:54 +0200 | [diff] [blame] | 566 |         if (!id2) | 
 | 567 |             return NULL; | 
| Martin v. Löwis | d63a3b8 | 2011-09-28 07:41:54 +0200 | [diff] [blame] | 568 |         id = id2; | 
| Martin v. Löwis | 4738340 | 2007-08-15 07:32:56 +0000 | [diff] [blame] | 569 |     } | 
| Martin v. Löwis | 5b22213 | 2007-06-10 09:51:05 +0000 | [diff] [blame] | 570 |     PyUnicode_InternInPlace(&id); | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 571 |     PyArena_AddPyObject(c->c_arena, id); | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 572 |     return id; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 573 | } | 
 | 574 |  | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 575 | #define NEW_IDENTIFIER(n) new_identifier(STR(n), c) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 576 |  | 
 | 577 | /* This routine provides an invalid object for the syntax error. | 
 | 578 |    The outermost routine must unpack this error and create the | 
 | 579 |    proper object.  We do this so that we don't have to pass | 
 | 580 |    the filename to everything function. | 
 | 581 |  | 
 | 582 |    XXX Maybe we should just pass the filename... | 
 | 583 | */ | 
 | 584 |  | 
 | 585 | static int | 
 | 586 | ast_error(const node *n, const char *errstr) | 
 | 587 | { | 
| Benjamin Peterson | d4efd9e | 2010-09-20 23:02:10 +0000 | [diff] [blame] | 588 |     PyObject *u = Py_BuildValue("zii", errstr, LINENO(n), n->n_col_offset); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 589 |     if (!u) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 590 |         return 0; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 591 |     PyErr_SetObject(PyExc_SyntaxError, u); | 
 | 592 |     Py_DECREF(u); | 
 | 593 |     return 0; | 
 | 594 | } | 
 | 595 |  | 
 | 596 | static void | 
 | 597 | ast_error_finish(const char *filename) | 
 | 598 | { | 
| Benjamin Peterson | d4efd9e | 2010-09-20 23:02:10 +0000 | [diff] [blame] | 599 |     PyObject *type, *value, *tback, *errstr, *offset, *loc, *tmp; | 
| Victor Stinner | 4c7c8c3 | 2010-10-16 13:14:10 +0000 | [diff] [blame] | 600 |     PyObject *filename_obj; | 
| Neal Norwitz | 46b7bda | 2006-01-08 01:06:06 +0000 | [diff] [blame] | 601 |     long lineno; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 602 |  | 
 | 603 |     assert(PyErr_Occurred()); | 
 | 604 |     if (!PyErr_ExceptionMatches(PyExc_SyntaxError)) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 605 |         return; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 606 |  | 
 | 607 |     PyErr_Fetch(&type, &value, &tback); | 
 | 608 |     errstr = PyTuple_GetItem(value, 0); | 
 | 609 |     if (!errstr) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 610 |         return; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 611 |     Py_INCREF(errstr); | 
| Christian Heimes | 217cfd1 | 2007-12-02 14:31:20 +0000 | [diff] [blame] | 612 |     lineno = PyLong_AsLong(PyTuple_GetItem(value, 1)); | 
| Neal Norwitz | 8ad64aa | 2005-12-11 20:08:33 +0000 | [diff] [blame] | 613 |     if (lineno == -1) { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 614 |         Py_DECREF(errstr); | 
 | 615 |         return; | 
| Neal Norwitz | 8ad64aa | 2005-12-11 20:08:33 +0000 | [diff] [blame] | 616 |     } | 
| Benjamin Peterson | d4efd9e | 2010-09-20 23:02:10 +0000 | [diff] [blame] | 617 |     offset = PyTuple_GetItem(value, 2); | 
 | 618 |     if (!offset) { | 
 | 619 |         Py_DECREF(errstr); | 
 | 620 |         return; | 
 | 621 |     } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 622 |     Py_DECREF(value); | 
 | 623 |  | 
 | 624 |     loc = PyErr_ProgramText(filename, lineno); | 
 | 625 |     if (!loc) { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 626 |         Py_INCREF(Py_None); | 
 | 627 |         loc = Py_None; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 628 |     } | 
| Victor Stinner | 2f2ed1f | 2010-10-16 13:42:53 +0000 | [diff] [blame] | 629 |     if (filename != NULL) | 
 | 630 |         filename_obj = PyUnicode_DecodeFSDefault(filename); | 
 | 631 |     else { | 
 | 632 |         Py_INCREF(Py_None); | 
 | 633 |         filename_obj = Py_None; | 
 | 634 |     } | 
| Victor Stinner | 4c7c8c3 | 2010-10-16 13:14:10 +0000 | [diff] [blame] | 635 |     if (filename_obj != NULL) | 
 | 636 |         tmp = Py_BuildValue("(NlOO)", filename_obj, lineno, offset, loc); | 
 | 637 |     else | 
 | 638 |         tmp = NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 639 |     Py_DECREF(loc); | 
| Neal Norwitz | 8ad64aa | 2005-12-11 20:08:33 +0000 | [diff] [blame] | 640 |     if (!tmp) { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 641 |         Py_DECREF(errstr); | 
 | 642 |         return; | 
| Neal Norwitz | 8ad64aa | 2005-12-11 20:08:33 +0000 | [diff] [blame] | 643 |     } | 
| Thomas Wouters | 477c8d5 | 2006-05-27 19:21:47 +0000 | [diff] [blame] | 644 |     value = PyTuple_Pack(2, errstr, tmp); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 645 |     Py_DECREF(errstr); | 
 | 646 |     Py_DECREF(tmp); | 
 | 647 |     if (!value) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 648 |         return; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 649 |     PyErr_Restore(type, value, tback); | 
 | 650 | } | 
 | 651 |  | 
 | 652 | /* num_stmts() returns number of contained statements. | 
 | 653 |  | 
 | 654 |    Use this routine to determine how big a sequence is needed for | 
 | 655 |    the statements in a parse tree.  Its raison d'etre is this bit of | 
 | 656 |    grammar: | 
 | 657 |  | 
 | 658 |    stmt: simple_stmt | compound_stmt | 
 | 659 |    simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE | 
 | 660 |  | 
 | 661 |    A simple_stmt can contain multiple small_stmt elements joined | 
 | 662 |    by semicolons.  If the arg is a simple_stmt, the number of | 
 | 663 |    small_stmt elements is returned. | 
 | 664 | */ | 
 | 665 |  | 
 | 666 | static int | 
 | 667 | num_stmts(const node *n) | 
 | 668 | { | 
 | 669 |     int i, l; | 
 | 670 |     node *ch; | 
 | 671 |  | 
 | 672 |     switch (TYPE(n)) { | 
 | 673 |         case single_input: | 
 | 674 |             if (TYPE(CHILD(n, 0)) == NEWLINE) | 
 | 675 |                 return 0; | 
 | 676 |             else | 
 | 677 |                 return num_stmts(CHILD(n, 0)); | 
 | 678 |         case file_input: | 
 | 679 |             l = 0; | 
 | 680 |             for (i = 0; i < NCH(n); i++) { | 
 | 681 |                 ch = CHILD(n, i); | 
 | 682 |                 if (TYPE(ch) == stmt) | 
 | 683 |                     l += num_stmts(ch); | 
 | 684 |             } | 
 | 685 |             return l; | 
 | 686 |         case stmt: | 
 | 687 |             return num_stmts(CHILD(n, 0)); | 
 | 688 |         case compound_stmt: | 
 | 689 |             return 1; | 
 | 690 |         case simple_stmt: | 
 | 691 |             return NCH(n) / 2; /* Divide by 2 to remove count of semi-colons */ | 
 | 692 |         case suite: | 
 | 693 |             if (NCH(n) == 1) | 
 | 694 |                 return num_stmts(CHILD(n, 0)); | 
 | 695 |             else { | 
 | 696 |                 l = 0; | 
 | 697 |                 for (i = 2; i < (NCH(n) - 1); i++) | 
 | 698 |                     l += num_stmts(CHILD(n, i)); | 
 | 699 |                 return l; | 
 | 700 |             } | 
 | 701 |         default: { | 
 | 702 |             char buf[128]; | 
 | 703 |  | 
| Benjamin Peterson | b58dda7 | 2009-01-18 22:27:04 +0000 | [diff] [blame] | 704 |             sprintf(buf, "Non-statement found: %d %d", | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 705 |                     TYPE(n), NCH(n)); | 
 | 706 |             Py_FatalError(buf); | 
 | 707 |         } | 
 | 708 |     } | 
 | 709 |     assert(0); | 
 | 710 |     return 0; | 
 | 711 | } | 
 | 712 |  | 
 | 713 | /* Transform the CST rooted at node * to the appropriate AST | 
 | 714 | */ | 
 | 715 |  | 
 | 716 | mod_ty | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 717 | PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename, | 
 | 718 |                PyArena *arena) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 719 | { | 
| Jeremy Hylton | a829313 | 2006-02-28 17:58:27 +0000 | [diff] [blame] | 720 |     int i, j, k, num; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 721 |     asdl_seq *stmts = NULL; | 
 | 722 |     stmt_ty s; | 
 | 723 |     node *ch; | 
 | 724 |     struct compiling c; | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 725 |     mod_ty res = NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 726 |  | 
 | 727 |     if (flags && flags->cf_flags & PyCF_SOURCE_IS_UTF8) { | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 728 |         c.c_encoding = "utf-8"; | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 729 |         if (TYPE(n) == encoding_decl) { | 
| Guido van Rossum | 5397039 | 2007-06-12 00:28:30 +0000 | [diff] [blame] | 730 | #if 0 | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 731 |             ast_error(n, "encoding declaration in Unicode string"); | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 732 |             goto out; | 
| Guido van Rossum | 5397039 | 2007-06-12 00:28:30 +0000 | [diff] [blame] | 733 | #endif | 
 | 734 |             n = CHILD(n, 0); | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 735 |         } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 736 |     } else if (TYPE(n) == encoding_decl) { | 
 | 737 |         c.c_encoding = STR(n); | 
 | 738 |         n = CHILD(n, 0); | 
 | 739 |     } else { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 740 |         /* PEP 3120 */ | 
| Martin v. Löwis | 447d33e | 2007-07-29 18:10:01 +0000 | [diff] [blame] | 741 |         c.c_encoding = "utf-8"; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 742 |     } | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 743 |     c.c_arena = arena; | 
| Guido van Rossum | 0d3fb8a | 2007-11-26 23:23:18 +0000 | [diff] [blame] | 744 |     c.c_filename = filename; | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 745 |     c.c_normalize = c.c_normalize_args = NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 746 |  | 
| Jeremy Hylton | a829313 | 2006-02-28 17:58:27 +0000 | [diff] [blame] | 747 |     k = 0; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 748 |     switch (TYPE(n)) { | 
 | 749 |         case file_input: | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 750 |             stmts = asdl_seq_new(num_stmts(n), arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 751 |             if (!stmts) | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 752 |                 goto out; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 753 |             for (i = 0; i < NCH(n) - 1; i++) { | 
 | 754 |                 ch = CHILD(n, i); | 
 | 755 |                 if (TYPE(ch) == NEWLINE) | 
 | 756 |                     continue; | 
 | 757 |                 REQ(ch, stmt); | 
 | 758 |                 num = num_stmts(ch); | 
 | 759 |                 if (num == 1) { | 
 | 760 |                     s = ast_for_stmt(&c, ch); | 
 | 761 |                     if (!s) | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 762 |                         goto out; | 
| Jeremy Hylton | a829313 | 2006-02-28 17:58:27 +0000 | [diff] [blame] | 763 |                     asdl_seq_SET(stmts, k++, s); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 764 |                 } | 
 | 765 |                 else { | 
 | 766 |                     ch = CHILD(ch, 0); | 
 | 767 |                     REQ(ch, simple_stmt); | 
 | 768 |                     for (j = 0; j < num; j++) { | 
 | 769 |                         s = ast_for_stmt(&c, CHILD(ch, j * 2)); | 
 | 770 |                         if (!s) | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 771 |                             goto out; | 
| Jeremy Hylton | a829313 | 2006-02-28 17:58:27 +0000 | [diff] [blame] | 772 |                         asdl_seq_SET(stmts, k++, s); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 773 |                     } | 
 | 774 |                 } | 
 | 775 |             } | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 776 |             res = Module(stmts, arena); | 
 | 777 |             break; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 778 |         case eval_input: { | 
 | 779 |             expr_ty testlist_ast; | 
 | 780 |  | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 781 |             /* XXX Why not comp_for here? */ | 
| Neil Schemenauer | c5dd10a | 2005-10-25 07:54:54 +0000 | [diff] [blame] | 782 |             testlist_ast = ast_for_testlist(&c, CHILD(n, 0)); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 783 |             if (!testlist_ast) | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 784 |                 goto out; | 
 | 785 |             res = Expression(testlist_ast, arena); | 
 | 786 |             break; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 787 |         } | 
 | 788 |         case single_input: | 
 | 789 |             if (TYPE(CHILD(n, 0)) == NEWLINE) { | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 790 |                 stmts = asdl_seq_new(1, arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 791 |                 if (!stmts) | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 792 |                     goto out; | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 793 |                 asdl_seq_SET(stmts, 0, Pass(n->n_lineno, n->n_col_offset, | 
 | 794 |                                             arena)); | 
| Guido van Rossum | 360e4b8 | 2007-05-14 22:51:27 +0000 | [diff] [blame] | 795 |                 if (!asdl_seq_GET(stmts, 0)) | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 796 |                     goto out; | 
 | 797 |                 res = Interactive(stmts, arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 798 |             } | 
 | 799 |             else { | 
 | 800 |                 n = CHILD(n, 0); | 
 | 801 |                 num = num_stmts(n); | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 802 |                 stmts = asdl_seq_new(num, arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 803 |                 if (!stmts) | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 804 |                     goto out; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 805 |                 if (num == 1) { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 806 |                     s = ast_for_stmt(&c, n); | 
 | 807 |                     if (!s) | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 808 |                         goto out; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 809 |                     asdl_seq_SET(stmts, 0, s); | 
 | 810 |                 } | 
 | 811 |                 else { | 
 | 812 |                     /* Only a simple_stmt can contain multiple statements. */ | 
 | 813 |                     REQ(n, simple_stmt); | 
 | 814 |                     for (i = 0; i < NCH(n); i += 2) { | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 815 |                         if (TYPE(CHILD(n, i)) == NEWLINE) | 
 | 816 |                             break; | 
 | 817 |                         s = ast_for_stmt(&c, CHILD(n, i)); | 
 | 818 |                         if (!s) | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 819 |                             goto out; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 820 |                         asdl_seq_SET(stmts, i / 2, s); | 
 | 821 |                     } | 
 | 822 |                 } | 
 | 823 |  | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 824 |                 res = Interactive(stmts, arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 825 |             } | 
| Benjamin Peterson | c8909dd | 2012-01-16 17:44:12 -0500 | [diff] [blame] | 826 |             break; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 827 |         default: | 
| Guido van Rossum | 360e4b8 | 2007-05-14 22:51:27 +0000 | [diff] [blame] | 828 |             PyErr_Format(PyExc_SystemError, | 
 | 829 |                          "invalid node %d for PyAST_FromNode", TYPE(n)); | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 830 |             goto out; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 831 |     } | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 832 |  out: | 
 | 833 |     if (c.c_normalize) { | 
 | 834 |         Py_DECREF(c.c_normalize); | 
 | 835 |         PyTuple_SET_ITEM(c.c_normalize_args, 1, NULL); | 
 | 836 |         Py_DECREF(c.c_normalize_args); | 
 | 837 |     } | 
| Benjamin Peterson | 205ad61 | 2012-01-16 17:31:43 -0500 | [diff] [blame] | 838 |     if (!res) | 
 | 839 |         ast_error_finish(filename); | 
| Benjamin Peterson | 55e0043 | 2012-01-16 17:22:31 -0500 | [diff] [blame] | 840 |     return res; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 841 | } | 
 | 842 |  | 
 | 843 | /* Return the AST repr. of the operator represented as syntax (|, ^, etc.) | 
 | 844 | */ | 
 | 845 |  | 
 | 846 | static operator_ty | 
 | 847 | get_operator(const node *n) | 
 | 848 | { | 
 | 849 |     switch (TYPE(n)) { | 
 | 850 |         case VBAR: | 
 | 851 |             return BitOr; | 
 | 852 |         case CIRCUMFLEX: | 
 | 853 |             return BitXor; | 
 | 854 |         case AMPER: | 
 | 855 |             return BitAnd; | 
 | 856 |         case LEFTSHIFT: | 
 | 857 |             return LShift; | 
 | 858 |         case RIGHTSHIFT: | 
 | 859 |             return RShift; | 
 | 860 |         case PLUS: | 
 | 861 |             return Add; | 
 | 862 |         case MINUS: | 
 | 863 |             return Sub; | 
 | 864 |         case STAR: | 
 | 865 |             return Mult; | 
 | 866 |         case SLASH: | 
 | 867 |             return Div; | 
 | 868 |         case DOUBLESLASH: | 
 | 869 |             return FloorDiv; | 
 | 870 |         case PERCENT: | 
 | 871 |             return Mod; | 
 | 872 |         default: | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 873 |             return (operator_ty)0; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 874 |     } | 
 | 875 | } | 
 | 876 |  | 
| Guido van Rossum | e7ba495 | 2007-06-06 23:52:48 +0000 | [diff] [blame] | 877 | static const char* FORBIDDEN[] = { | 
 | 878 |     "None", | 
 | 879 |     "True", | 
 | 880 |     "False", | 
 | 881 |     NULL, | 
 | 882 | }; | 
 | 883 |  | 
 | 884 | static int | 
| Benjamin Peterson | 70f5276 | 2009-06-28 23:32:44 +0000 | [diff] [blame] | 885 | forbidden_name(identifier name, const node *n, int full_checks) | 
| Guido van Rossum | e7ba495 | 2007-06-06 23:52:48 +0000 | [diff] [blame] | 886 | { | 
| Benjamin Peterson | 78565b2 | 2009-06-28 19:19:51 +0000 | [diff] [blame] | 887 |     assert(PyUnicode_Check(name)); | 
| Benjamin Peterson | 70f5276 | 2009-06-28 23:32:44 +0000 | [diff] [blame] | 888 |     if (PyUnicode_CompareWithASCIIString(name, "__debug__") == 0) { | 
 | 889 |         ast_error(n, "assignment to keyword"); | 
 | 890 |         return 1; | 
 | 891 |     } | 
 | 892 |     if (full_checks) { | 
 | 893 |         const char **p; | 
 | 894 |         for (p = FORBIDDEN; *p; p++) { | 
 | 895 |             if (PyUnicode_CompareWithASCIIString(name, *p) == 0) { | 
 | 896 |                 ast_error(n, "assignment to keyword"); | 
 | 897 |                 return 1; | 
 | 898 |             } | 
| Guido van Rossum | e7ba495 | 2007-06-06 23:52:48 +0000 | [diff] [blame] | 899 |         } | 
 | 900 |     } | 
 | 901 |     return 0; | 
 | 902 | } | 
 | 903 |  | 
| Jeremy Hylton | a829313 | 2006-02-28 17:58:27 +0000 | [diff] [blame] | 904 | /* Set the context ctx for expr_ty e, recursively traversing e. | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 905 |  | 
 | 906 |    Only sets context for expr kinds that "can appear in assignment context" | 
 | 907 |    (according to ../Parser/Python.asdl).  For other expr kinds, it sets | 
 | 908 |    an appropriate syntax error and returns false. | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 909 | */ | 
 | 910 |  | 
 | 911 | static int | 
| Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 912 | set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 913 | { | 
 | 914 |     asdl_seq *s = NULL; | 
| Jeremy Hylton | c960f26 | 2006-01-27 15:18:39 +0000 | [diff] [blame] | 915 |     /* If a particular expression type can't be used for assign / delete, | 
 | 916 |        set expr_name to its name and an error message will be generated. | 
 | 917 |     */ | 
 | 918 |     const char* expr_name = NULL; | 
 | 919 |  | 
 | 920 |     /* The ast defines augmented store and load contexts, but the | 
 | 921 |        implementation here doesn't actually use them.  The code may be | 
 | 922 |        a little more complex than necessary as a result.  It also means | 
| Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 923 |        that expressions in an augmented assignment have a Store context. | 
| Jeremy Hylton | c960f26 | 2006-01-27 15:18:39 +0000 | [diff] [blame] | 924 |        Consider restructuring so that augmented assignment uses | 
| Guido van Rossum | c2e2074 | 2006-02-27 22:32:47 +0000 | [diff] [blame] | 925 |        set_context(), too. | 
| Jeremy Hylton | c960f26 | 2006-01-27 15:18:39 +0000 | [diff] [blame] | 926 |     */ | 
 | 927 |     assert(ctx != AugStore && ctx != AugLoad); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 928 |  | 
 | 929 |     switch (e->kind) { | 
 | 930 |         case Attribute_kind: | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 931 |             e->v.Attribute.ctx = ctx; | 
| Benjamin Peterson | 70f5276 | 2009-06-28 23:32:44 +0000 | [diff] [blame] | 932 |             if (ctx == Store && forbidden_name(e->v.Attribute.attr, n, 1)) | 
 | 933 |                 return 0; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 934 |             break; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 935 |         case Subscript_kind: | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 936 |             e->v.Subscript.ctx = ctx; | 
 | 937 |             break; | 
| Guido van Rossum | 0368b72 | 2007-05-11 16:50:42 +0000 | [diff] [blame] | 938 |         case Starred_kind: | 
 | 939 |             e->v.Starred.ctx = ctx; | 
| Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 940 |             if (!set_context(c, e->v.Starred.value, ctx, n)) | 
| Guido van Rossum | 0368b72 | 2007-05-11 16:50:42 +0000 | [diff] [blame] | 941 |                 return 0; | 
 | 942 |             break; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 943 |         case Name_kind: | 
| Guido van Rossum | e7ba495 | 2007-06-06 23:52:48 +0000 | [diff] [blame] | 944 |             if (ctx == Store) { | 
| Benjamin Peterson | 70f5276 | 2009-06-28 23:32:44 +0000 | [diff] [blame] | 945 |                 if (forbidden_name(e->v.Name.id, n, 1)) | 
| Guido van Rossum | e7ba495 | 2007-06-06 23:52:48 +0000 | [diff] [blame] | 946 |                     return 0; /* forbidden_name() calls ast_error() */ | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 947 |             } | 
 | 948 |             e->v.Name.ctx = ctx; | 
 | 949 |             break; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 950 |         case List_kind: | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 951 |             e->v.List.ctx = ctx; | 
 | 952 |             s = e->v.List.elts; | 
 | 953 |             break; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 954 |         case Tuple_kind: | 
| Benjamin Peterson | 78565b2 | 2009-06-28 19:19:51 +0000 | [diff] [blame] | 955 |             if (asdl_seq_LEN(e->v.Tuple.elts))  { | 
 | 956 |                 e->v.Tuple.ctx = ctx; | 
 | 957 |                 s = e->v.Tuple.elts; | 
 | 958 |             } | 
 | 959 |             else { | 
 | 960 |                 expr_name = "()"; | 
 | 961 |             } | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 962 |             break; | 
| Jeremy Hylton | c960f26 | 2006-01-27 15:18:39 +0000 | [diff] [blame] | 963 |         case Lambda_kind: | 
 | 964 |             expr_name = "lambda"; | 
 | 965 |             break; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 966 |         case Call_kind: | 
| Jeremy Hylton | c960f26 | 2006-01-27 15:18:39 +0000 | [diff] [blame] | 967 |             expr_name = "function call"; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 968 |             break; | 
| Jeremy Hylton | c960f26 | 2006-01-27 15:18:39 +0000 | [diff] [blame] | 969 |         case BoolOp_kind: | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 970 |         case BinOp_kind: | 
| Jeremy Hylton | c960f26 | 2006-01-27 15:18:39 +0000 | [diff] [blame] | 971 |         case UnaryOp_kind: | 
 | 972 |             expr_name = "operator"; | 
 | 973 |             break; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 974 |         case GeneratorExp_kind: | 
| Jeremy Hylton | c960f26 | 2006-01-27 15:18:39 +0000 | [diff] [blame] | 975 |             expr_name = "generator expression"; | 
 | 976 |             break; | 
| Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 977 |         case Yield_kind: | 
| Benjamin Peterson | 527c622 | 2012-01-14 08:58:23 -0500 | [diff] [blame] | 978 |         case YieldFrom_kind: | 
| Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 979 |             expr_name = "yield expression"; | 
 | 980 |             break; | 
| Jeremy Hylton | c960f26 | 2006-01-27 15:18:39 +0000 | [diff] [blame] | 981 |         case ListComp_kind: | 
 | 982 |             expr_name = "list comprehension"; | 
 | 983 |             break; | 
| Guido van Rossum | 0368b72 | 2007-05-11 16:50:42 +0000 | [diff] [blame] | 984 |         case SetComp_kind: | 
 | 985 |             expr_name = "set comprehension"; | 
 | 986 |             break; | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 987 |         case DictComp_kind: | 
 | 988 |             expr_name = "dict comprehension"; | 
 | 989 |             break; | 
| Jeremy Hylton | c960f26 | 2006-01-27 15:18:39 +0000 | [diff] [blame] | 990 |         case Dict_kind: | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 991 |         case Set_kind: | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 992 |         case Num_kind: | 
 | 993 |         case Str_kind: | 
| Benjamin Peterson | bd3e362 | 2011-04-12 18:33:28 -0500 | [diff] [blame] | 994 |         case Bytes_kind: | 
| Jeremy Hylton | c960f26 | 2006-01-27 15:18:39 +0000 | [diff] [blame] | 995 |             expr_name = "literal"; | 
 | 996 |             break; | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 997 |         case Ellipsis_kind: | 
 | 998 |             expr_name = "Ellipsis"; | 
 | 999 |             break; | 
| Jeremy Hylton | c960f26 | 2006-01-27 15:18:39 +0000 | [diff] [blame] | 1000 |         case Compare_kind: | 
 | 1001 |             expr_name = "comparison"; | 
 | 1002 |             break; | 
| Thomas Wouters | 477c8d5 | 2006-05-27 19:21:47 +0000 | [diff] [blame] | 1003 |         case IfExp_kind: | 
 | 1004 |             expr_name = "conditional expression"; | 
 | 1005 |             break; | 
| Jeremy Hylton | c960f26 | 2006-01-27 15:18:39 +0000 | [diff] [blame] | 1006 |         default: | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1007 |             PyErr_Format(PyExc_SystemError, | 
 | 1008 |                          "unexpected expression in assignment %d (line %d)", | 
| Jeremy Hylton | c960f26 | 2006-01-27 15:18:39 +0000 | [diff] [blame] | 1009 |                          e->kind, e->lineno); | 
 | 1010 |             return 0; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1011 |     } | 
| Jeremy Hylton | c960f26 | 2006-01-27 15:18:39 +0000 | [diff] [blame] | 1012 |     /* Check for error string set by switch */ | 
 | 1013 |     if (expr_name) { | 
 | 1014 |         char buf[300]; | 
 | 1015 |         PyOS_snprintf(buf, sizeof(buf), | 
 | 1016 |                       "can't %s %s", | 
 | 1017 |                       ctx == Store ? "assign to" : "delete", | 
 | 1018 |                       expr_name); | 
 | 1019 |         return ast_error(n, buf); | 
 | 1020 |     } | 
 | 1021 |  | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1022 |     /* If the LHS is a list or tuple, we need to set the assignment | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1023 |        context for all the contained elements. | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1024 |     */ | 
 | 1025 |     if (s) { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1026 |         int i; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1027 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1028 |         for (i = 0; i < asdl_seq_LEN(s); i++) { | 
| Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 1029 |             if (!set_context(c, (expr_ty)asdl_seq_GET(s, i), ctx, n)) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1030 |                 return 0; | 
 | 1031 |         } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1032 |     } | 
 | 1033 |     return 1; | 
 | 1034 | } | 
 | 1035 |  | 
 | 1036 | static operator_ty | 
| Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 1037 | ast_for_augassign(struct compiling *c, const node *n) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1038 | { | 
 | 1039 |     REQ(n, augassign); | 
 | 1040 |     n = CHILD(n, 0); | 
 | 1041 |     switch (STR(n)[0]) { | 
 | 1042 |         case '+': | 
 | 1043 |             return Add; | 
 | 1044 |         case '-': | 
 | 1045 |             return Sub; | 
 | 1046 |         case '/': | 
 | 1047 |             if (STR(n)[1] == '/') | 
 | 1048 |                 return FloorDiv; | 
 | 1049 |             else | 
 | 1050 |                 return Div; | 
 | 1051 |         case '%': | 
 | 1052 |             return Mod; | 
 | 1053 |         case '<': | 
 | 1054 |             return LShift; | 
 | 1055 |         case '>': | 
 | 1056 |             return RShift; | 
 | 1057 |         case '&': | 
 | 1058 |             return BitAnd; | 
 | 1059 |         case '^': | 
 | 1060 |             return BitXor; | 
 | 1061 |         case '|': | 
 | 1062 |             return BitOr; | 
 | 1063 |         case '*': | 
 | 1064 |             if (STR(n)[1] == '*') | 
 | 1065 |                 return Pow; | 
 | 1066 |             else | 
 | 1067 |                 return Mult; | 
 | 1068 |         default: | 
| Neal Norwitz | 7979265 | 2005-11-14 04:25:03 +0000 | [diff] [blame] | 1069 |             PyErr_Format(PyExc_SystemError, "invalid augassign: %s", STR(n)); | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 1070 |             return (operator_ty)0; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1071 |     } | 
 | 1072 | } | 
 | 1073 |  | 
 | 1074 | static cmpop_ty | 
| Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 1075 | ast_for_comp_op(struct compiling *c, const node *n) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1076 | { | 
| Guido van Rossum | b053cd8 | 2006-08-24 03:53:23 +0000 | [diff] [blame] | 1077 |     /* comp_op: '<'|'>'|'=='|'>='|'<='|'!='|'in'|'not' 'in'|'is' | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1078 |                |'is' 'not' | 
 | 1079 |     */ | 
 | 1080 |     REQ(n, comp_op); | 
 | 1081 |     if (NCH(n) == 1) { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1082 |         n = CHILD(n, 0); | 
 | 1083 |         switch (TYPE(n)) { | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1084 |             case LESS: | 
 | 1085 |                 return Lt; | 
 | 1086 |             case GREATER: | 
 | 1087 |                 return Gt; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1088 |             case EQEQUAL:                       /* == */ | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1089 |                 return Eq; | 
 | 1090 |             case LESSEQUAL: | 
 | 1091 |                 return LtE; | 
 | 1092 |             case GREATEREQUAL: | 
 | 1093 |                 return GtE; | 
 | 1094 |             case NOTEQUAL: | 
 | 1095 |                 return NotEq; | 
 | 1096 |             case NAME: | 
 | 1097 |                 if (strcmp(STR(n), "in") == 0) | 
 | 1098 |                     return In; | 
 | 1099 |                 if (strcmp(STR(n), "is") == 0) | 
 | 1100 |                     return Is; | 
 | 1101 |             default: | 
| Neal Norwitz | 7979265 | 2005-11-14 04:25:03 +0000 | [diff] [blame] | 1102 |                 PyErr_Format(PyExc_SystemError, "invalid comp_op: %s", | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1103 |                              STR(n)); | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 1104 |                 return (cmpop_ty)0; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1105 |         } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1106 |     } | 
 | 1107 |     else if (NCH(n) == 2) { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1108 |         /* handle "not in" and "is not" */ | 
 | 1109 |         switch (TYPE(CHILD(n, 0))) { | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1110 |             case NAME: | 
 | 1111 |                 if (strcmp(STR(CHILD(n, 1)), "in") == 0) | 
 | 1112 |                     return NotIn; | 
 | 1113 |                 if (strcmp(STR(CHILD(n, 0)), "is") == 0) | 
 | 1114 |                     return IsNot; | 
 | 1115 |             default: | 
| Neal Norwitz | 7979265 | 2005-11-14 04:25:03 +0000 | [diff] [blame] | 1116 |                 PyErr_Format(PyExc_SystemError, "invalid comp_op: %s %s", | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1117 |                              STR(CHILD(n, 0)), STR(CHILD(n, 1))); | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 1118 |                 return (cmpop_ty)0; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1119 |         } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1120 |     } | 
| Neal Norwitz | 7979265 | 2005-11-14 04:25:03 +0000 | [diff] [blame] | 1121 |     PyErr_Format(PyExc_SystemError, "invalid comp_op: has %d children", | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1122 |                  NCH(n)); | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 1123 |     return (cmpop_ty)0; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1124 | } | 
 | 1125 |  | 
 | 1126 | static asdl_seq * | 
 | 1127 | seq_for_testlist(struct compiling *c, const node *n) | 
 | 1128 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1129 |     /* testlist: test (',' test)* [','] | 
| Benjamin Peterson | 4905e80 | 2009-09-27 02:43:28 +0000 | [diff] [blame] | 1130 |        testlist_star_expr: test|star_expr (',' test|star_expr)* [','] | 
 | 1131 |     */ | 
| Armin Rigo | 3144130 | 2005-10-21 12:57:31 +0000 | [diff] [blame] | 1132 |     asdl_seq *seq; | 
 | 1133 |     expr_ty expression; | 
 | 1134 |     int i; | 
| Benjamin Peterson | 4905e80 | 2009-09-27 02:43:28 +0000 | [diff] [blame] | 1135 |     assert(TYPE(n) == testlist || TYPE(n) == testlist_star_expr || TYPE(n) == testlist_comp); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1136 |  | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 1137 |     seq = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1138 |     if (!seq) | 
 | 1139 |         return NULL; | 
 | 1140 |  | 
 | 1141 |     for (i = 0; i < NCH(n); i += 2) { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1142 |         const node *ch = CHILD(n, i); | 
| Benjamin Peterson | 4905e80 | 2009-09-27 02:43:28 +0000 | [diff] [blame] | 1143 |         assert(TYPE(ch) == test || TYPE(ch) == test_nocond || TYPE(ch) == star_expr); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1144 |  | 
| Benjamin Peterson | 4905e80 | 2009-09-27 02:43:28 +0000 | [diff] [blame] | 1145 |         expression = ast_for_expr(c, ch); | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 1146 |         if (!expression) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1147 |             return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1148 |  | 
 | 1149 |         assert(i / 2 < seq->size); | 
 | 1150 |         asdl_seq_SET(seq, i / 2, expression); | 
 | 1151 |     } | 
 | 1152 |     return seq; | 
 | 1153 | } | 
 | 1154 |  | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1155 | static arg_ty | 
| Benjamin Peterson | bc4665e | 2012-03-12 11:00:41 -0700 | [diff] [blame] | 1156 | ast_for_arg(struct compiling *c, const node *n) | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1157 | { | 
 | 1158 |     identifier name; | 
 | 1159 |     expr_ty annotation = NULL; | 
 | 1160 |     node *ch; | 
 | 1161 |  | 
| Guido van Rossum | 1bc535d | 2007-05-15 18:46:22 +0000 | [diff] [blame] | 1162 |     assert(TYPE(n) == tfpdef || TYPE(n) == vfpdef); | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1163 |     ch = CHILD(n, 0); | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1164 |     name = NEW_IDENTIFIER(ch); | 
 | 1165 |     if (!name) | 
 | 1166 |         return NULL; | 
| Benjamin Peterson | 70f5276 | 2009-06-28 23:32:44 +0000 | [diff] [blame] | 1167 |     if (forbidden_name(name, ch, 0)) | 
 | 1168 |         return NULL; | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1169 |  | 
 | 1170 |     if (NCH(n) == 3 && TYPE(CHILD(n, 1)) == COLON) { | 
 | 1171 |         annotation = ast_for_expr(c, CHILD(n, 2)); | 
 | 1172 |         if (!annotation) | 
 | 1173 |             return NULL; | 
 | 1174 |     } | 
 | 1175 |  | 
| Guido van Rossum | 1bc535d | 2007-05-15 18:46:22 +0000 | [diff] [blame] | 1176 |     return arg(name, annotation, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1177 | } | 
 | 1178 |  | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1179 | /* returns -1 if failed to handle keyword only arguments | 
 | 1180 |    returns new position to keep processing if successful | 
| Guido van Rossum | 1bc535d | 2007-05-15 18:46:22 +0000 | [diff] [blame] | 1181 |                (',' tfpdef ['=' test])* | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1182 |                      ^^^ | 
 | 1183 |    start pointing here | 
 | 1184 |  */ | 
 | 1185 | static int | 
 | 1186 | handle_keywordonly_args(struct compiling *c, const node *n, int start, | 
 | 1187 |                         asdl_seq *kwonlyargs, asdl_seq *kwdefaults) | 
 | 1188 | { | 
| Benjamin Peterson | d951e7b | 2008-11-25 22:19:53 +0000 | [diff] [blame] | 1189 |     PyObject *argname; | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1190 |     node *ch; | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1191 |     expr_ty expression, annotation; | 
 | 1192 |     arg_ty arg; | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1193 |     int i = start; | 
 | 1194 |     int j = 0; /* index for kwdefaults and kwonlyargs */ | 
| Amaury Forgeot d'Arc | 40d3a67 | 2007-12-09 21:49:48 +0000 | [diff] [blame] | 1195 |  | 
 | 1196 |     if (kwonlyargs == NULL) { | 
 | 1197 |         ast_error(CHILD(n, start), "named arguments must follow bare *"); | 
 | 1198 |         return -1; | 
 | 1199 |     } | 
 | 1200 |     assert(kwdefaults != NULL); | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1201 |     while (i < NCH(n)) { | 
 | 1202 |         ch = CHILD(n, i); | 
 | 1203 |         switch (TYPE(ch)) { | 
| Guido van Rossum | 1bc535d | 2007-05-15 18:46:22 +0000 | [diff] [blame] | 1204 |             case vfpdef: | 
 | 1205 |             case tfpdef: | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1206 |                 if (i + 1 < NCH(n) && TYPE(CHILD(n, i + 1)) == EQUAL) { | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1207 |                     expression = ast_for_expr(c, CHILD(n, i + 2)); | 
| Amaury Forgeot d'Arc | 92dc80a | 2010-08-19 17:43:15 +0000 | [diff] [blame] | 1208 |                     if (!expression) | 
| Amaury Forgeot d'Arc | 12844e6 | 2010-08-19 21:32:38 +0000 | [diff] [blame] | 1209 |                         goto error; | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1210 |                     asdl_seq_SET(kwdefaults, j, expression); | 
 | 1211 |                     i += 2; /* '=' and test */ | 
 | 1212 |                 } | 
 | 1213 |                 else { /* setting NULL if no default value exists */ | 
 | 1214 |                     asdl_seq_SET(kwdefaults, j, NULL); | 
 | 1215 |                 } | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1216 |                 if (NCH(ch) == 3) { | 
 | 1217 |                     /* ch is NAME ':' test */ | 
 | 1218 |                     annotation = ast_for_expr(c, CHILD(ch, 2)); | 
| Amaury Forgeot d'Arc | 92dc80a | 2010-08-19 17:43:15 +0000 | [diff] [blame] | 1219 |                     if (!annotation) | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1220 |                         goto error; | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1221 |                 } | 
 | 1222 |                 else { | 
 | 1223 |                     annotation = NULL; | 
 | 1224 |                 } | 
 | 1225 |                 ch = CHILD(ch, 0); | 
| Benjamin Peterson | d951e7b | 2008-11-25 22:19:53 +0000 | [diff] [blame] | 1226 |                 argname = NEW_IDENTIFIER(ch); | 
 | 1227 |                 if (!argname) | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1228 |                     goto error; | 
| Benjamin Peterson | 70f5276 | 2009-06-28 23:32:44 +0000 | [diff] [blame] | 1229 |                 if (forbidden_name(argname, ch, 0)) | 
 | 1230 |                     goto error; | 
| Benjamin Peterson | d951e7b | 2008-11-25 22:19:53 +0000 | [diff] [blame] | 1231 |                 arg = arg(argname, annotation, c->c_arena); | 
 | 1232 |                 if (!arg) | 
 | 1233 |                     goto error; | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1234 |                 asdl_seq_SET(kwonlyargs, j++, arg); | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1235 |                 i += 2; /* the name and the comma */ | 
 | 1236 |                 break; | 
 | 1237 |             case DOUBLESTAR: | 
 | 1238 |                 return i; | 
 | 1239 |             default: | 
 | 1240 |                 ast_error(ch, "unexpected node"); | 
 | 1241 |                 goto error; | 
 | 1242 |         } | 
 | 1243 |     } | 
 | 1244 |     return i; | 
 | 1245 |  error: | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1246 |     return -1; | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1247 | } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1248 |  | 
| Jeremy Hylton | a829313 | 2006-02-28 17:58:27 +0000 | [diff] [blame] | 1249 | /* Create AST for argument list. */ | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1250 |  | 
 | 1251 | static arguments_ty | 
 | 1252 | ast_for_arguments(struct compiling *c, const node *n) | 
 | 1253 | { | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1254 |     /* This function handles both typedargslist (function definition) | 
 | 1255 |        and varargslist (lambda definition). | 
 | 1256 |  | 
 | 1257 |        parameters: '(' [typedargslist] ')' | 
 | 1258 |        typedargslist: ((tfpdef ['=' test] ',')* | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1259 |            ('*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | 
| Guido van Rossum | 1bc535d | 2007-05-15 18:46:22 +0000 | [diff] [blame] | 1260 |            | '**' tfpdef) | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1261 |            | tfpdef ['=' test] (',' tfpdef ['=' test])* [',']) | 
| Guido van Rossum | 1bc535d | 2007-05-15 18:46:22 +0000 | [diff] [blame] | 1262 |        tfpdef: NAME [':' test] | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1263 |        varargslist: ((vfpdef ['=' test] ',')* | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1264 |            ('*' [vfpdef] (',' vfpdef ['=' test])*  [',' '**' vfpdef] | 
| Guido van Rossum | 1bc535d | 2007-05-15 18:46:22 +0000 | [diff] [blame] | 1265 |            | '**' vfpdef) | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1266 |            | vfpdef ['=' test] (',' vfpdef ['=' test])* [',']) | 
| Guido van Rossum | 1bc535d | 2007-05-15 18:46:22 +0000 | [diff] [blame] | 1267 |        vfpdef: NAME | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1268 |     */ | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1269 |     int i, j, k, nposargs = 0, nkwonlyargs = 0; | 
 | 1270 |     int nposdefaults = 0, found_default = 0; | 
 | 1271 |     asdl_seq *posargs, *posdefaults, *kwonlyargs, *kwdefaults; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1272 |     identifier vararg = NULL, kwarg = NULL; | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1273 |     arg_ty arg; | 
 | 1274 |     expr_ty varargannotation = NULL, kwargannotation = NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1275 |     node *ch; | 
 | 1276 |  | 
 | 1277 |     if (TYPE(n) == parameters) { | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1278 |         if (NCH(n) == 2) /* () as argument list */ | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1279 |             return arguments(NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 
 | 1280 |                              NULL, c->c_arena); | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1281 |         n = CHILD(n, 1); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1282 |     } | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1283 |     assert(TYPE(n) == typedargslist || TYPE(n) == varargslist); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1284 |  | 
| Jeremy Hylton | e921e02 | 2008-07-17 16:37:17 +0000 | [diff] [blame] | 1285 |     /* First count the number of positional args & defaults.  The | 
 | 1286 |        variable i is the loop index for this for loop and the next. | 
 | 1287 |        The next loop picks up where the first leaves off. | 
 | 1288 |     */ | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1289 |     for (i = 0; i < NCH(n); i++) { | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1290 |         ch = CHILD(n, i); | 
 | 1291 |         if (TYPE(ch) == STAR) { | 
| Jeremy Hylton | e921e02 | 2008-07-17 16:37:17 +0000 | [diff] [blame] | 1292 |             /* skip star */ | 
| Guido van Rossum | 1bc535d | 2007-05-15 18:46:22 +0000 | [diff] [blame] | 1293 |             i++; | 
| Jeremy Hylton | e921e02 | 2008-07-17 16:37:17 +0000 | [diff] [blame] | 1294 |             if (i < NCH(n) && /* skip argument following star */ | 
 | 1295 |                 (TYPE(CHILD(n, i)) == tfpdef || | 
 | 1296 |                  TYPE(CHILD(n, i)) == vfpdef)) { | 
 | 1297 |                 i++; | 
 | 1298 |             } | 
 | 1299 |             break; | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1300 |         } | 
| Guido van Rossum | 1bc535d | 2007-05-15 18:46:22 +0000 | [diff] [blame] | 1301 |         if (TYPE(ch) == DOUBLESTAR) break; | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1302 |         if (TYPE(ch) == vfpdef || TYPE(ch) == tfpdef) nposargs++; | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1303 |         if (TYPE(ch) == EQUAL) nposdefaults++; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1304 |     } | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1305 |     /* count the number of keyword only args & | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1306 |        defaults for keyword only args */ | 
 | 1307 |     for ( ; i < NCH(n); ++i) { | 
 | 1308 |         ch = CHILD(n, i); | 
 | 1309 |         if (TYPE(ch) == DOUBLESTAR) break; | 
| Guido van Rossum | 1bc535d | 2007-05-15 18:46:22 +0000 | [diff] [blame] | 1310 |         if (TYPE(ch) == tfpdef || TYPE(ch) == vfpdef) nkwonlyargs++; | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1311 |     } | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1312 |     posargs = (nposargs ? asdl_seq_new(nposargs, c->c_arena) : NULL); | 
 | 1313 |     if (!posargs && nposargs) | 
| Amaury Forgeot d'Arc | 92dc80a | 2010-08-19 17:43:15 +0000 | [diff] [blame] | 1314 |         return NULL; | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1315 |     kwonlyargs = (nkwonlyargs ? | 
 | 1316 |                    asdl_seq_new(nkwonlyargs, c->c_arena) : NULL); | 
 | 1317 |     if (!kwonlyargs && nkwonlyargs) | 
| Amaury Forgeot d'Arc | 92dc80a | 2010-08-19 17:43:15 +0000 | [diff] [blame] | 1318 |         return NULL; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1319 |     posdefaults = (nposdefaults ? | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1320 |                     asdl_seq_new(nposdefaults, c->c_arena) : NULL); | 
 | 1321 |     if (!posdefaults && nposdefaults) | 
| Amaury Forgeot d'Arc | 92dc80a | 2010-08-19 17:43:15 +0000 | [diff] [blame] | 1322 |         return NULL; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1323 |     /* The length of kwonlyargs and kwdefaults are same | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1324 |        since we set NULL as default for keyword only argument w/o default | 
 | 1325 |        - we have sequence data structure, but no dictionary */ | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1326 |     kwdefaults = (nkwonlyargs ? | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1327 |                    asdl_seq_new(nkwonlyargs, c->c_arena) : NULL); | 
 | 1328 |     if (!kwdefaults && nkwonlyargs) | 
| Amaury Forgeot d'Arc | 92dc80a | 2010-08-19 17:43:15 +0000 | [diff] [blame] | 1329 |         return NULL; | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1330 |  | 
 | 1331 |     if (nposargs + nkwonlyargs > 255) { | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1332 |         ast_error(n, "more than 255 arguments"); | 
 | 1333 |         return NULL; | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1334 |     } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1335 |  | 
| Guido van Rossum | 1bc535d | 2007-05-15 18:46:22 +0000 | [diff] [blame] | 1336 |     /* tfpdef: NAME [':' test] | 
 | 1337 |        vfpdef: NAME | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1338 |     */ | 
 | 1339 |     i = 0; | 
| Jeremy Hylton | a829313 | 2006-02-28 17:58:27 +0000 | [diff] [blame] | 1340 |     j = 0;  /* index for defaults */ | 
 | 1341 |     k = 0;  /* index for args */ | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1342 |     while (i < NCH(n)) { | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1343 |         ch = CHILD(n, i); | 
 | 1344 |         switch (TYPE(ch)) { | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1345 |             case tfpdef: | 
 | 1346 |             case vfpdef: | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1347 |                 /* XXX Need to worry about checking if TYPE(CHILD(n, i+1)) is | 
 | 1348 |                    anything other than EQUAL or a comma? */ | 
 | 1349 |                 /* XXX Should NCH(n) check be made a separate check? */ | 
 | 1350 |                 if (i + 1 < NCH(n) && TYPE(CHILD(n, i + 1)) == EQUAL) { | 
| Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 1351 |                     expr_ty expression = ast_for_expr(c, CHILD(n, i + 2)); | 
 | 1352 |                     if (!expression) | 
| Amaury Forgeot d'Arc | 92dc80a | 2010-08-19 17:43:15 +0000 | [diff] [blame] | 1353 |                         return NULL; | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1354 |                     assert(posdefaults != NULL); | 
 | 1355 |                     asdl_seq_SET(posdefaults, j++, expression); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1356 |                     i += 2; | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1357 |                     found_default = 1; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1358 |                 } | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1359 |                 else if (found_default) { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1360 |                     ast_error(n, | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1361 |                              "non-default argument follows default argument"); | 
| Amaury Forgeot d'Arc | 92dc80a | 2010-08-19 17:43:15 +0000 | [diff] [blame] | 1362 |                     return NULL; | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1363 |                 } | 
| Benjamin Peterson | bc4665e | 2012-03-12 11:00:41 -0700 | [diff] [blame] | 1364 |                 arg = ast_for_arg(c, ch); | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1365 |                 if (!arg) | 
| Amaury Forgeot d'Arc | 92dc80a | 2010-08-19 17:43:15 +0000 | [diff] [blame] | 1366 |                     return NULL; | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1367 |                 asdl_seq_SET(posargs, k++, arg); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1368 |                 i += 2; /* the name and the comma */ | 
 | 1369 |                 break; | 
 | 1370 |             case STAR: | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1371 |                 if (i+1 >= NCH(n)) { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1372 |                     ast_error(CHILD(n, i), | 
| Amaury Forgeot d'Arc | 40d3a67 | 2007-12-09 21:49:48 +0000 | [diff] [blame] | 1373 |                         "named arguments must follow bare *"); | 
| Amaury Forgeot d'Arc | 92dc80a | 2010-08-19 17:43:15 +0000 | [diff] [blame] | 1374 |                     return NULL; | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1375 |                 } | 
| Guido van Rossum | 1bc535d | 2007-05-15 18:46:22 +0000 | [diff] [blame] | 1376 |                 ch = CHILD(n, i+1);  /* tfpdef or COMMA */ | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1377 |                 if (TYPE(ch) == COMMA) { | 
 | 1378 |                     int res = 0; | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1379 |                     i += 2; /* now follows keyword only arguments */ | 
 | 1380 |                     res = handle_keywordonly_args(c, n, i, | 
 | 1381 |                                                   kwonlyargs, kwdefaults); | 
| Amaury Forgeot d'Arc | 92dc80a | 2010-08-19 17:43:15 +0000 | [diff] [blame] | 1382 |                     if (res == -1) return NULL; | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1383 |                     i = res; /* res has new position to process */ | 
 | 1384 |                 } | 
 | 1385 |                 else { | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1386 |                     vararg = NEW_IDENTIFIER(CHILD(ch, 0)); | 
| Benjamin Peterson | 3076006 | 2008-11-25 04:02:28 +0000 | [diff] [blame] | 1387 |                     if (!vararg) | 
 | 1388 |                         return NULL; | 
| Benjamin Peterson | 70f5276 | 2009-06-28 23:32:44 +0000 | [diff] [blame] | 1389 |                     if (forbidden_name(vararg, CHILD(ch, 0), 0)) | 
 | 1390 |                         return NULL; | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1391 |                     if (NCH(ch) > 1) { | 
| Guido van Rossum | 1bc535d | 2007-05-15 18:46:22 +0000 | [diff] [blame] | 1392 |                         /* there is an annotation on the vararg */ | 
 | 1393 |                         varargannotation = ast_for_expr(c, CHILD(ch, 2)); | 
| Amaury Forgeot d'Arc | 92dc80a | 2010-08-19 17:43:15 +0000 | [diff] [blame] | 1394 |                         if (!varargannotation) | 
 | 1395 |                             return NULL; | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1396 |                     } | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1397 |                     i += 3; | 
| Guido van Rossum | 1bc535d | 2007-05-15 18:46:22 +0000 | [diff] [blame] | 1398 |                     if (i < NCH(n) && (TYPE(CHILD(n, i)) == tfpdef | 
 | 1399 |                                     || TYPE(CHILD(n, i)) == vfpdef)) { | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1400 |                         int res = 0; | 
 | 1401 |                         res = handle_keywordonly_args(c, n, i, | 
 | 1402 |                                                       kwonlyargs, kwdefaults); | 
| Amaury Forgeot d'Arc | 92dc80a | 2010-08-19 17:43:15 +0000 | [diff] [blame] | 1403 |                         if (res == -1) return NULL; | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1404 |                         i = res; /* res has new position to process */ | 
 | 1405 |                     } | 
 | 1406 |                 } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1407 |                 break; | 
 | 1408 |             case DOUBLESTAR: | 
| Guido van Rossum | 1bc535d | 2007-05-15 18:46:22 +0000 | [diff] [blame] | 1409 |                 ch = CHILD(n, i+1);  /* tfpdef */ | 
 | 1410 |                 assert(TYPE(ch) == tfpdef || TYPE(ch) == vfpdef); | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1411 |                 kwarg = NEW_IDENTIFIER(CHILD(ch, 0)); | 
| Amaury Forgeot d'Arc | 12844e6 | 2010-08-19 21:32:38 +0000 | [diff] [blame] | 1412 |                 if (!kwarg) | 
 | 1413 |                     return NULL; | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1414 |                 if (NCH(ch) > 1) { | 
 | 1415 |                     /* there is an annotation on the kwarg */ | 
 | 1416 |                     kwargannotation = ast_for_expr(c, CHILD(ch, 2)); | 
| Amaury Forgeot d'Arc | 92dc80a | 2010-08-19 17:43:15 +0000 | [diff] [blame] | 1417 |                     if (!kwargannotation) | 
 | 1418 |                         return NULL; | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1419 |                 } | 
| Benjamin Peterson | 70f5276 | 2009-06-28 23:32:44 +0000 | [diff] [blame] | 1420 |                 if (forbidden_name(kwarg, CHILD(ch, 0), 0)) | 
| Amaury Forgeot d'Arc | 92dc80a | 2010-08-19 17:43:15 +0000 | [diff] [blame] | 1421 |                     return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1422 |                 i += 3; | 
 | 1423 |                 break; | 
 | 1424 |             default: | 
| Neal Norwitz | 7979265 | 2005-11-14 04:25:03 +0000 | [diff] [blame] | 1425 |                 PyErr_Format(PyExc_SystemError, | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1426 |                              "unexpected node in varargslist: %d @ %d", | 
 | 1427 |                              TYPE(ch), i); | 
| Amaury Forgeot d'Arc | 92dc80a | 2010-08-19 17:43:15 +0000 | [diff] [blame] | 1428 |                 return NULL; | 
| Guido van Rossum | 4f72a78 | 2006-10-27 23:31:49 +0000 | [diff] [blame] | 1429 |         } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1430 |     } | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1431 |     return arguments(posargs, vararg, varargannotation, kwonlyargs, kwarg, | 
 | 1432 |                     kwargannotation, posdefaults, kwdefaults, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1433 | } | 
 | 1434 |  | 
 | 1435 | static expr_ty | 
 | 1436 | ast_for_dotted_name(struct compiling *c, const node *n) | 
 | 1437 | { | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 1438 |     expr_ty e; | 
 | 1439 |     identifier id; | 
| Martin v. Löwis | 49c5da1 | 2006-03-01 22:49:05 +0000 | [diff] [blame] | 1440 |     int lineno, col_offset; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1441 |     int i; | 
 | 1442 |  | 
 | 1443 |     REQ(n, dotted_name); | 
| Martin v. Löwis | 49c5da1 | 2006-03-01 22:49:05 +0000 | [diff] [blame] | 1444 |  | 
 | 1445 |     lineno = LINENO(n); | 
 | 1446 |     col_offset = n->n_col_offset; | 
 | 1447 |  | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1448 |     id = NEW_IDENTIFIER(CHILD(n, 0)); | 
 | 1449 |     if (!id) | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 1450 |         return NULL; | 
| Martin v. Löwis | 49c5da1 | 2006-03-01 22:49:05 +0000 | [diff] [blame] | 1451 |     e = Name(id, Load, lineno, col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1452 |     if (!e) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1453 |         return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1454 |  | 
 | 1455 |     for (i = 2; i < NCH(n); i+=2) { | 
 | 1456 |         id = NEW_IDENTIFIER(CHILD(n, i)); | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1457 |         if (!id) | 
 | 1458 |             return NULL; | 
 | 1459 |         e = Attribute(e, id, Load, lineno, col_offset, c->c_arena); | 
 | 1460 |         if (!e) | 
 | 1461 |             return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1462 |     } | 
 | 1463 |  | 
 | 1464 |     return e; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1465 | } | 
 | 1466 |  | 
 | 1467 | static expr_ty | 
 | 1468 | ast_for_decorator(struct compiling *c, const node *n) | 
 | 1469 | { | 
 | 1470 |     /* decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE */ | 
 | 1471 |     expr_ty d = NULL; | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 1472 |     expr_ty name_expr; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1473 |  | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1474 |     REQ(n, decorator); | 
| Jeremy Hylton | c960f26 | 2006-01-27 15:18:39 +0000 | [diff] [blame] | 1475 |     REQ(CHILD(n, 0), AT); | 
 | 1476 |     REQ(RCHILD(n, -1), NEWLINE); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1477 |  | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1478 |     name_expr = ast_for_dotted_name(c, CHILD(n, 1)); | 
 | 1479 |     if (!name_expr) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1480 |         return NULL; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1481 |  | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1482 |     if (NCH(n) == 3) { /* No arguments */ | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1483 |         d = name_expr; | 
 | 1484 |         name_expr = NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1485 |     } | 
 | 1486 |     else if (NCH(n) == 5) { /* Call with no arguments */ | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1487 |         d = Call(name_expr, NULL, NULL, NULL, NULL, LINENO(n), | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 1488 |                  n->n_col_offset, c->c_arena); | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1489 |         if (!d) | 
 | 1490 |             return NULL; | 
 | 1491 |         name_expr = NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1492 |     } | 
 | 1493 |     else { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1494 |         d = ast_for_call(c, CHILD(n, 3), name_expr); | 
 | 1495 |         if (!d) | 
 | 1496 |             return NULL; | 
 | 1497 |         name_expr = NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1498 |     } | 
 | 1499 |  | 
 | 1500 |     return d; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1501 | } | 
 | 1502 |  | 
 | 1503 | static asdl_seq* | 
 | 1504 | ast_for_decorators(struct compiling *c, const node *n) | 
 | 1505 | { | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 1506 |     asdl_seq* decorator_seq; | 
| Neal Norwitz | e76adcd | 2005-11-15 05:04:31 +0000 | [diff] [blame] | 1507 |     expr_ty d; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1508 |     int i; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1509 |  | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1510 |     REQ(n, decorators); | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 1511 |     decorator_seq = asdl_seq_new(NCH(n), c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1512 |     if (!decorator_seq) | 
 | 1513 |         return NULL; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1514 |  | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1515 |     for (i = 0; i < NCH(n); i++) { | 
| Jeremy Hylton | a829313 | 2006-02-28 17:58:27 +0000 | [diff] [blame] | 1516 |         d = ast_for_decorator(c, CHILD(n, i)); | 
| Amaury Forgeot d'Arc | 92dc80a | 2010-08-19 17:43:15 +0000 | [diff] [blame] | 1517 |         if (!d) | 
 | 1518 |             return NULL; | 
 | 1519 |         asdl_seq_SET(decorator_seq, i, d); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1520 |     } | 
 | 1521 |     return decorator_seq; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1522 | } | 
 | 1523 |  | 
 | 1524 | static stmt_ty | 
| Guido van Rossum | d59da4b | 2007-05-22 18:11:13 +0000 | [diff] [blame] | 1525 | ast_for_funcdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1526 | { | 
| Guido van Rossum | d59da4b | 2007-05-22 18:11:13 +0000 | [diff] [blame] | 1527 |     /* funcdef: 'def' NAME parameters ['->' test] ':' suite */ | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 1528 |     identifier name; | 
 | 1529 |     arguments_ty args; | 
 | 1530 |     asdl_seq *body; | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1531 |     expr_ty returns = NULL; | 
| Guido van Rossum | d59da4b | 2007-05-22 18:11:13 +0000 | [diff] [blame] | 1532 |     int name_i = 1; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1533 |  | 
 | 1534 |     REQ(n, funcdef); | 
 | 1535 |  | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1536 |     name = NEW_IDENTIFIER(CHILD(n, name_i)); | 
 | 1537 |     if (!name) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1538 |         return NULL; | 
| Benjamin Peterson | 70f5276 | 2009-06-28 23:32:44 +0000 | [diff] [blame] | 1539 |     if (forbidden_name(name, CHILD(n, name_i), 0)) | 
 | 1540 |         return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1541 |     args = ast_for_arguments(c, CHILD(n, name_i + 1)); | 
 | 1542 |     if (!args) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1543 |         return NULL; | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1544 |     if (TYPE(CHILD(n, name_i+2)) == RARROW) { | 
 | 1545 |         returns = ast_for_expr(c, CHILD(n, name_i + 3)); | 
 | 1546 |         if (!returns) | 
| Amaury Forgeot d'Arc | 92dc80a | 2010-08-19 17:43:15 +0000 | [diff] [blame] | 1547 |             return NULL; | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1548 |         name_i += 2; | 
 | 1549 |     } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1550 |     body = ast_for_suite(c, CHILD(n, name_i + 3)); | 
 | 1551 |     if (!body) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1552 |         return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1553 |  | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1554 |     return FunctionDef(name, args, body, decorator_seq, returns, LINENO(n), | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 1555 |                        n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1556 | } | 
 | 1557 |  | 
| Guido van Rossum | d59da4b | 2007-05-22 18:11:13 +0000 | [diff] [blame] | 1558 | static stmt_ty | 
 | 1559 | ast_for_decorated(struct compiling *c, const node *n) | 
 | 1560 | { | 
 | 1561 |     /* decorated: decorators (classdef | funcdef) */ | 
 | 1562 |     stmt_ty thing = NULL; | 
 | 1563 |     asdl_seq *decorator_seq = NULL; | 
 | 1564 |  | 
 | 1565 |     REQ(n, decorated); | 
 | 1566 |  | 
 | 1567 |     decorator_seq = ast_for_decorators(c, CHILD(n, 0)); | 
 | 1568 |     if (!decorator_seq) | 
 | 1569 |       return NULL; | 
 | 1570 |  | 
 | 1571 |     assert(TYPE(CHILD(n, 1)) == funcdef || | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1572 |            TYPE(CHILD(n, 1)) == classdef); | 
| Guido van Rossum | d59da4b | 2007-05-22 18:11:13 +0000 | [diff] [blame] | 1573 |  | 
 | 1574 |     if (TYPE(CHILD(n, 1)) == funcdef) { | 
 | 1575 |       thing = ast_for_funcdef(c, CHILD(n, 1), decorator_seq); | 
 | 1576 |     } else if (TYPE(CHILD(n, 1)) == classdef) { | 
 | 1577 |       thing = ast_for_classdef(c, CHILD(n, 1), decorator_seq); | 
 | 1578 |     } | 
| Christian Heimes | 09aaa88 | 2008-02-23 15:01:06 +0000 | [diff] [blame] | 1579 |     /* we count the decorators in when talking about the class' or | 
 | 1580 |      * function's line number */ | 
 | 1581 |     if (thing) { | 
 | 1582 |         thing->lineno = LINENO(n); | 
 | 1583 |         thing->col_offset = n->n_col_offset; | 
 | 1584 |     } | 
| Guido van Rossum | d59da4b | 2007-05-22 18:11:13 +0000 | [diff] [blame] | 1585 |     return thing; | 
 | 1586 | } | 
 | 1587 |  | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1588 | static expr_ty | 
 | 1589 | ast_for_lambdef(struct compiling *c, const node *n) | 
 | 1590 | { | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1591 |     /* lambdef: 'lambda' [varargslist] ':' test | 
 | 1592 |        lambdef_nocond: 'lambda' [varargslist] ':' test_nocond */ | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1593 |     arguments_ty args; | 
 | 1594 |     expr_ty expression; | 
 | 1595 |  | 
 | 1596 |     if (NCH(n) == 3) { | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1597 |         args = arguments(NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 
 | 1598 |                          NULL, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1599 |         if (!args) | 
 | 1600 |             return NULL; | 
 | 1601 |         expression = ast_for_expr(c, CHILD(n, 2)); | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 1602 |         if (!expression) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1603 |             return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1604 |     } | 
 | 1605 |     else { | 
 | 1606 |         args = ast_for_arguments(c, CHILD(n, 1)); | 
 | 1607 |         if (!args) | 
 | 1608 |             return NULL; | 
 | 1609 |         expression = ast_for_expr(c, CHILD(n, 3)); | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 1610 |         if (!expression) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1611 |             return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1612 |     } | 
 | 1613 |  | 
| Martin v. Löwis | 49c5da1 | 2006-03-01 22:49:05 +0000 | [diff] [blame] | 1614 |     return Lambda(args, expression, LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1615 | } | 
 | 1616 |  | 
| Thomas Wouters | dca3b9c | 2006-02-27 00:24:13 +0000 | [diff] [blame] | 1617 | static expr_ty | 
 | 1618 | ast_for_ifexpr(struct compiling *c, const node *n) | 
 | 1619 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1620 |     /* test: or_test 'if' or_test 'else' test */ | 
| Thomas Wouters | dca3b9c | 2006-02-27 00:24:13 +0000 | [diff] [blame] | 1621 |     expr_ty expression, body, orelse; | 
 | 1622 |  | 
| Thomas Wouters | aa8b6c5 | 2006-02-27 16:46:22 +0000 | [diff] [blame] | 1623 |     assert(NCH(n) == 5); | 
| Thomas Wouters | dca3b9c | 2006-02-27 00:24:13 +0000 | [diff] [blame] | 1624 |     body = ast_for_expr(c, CHILD(n, 0)); | 
 | 1625 |     if (!body) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1626 |         return NULL; | 
| Thomas Wouters | dca3b9c | 2006-02-27 00:24:13 +0000 | [diff] [blame] | 1627 |     expression = ast_for_expr(c, CHILD(n, 2)); | 
 | 1628 |     if (!expression) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1629 |         return NULL; | 
| Thomas Wouters | dca3b9c | 2006-02-27 00:24:13 +0000 | [diff] [blame] | 1630 |     orelse = ast_for_expr(c, CHILD(n, 4)); | 
 | 1631 |     if (!orelse) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1632 |         return NULL; | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 1633 |     return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset, | 
 | 1634 |                  c->c_arena); | 
| Thomas Wouters | dca3b9c | 2006-02-27 00:24:13 +0000 | [diff] [blame] | 1635 | } | 
 | 1636 |  | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1637 | /* | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1638 |    Count the number of 'for' loops in a comprehension. | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1639 |  | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1640 |    Helper for ast_for_comprehension(). | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1641 | */ | 
 | 1642 |  | 
 | 1643 | static int | 
| Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 1644 | count_comp_fors(struct compiling *c, const node *n) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1645 | { | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 1646 |     int n_fors = 0; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1647 |  | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 1648 |   count_comp_for: | 
 | 1649 |     n_fors++; | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1650 |     REQ(n, comp_for); | 
 | 1651 |     if (NCH(n) == 5) | 
 | 1652 |         n = CHILD(n, 4); | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 1653 |     else | 
 | 1654 |         return n_fors; | 
 | 1655 |   count_comp_iter: | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1656 |     REQ(n, comp_iter); | 
 | 1657 |     n = CHILD(n, 0); | 
 | 1658 |     if (TYPE(n) == comp_for) | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 1659 |         goto count_comp_for; | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1660 |     else if (TYPE(n) == comp_if) { | 
 | 1661 |         if (NCH(n) == 3) { | 
 | 1662 |             n = CHILD(n, 2); | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 1663 |             goto count_comp_iter; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1664 |         } | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 1665 |         else | 
 | 1666 |             return n_fors; | 
 | 1667 |     } | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 1668 |  | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 1669 |     /* Should never be reached */ | 
 | 1670 |     PyErr_SetString(PyExc_SystemError, | 
 | 1671 |                     "logic error in count_comp_fors"); | 
 | 1672 |     return -1; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1673 | } | 
 | 1674 |  | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1675 | /* Count the number of 'if' statements in a comprehension. | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1676 |  | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1677 |    Helper for ast_for_comprehension(). | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1678 | */ | 
 | 1679 |  | 
 | 1680 | static int | 
| Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 1681 | count_comp_ifs(struct compiling *c, const node *n) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1682 | { | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 1683 |     int n_ifs = 0; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1684 |  | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 1685 |     while (1) { | 
 | 1686 |         REQ(n, comp_iter); | 
 | 1687 |         if (TYPE(CHILD(n, 0)) == comp_for) | 
 | 1688 |             return n_ifs; | 
 | 1689 |         n = CHILD(n, 0); | 
 | 1690 |         REQ(n, comp_if); | 
 | 1691 |         n_ifs++; | 
 | 1692 |         if (NCH(n) == 2) | 
 | 1693 |             return n_ifs; | 
 | 1694 |         n = CHILD(n, 2); | 
 | 1695 |     } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1696 | } | 
 | 1697 |  | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1698 | static asdl_seq * | 
 | 1699 | ast_for_comprehension(struct compiling *c, const node *n) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1700 | { | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1701 |     int i, n_fors; | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1702 |     asdl_seq *comps; | 
 | 1703 |  | 
| Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 1704 |     n_fors = count_comp_fors(c, n); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1705 |     if (n_fors == -1) | 
 | 1706 |         return NULL; | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 1707 |  | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1708 |     comps = asdl_seq_new(n_fors, c->c_arena); | 
 | 1709 |     if (!comps) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1710 |         return NULL; | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 1711 |  | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1712 |     for (i = 0; i < n_fors; i++) { | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1713 |         comprehension_ty comp; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1714 |         asdl_seq *t; | 
| Benjamin Peterson | 2e4b0e1 | 2009-09-11 22:36:20 +0000 | [diff] [blame] | 1715 |         expr_ty expression, first; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1716 |         node *for_ch; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1717 |  | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1718 |         REQ(n, comp_for); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1719 |  | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1720 |         for_ch = CHILD(n, 1); | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1721 |         t = ast_for_exprlist(c, for_ch, Store); | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 1722 |         if (!t) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1723 |             return NULL; | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1724 |         expression = ast_for_expr(c, CHILD(n, 3)); | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 1725 |         if (!expression) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1726 |             return NULL; | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 1727 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1728 |         /* Check the # of children rather than the length of t, since | 
 | 1729 |            (x for x, in ...) has 1 element in t, but still requires a Tuple. */ | 
| Benjamin Peterson | 2e4b0e1 | 2009-09-11 22:36:20 +0000 | [diff] [blame] | 1730 |         first = (expr_ty)asdl_seq_GET(t, 0); | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1731 |         if (NCH(for_ch) == 1) | 
| Benjamin Peterson | 2e4b0e1 | 2009-09-11 22:36:20 +0000 | [diff] [blame] | 1732 |             comp = comprehension(first, expression, NULL, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1733 |         else | 
| Benjamin Peterson | 2e4b0e1 | 2009-09-11 22:36:20 +0000 | [diff] [blame] | 1734 |             comp = comprehension(Tuple(t, Store, first->lineno, first->col_offset, | 
 | 1735 |                                      c->c_arena), | 
 | 1736 |                                expression, NULL, c->c_arena); | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1737 |         if (!comp) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1738 |             return NULL; | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 1739 |  | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1740 |         if (NCH(n) == 5) { | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1741 |             int j, n_ifs; | 
 | 1742 |             asdl_seq *ifs; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1743 |  | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1744 |             n = CHILD(n, 4); | 
| Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 1745 |             n_ifs = count_comp_ifs(c, n); | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 1746 |             if (n_ifs == -1) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1747 |                 return NULL; | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 1748 |  | 
 | 1749 |             ifs = asdl_seq_new(n_ifs, c->c_arena); | 
 | 1750 |             if (!ifs) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1751 |                 return NULL; | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 1752 |  | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1753 |             for (j = 0; j < n_ifs; j++) { | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1754 |                 REQ(n, comp_iter); | 
 | 1755 |                 n = CHILD(n, 0); | 
 | 1756 |                 REQ(n, comp_if); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1757 |  | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1758 |                 expression = ast_for_expr(c, CHILD(n, 1)); | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 1759 |                 if (!expression) | 
| Neil Schemenauer | c5dd10a | 2005-10-25 07:54:54 +0000 | [diff] [blame] | 1760 |                     return NULL; | 
| Jeremy Hylton | a829313 | 2006-02-28 17:58:27 +0000 | [diff] [blame] | 1761 |                 asdl_seq_SET(ifs, j, expression); | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1762 |                 if (NCH(n) == 3) | 
 | 1763 |                     n = CHILD(n, 2); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1764 |             } | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1765 |             /* on exit, must guarantee that n is a comp_for */ | 
 | 1766 |             if (TYPE(n) == comp_iter) | 
 | 1767 |                 n = CHILD(n, 0); | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1768 |             comp->ifs = ifs; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1769 |         } | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1770 |         asdl_seq_SET(comps, i, comp); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1771 |     } | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1772 |     return comps; | 
 | 1773 | } | 
 | 1774 |  | 
 | 1775 | static expr_ty | 
 | 1776 | ast_for_itercomp(struct compiling *c, const node *n, int type) | 
 | 1777 | { | 
 | 1778 |     /* testlist_comp: test ( comp_for | (',' test)* [','] ) | 
 | 1779 |        argument: [test '='] test [comp_for]       # Really [keyword '='] test */ | 
 | 1780 |     expr_ty elt; | 
 | 1781 |     asdl_seq *comps; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1782 |  | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1783 |     assert(NCH(n) > 1); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1784 |  | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1785 |     elt = ast_for_expr(c, CHILD(n, 0)); | 
 | 1786 |     if (!elt) | 
 | 1787 |         return NULL; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1788 |  | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1789 |     comps = ast_for_comprehension(c, CHILD(n, 1)); | 
 | 1790 |     if (!comps) | 
 | 1791 |         return NULL; | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1792 |  | 
 | 1793 |     if (type == COMP_GENEXP) | 
 | 1794 |         return GeneratorExp(elt, comps, LINENO(n), n->n_col_offset, c->c_arena); | 
 | 1795 |     else if (type == COMP_LISTCOMP) | 
 | 1796 |         return ListComp(elt, comps, LINENO(n), n->n_col_offset, c->c_arena); | 
 | 1797 |     else if (type == COMP_SETCOMP) | 
 | 1798 |         return SetComp(elt, comps, LINENO(n), n->n_col_offset, c->c_arena); | 
 | 1799 |     else | 
 | 1800 |         /* Should never happen */ | 
 | 1801 |         return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1802 | } | 
 | 1803 |  | 
 | 1804 | static expr_ty | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1805 | ast_for_dictcomp(struct compiling *c, const node *n) | 
 | 1806 | { | 
 | 1807 |     expr_ty key, value; | 
 | 1808 |     asdl_seq *comps; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1809 |  | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1810 |     assert(NCH(n) > 3); | 
 | 1811 |     REQ(CHILD(n, 1), COLON); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1812 |  | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1813 |     key = ast_for_expr(c, CHILD(n, 0)); | 
 | 1814 |     if (!key) | 
 | 1815 |         return NULL; | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1816 |     value = ast_for_expr(c, CHILD(n, 2)); | 
 | 1817 |     if (!value) | 
 | 1818 |         return NULL; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1819 |  | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1820 |     comps = ast_for_comprehension(c, CHILD(n, 3)); | 
 | 1821 |     if (!comps) | 
 | 1822 |         return NULL; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1823 |  | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1824 |     return DictComp(key, value, comps, LINENO(n), n->n_col_offset, c->c_arena); | 
 | 1825 | } | 
 | 1826 |  | 
 | 1827 | static expr_ty | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1828 | ast_for_genexp(struct compiling *c, const node *n) | 
 | 1829 | { | 
 | 1830 |     assert(TYPE(n) == (testlist_comp) || TYPE(n) == (argument)); | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1831 |     return ast_for_itercomp(c, n, COMP_GENEXP); | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1832 | } | 
 | 1833 |  | 
 | 1834 | static expr_ty | 
 | 1835 | ast_for_listcomp(struct compiling *c, const node *n) | 
 | 1836 | { | 
 | 1837 |     assert(TYPE(n) == (testlist_comp)); | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1838 |     return ast_for_itercomp(c, n, COMP_LISTCOMP); | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1839 | } | 
 | 1840 |  | 
 | 1841 | static expr_ty | 
 | 1842 | ast_for_setcomp(struct compiling *c, const node *n) | 
 | 1843 | { | 
 | 1844 |     assert(TYPE(n) == (dictorsetmaker)); | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1845 |     return ast_for_itercomp(c, n, COMP_SETCOMP); | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1846 | } | 
 | 1847 |  | 
 | 1848 |  | 
 | 1849 | static expr_ty | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1850 | ast_for_atom(struct compiling *c, const node *n) | 
 | 1851 | { | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1852 |     /* atom: '(' [yield_expr|testlist_comp] ')' | '[' [testlist_comp] ']' | 
 | 1853 |        | '{' [dictmaker|testlist_comp] '}' | NAME | NUMBER | STRING+ | 
| Guido van Rossum | e7ba495 | 2007-06-06 23:52:48 +0000 | [diff] [blame] | 1854 |        | '...' | 'None' | 'True' | 'False' | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1855 |     */ | 
 | 1856 |     node *ch = CHILD(n, 0); | 
| Thomas Wouters | 00e41de | 2007-02-23 19:56:57 +0000 | [diff] [blame] | 1857 |     int bytesmode = 0; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1858 |  | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1859 |     switch (TYPE(ch)) { | 
| Benjamin Peterson | 3076006 | 2008-11-25 04:02:28 +0000 | [diff] [blame] | 1860 |     case NAME: { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1861 |         /* All names start in Load context, but may later be | 
 | 1862 |            changed. */ | 
| Benjamin Peterson | 3076006 | 2008-11-25 04:02:28 +0000 | [diff] [blame] | 1863 |         PyObject *name = NEW_IDENTIFIER(ch); | 
 | 1864 |         if (!name) | 
 | 1865 |             return NULL; | 
 | 1866 |         return Name(name, Load, LINENO(n), n->n_col_offset, c->c_arena); | 
 | 1867 |     } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1868 |     case STRING: { | 
| Thomas Wouters | 00e41de | 2007-02-23 19:56:57 +0000 | [diff] [blame] | 1869 |         PyObject *str = parsestrplus(c, n, &bytesmode); | 
| Guido van Rossum | b5a755e | 2007-07-18 18:15:48 +0000 | [diff] [blame] | 1870 |         if (!str) { | 
| Guido van Rossum | 29fd712 | 2007-11-12 01:13:56 +0000 | [diff] [blame] | 1871 |             if (PyErr_ExceptionMatches(PyExc_UnicodeError)) { | 
| Guido van Rossum | b5a755e | 2007-07-18 18:15:48 +0000 | [diff] [blame] | 1872 |                 PyObject *type, *value, *tback, *errstr; | 
 | 1873 |                 PyErr_Fetch(&type, &value, &tback); | 
| Benjamin Peterson | 6f7fad1 | 2008-11-21 22:58:57 +0000 | [diff] [blame] | 1874 |                 errstr = PyObject_Str(value); | 
| Guido van Rossum | b5a755e | 2007-07-18 18:15:48 +0000 | [diff] [blame] | 1875 |                 if (errstr) { | 
 | 1876 |                     char *s = ""; | 
 | 1877 |                     char buf[128]; | 
| Marc-André Lemburg | 4cc0f24 | 2008-08-07 18:54:33 +0000 | [diff] [blame] | 1878 |                     s = _PyUnicode_AsString(errstr); | 
| Guido van Rossum | b5a755e | 2007-07-18 18:15:48 +0000 | [diff] [blame] | 1879 |                     PyOS_snprintf(buf, sizeof(buf), "(unicode error) %s", s); | 
 | 1880 |                     ast_error(n, buf); | 
| Benjamin Peterson | 6f7fad1 | 2008-11-21 22:58:57 +0000 | [diff] [blame] | 1881 |                     Py_DECREF(errstr); | 
| Guido van Rossum | b5a755e | 2007-07-18 18:15:48 +0000 | [diff] [blame] | 1882 |                 } else { | 
 | 1883 |                     ast_error(n, "(unicode error) unknown error"); | 
 | 1884 |                 } | 
 | 1885 |                 Py_DECREF(type); | 
 | 1886 |                 Py_DECREF(value); | 
 | 1887 |                 Py_XDECREF(tback); | 
 | 1888 |             } | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1889 |             return NULL; | 
| Guido van Rossum | b5a755e | 2007-07-18 18:15:48 +0000 | [diff] [blame] | 1890 |         } | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1891 |         PyArena_AddPyObject(c->c_arena, str); | 
| Thomas Wouters | 00e41de | 2007-02-23 19:56:57 +0000 | [diff] [blame] | 1892 |         if (bytesmode) | 
 | 1893 |             return Bytes(str, LINENO(n), n->n_col_offset, c->c_arena); | 
 | 1894 |         else | 
 | 1895 |             return Str(str, LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1896 |     } | 
 | 1897 |     case NUMBER: { | 
| Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 1898 |         PyObject *pynum = parsenumber(c, STR(ch)); | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1899 |         if (!pynum) | 
 | 1900 |             return NULL; | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 1901 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1902 |         PyArena_AddPyObject(c->c_arena, pynum); | 
 | 1903 |         return Num(pynum, LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1904 |     } | 
| Georg Brandl | dde0028 | 2007-03-18 19:01:53 +0000 | [diff] [blame] | 1905 |     case ELLIPSIS: /* Ellipsis */ | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1906 |         return Ellipsis(LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1907 |     case LPAR: /* some parenthesized expressions */ | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1908 |         ch = CHILD(n, 1); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1909 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1910 |         if (TYPE(ch) == RPAR) | 
 | 1911 |             return Tuple(NULL, Load, LINENO(n), n->n_col_offset, c->c_arena); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1912 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1913 |         if (TYPE(ch) == yield_expr) | 
 | 1914 |             return ast_for_expr(c, ch); | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1915 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1916 |         /* testlist_comp: test ( comp_for | (',' test)* [','] ) */ | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1917 |         if ((NCH(ch) > 1) && (TYPE(CHILD(ch, 1)) == comp_for)) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1918 |             return ast_for_genexp(c, ch); | 
| Benjamin Peterson | 78565b2 | 2009-06-28 19:19:51 +0000 | [diff] [blame] | 1919 |  | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1920 |         return ast_for_testlist(c, ch); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1921 |     case LSQB: /* list (or list comprehension) */ | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1922 |         ch = CHILD(n, 1); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1923 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1924 |         if (TYPE(ch) == RSQB) | 
 | 1925 |             return List(NULL, Load, LINENO(n), n->n_col_offset, c->c_arena); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1926 |  | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1927 |         REQ(ch, testlist_comp); | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1928 |         if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) { | 
 | 1929 |             asdl_seq *elts = seq_for_testlist(c, ch); | 
 | 1930 |             if (!elts) | 
 | 1931 |                 return NULL; | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 1932 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1933 |             return List(elts, Load, LINENO(n), n->n_col_offset, c->c_arena); | 
 | 1934 |         } | 
 | 1935 |         else | 
 | 1936 |             return ast_for_listcomp(c, ch); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1937 |     case LBRACE: { | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1938 |         /* dictorsetmaker: test ':' test (',' test ':' test)* [','] | | 
 | 1939 |          *                 test (gen_for | (',' test)* [','])  */ | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 1940 |         int i, size; | 
 | 1941 |         asdl_seq *keys, *values; | 
 | 1942 |  | 
 | 1943 |         ch = CHILD(n, 1); | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1944 |         if (TYPE(ch) == RBRACE) { | 
 | 1945 |             /* it's an empty dict */ | 
 | 1946 |             return Dict(NULL, NULL, LINENO(n), n->n_col_offset, c->c_arena); | 
 | 1947 |         } else if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) { | 
 | 1948 |             /* it's a simple set */ | 
| Guido van Rossum | 4d2adcc | 2007-04-17 21:58:50 +0000 | [diff] [blame] | 1949 |             asdl_seq *elts; | 
| Guido van Rossum | 86e58e2 | 2006-08-28 15:27:34 +0000 | [diff] [blame] | 1950 |             size = (NCH(ch) + 1) / 2; /* +1 in case no trailing comma */ | 
| Guido van Rossum | 4d2adcc | 2007-04-17 21:58:50 +0000 | [diff] [blame] | 1951 |             elts = asdl_seq_new(size, c->c_arena); | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1952 |             if (!elts) | 
| Guido van Rossum | 86e58e2 | 2006-08-28 15:27:34 +0000 | [diff] [blame] | 1953 |                 return NULL; | 
| Guido van Rossum | 86e58e2 | 2006-08-28 15:27:34 +0000 | [diff] [blame] | 1954 |             for (i = 0; i < NCH(ch); i += 2) { | 
 | 1955 |                 expr_ty expression; | 
 | 1956 |                 expression = ast_for_expr(c, CHILD(ch, i)); | 
 | 1957 |                 if (!expression) | 
 | 1958 |                     return NULL; | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1959 |                 asdl_seq_SET(elts, i / 2, expression); | 
| Guido van Rossum | 86e58e2 | 2006-08-28 15:27:34 +0000 | [diff] [blame] | 1960 |             } | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 1961 |             return Set(elts, LINENO(n), n->n_col_offset, c->c_arena); | 
 | 1962 |         } else if (TYPE(CHILD(ch, 1)) == comp_for) { | 
 | 1963 |             /* it's a set comprehension */ | 
 | 1964 |             return ast_for_setcomp(c, ch); | 
| Guido van Rossum | 992d4a3 | 2007-07-11 13:09:30 +0000 | [diff] [blame] | 1965 |         } else if (NCH(ch) > 3 && TYPE(CHILD(ch, 3)) == comp_for) { | 
 | 1966 |             return ast_for_dictcomp(c, ch); | 
| Guido van Rossum | 86e58e2 | 2006-08-28 15:27:34 +0000 | [diff] [blame] | 1967 |         } else { | 
 | 1968 |             /* it's a dict */ | 
 | 1969 |             size = (NCH(ch) + 1) / 4; /* +1 in case no trailing comma */ | 
 | 1970 |             keys = asdl_seq_new(size, c->c_arena); | 
 | 1971 |             if (!keys) | 
 | 1972 |                 return NULL; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1973 |  | 
| Guido van Rossum | 86e58e2 | 2006-08-28 15:27:34 +0000 | [diff] [blame] | 1974 |             values = asdl_seq_new(size, c->c_arena); | 
 | 1975 |             if (!values) | 
 | 1976 |                 return NULL; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1977 |  | 
| Guido van Rossum | 86e58e2 | 2006-08-28 15:27:34 +0000 | [diff] [blame] | 1978 |             for (i = 0; i < NCH(ch); i += 4) { | 
 | 1979 |                 expr_ty expression; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 1980 |  | 
| Guido van Rossum | 86e58e2 | 2006-08-28 15:27:34 +0000 | [diff] [blame] | 1981 |                 expression = ast_for_expr(c, CHILD(ch, i)); | 
 | 1982 |                 if (!expression) | 
 | 1983 |                     return NULL; | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 1984 |  | 
| Guido van Rossum | 86e58e2 | 2006-08-28 15:27:34 +0000 | [diff] [blame] | 1985 |                 asdl_seq_SET(keys, i / 4, expression); | 
| Neal Norwitz | e76adcd | 2005-11-15 05:04:31 +0000 | [diff] [blame] | 1986 |  | 
| Guido van Rossum | 86e58e2 | 2006-08-28 15:27:34 +0000 | [diff] [blame] | 1987 |                 expression = ast_for_expr(c, CHILD(ch, i + 2)); | 
 | 1988 |                 if (!expression) | 
 | 1989 |                     return NULL; | 
 | 1990 |  | 
 | 1991 |                 asdl_seq_SET(values, i / 4, expression); | 
 | 1992 |             } | 
 | 1993 |             return Dict(keys, values, LINENO(n), n->n_col_offset, c->c_arena); | 
 | 1994 |         } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1995 |     } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1996 |     default: | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1997 |         PyErr_Format(PyExc_SystemError, "unhandled atom %d", TYPE(ch)); | 
 | 1998 |         return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 1999 |     } | 
 | 2000 | } | 
 | 2001 |  | 
 | 2002 | static slice_ty | 
 | 2003 | ast_for_slice(struct compiling *c, const node *n) | 
 | 2004 | { | 
 | 2005 |     node *ch; | 
 | 2006 |     expr_ty lower = NULL, upper = NULL, step = NULL; | 
 | 2007 |  | 
 | 2008 |     REQ(n, subscript); | 
 | 2009 |  | 
 | 2010 |     /* | 
| Georg Brandl | 52318d6 | 2006-09-06 07:06:08 +0000 | [diff] [blame] | 2011 |        subscript: test | [test] ':' [test] [sliceop] | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2012 |        sliceop: ':' [test] | 
 | 2013 |     */ | 
 | 2014 |     ch = CHILD(n, 0); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2015 |     if (NCH(n) == 1 && TYPE(ch) == test) { | 
 | 2016 |         /* 'step' variable hold no significance in terms of being used over | 
 | 2017 |            other vars */ | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 2018 |         step = ast_for_expr(c, ch); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2019 |         if (!step) | 
 | 2020 |             return NULL; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 2021 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2022 |         return Index(step, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2023 |     } | 
 | 2024 |  | 
 | 2025 |     if (TYPE(ch) == test) { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2026 |         lower = ast_for_expr(c, ch); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2027 |         if (!lower) | 
 | 2028 |             return NULL; | 
 | 2029 |     } | 
 | 2030 |  | 
 | 2031 |     /* If there's an upper bound it's in the second or third position. */ | 
 | 2032 |     if (TYPE(ch) == COLON) { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2033 |         if (NCH(n) > 1) { | 
 | 2034 |             node *n2 = CHILD(n, 1); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2035 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2036 |             if (TYPE(n2) == test) { | 
 | 2037 |                 upper = ast_for_expr(c, n2); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2038 |                 if (!upper) | 
 | 2039 |                     return NULL; | 
 | 2040 |             } | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2041 |         } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2042 |     } else if (NCH(n) > 2) { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2043 |         node *n2 = CHILD(n, 2); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2044 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2045 |         if (TYPE(n2) == test) { | 
 | 2046 |             upper = ast_for_expr(c, n2); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2047 |             if (!upper) | 
 | 2048 |                 return NULL; | 
 | 2049 |         } | 
 | 2050 |     } | 
 | 2051 |  | 
 | 2052 |     ch = CHILD(n, NCH(n) - 1); | 
 | 2053 |     if (TYPE(ch) == sliceop) { | 
| Benjamin Peterson | 78565b2 | 2009-06-28 19:19:51 +0000 | [diff] [blame] | 2054 |         if (NCH(ch) != 1) { | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 2055 |             ch = CHILD(ch, 1); | 
 | 2056 |             if (TYPE(ch) == test) { | 
 | 2057 |                 step = ast_for_expr(c, ch); | 
 | 2058 |                 if (!step) | 
 | 2059 |                     return NULL; | 
 | 2060 |             } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2061 |         } | 
 | 2062 |     } | 
 | 2063 |  | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 2064 |     return Slice(lower, upper, step, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2065 | } | 
 | 2066 |  | 
 | 2067 | static expr_ty | 
 | 2068 | ast_for_binop(struct compiling *c, const node *n) | 
 | 2069 | { | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 2070 |     /* Must account for a sequence of expressions. | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 2071 |        How should A op B op C by represented? | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 2072 |        BinOp(BinOp(A, op, B), op, C). | 
 | 2073 |     */ | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2074 |  | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 2075 |     int i, nops; | 
 | 2076 |     expr_ty expr1, expr2, result; | 
 | 2077 |     operator_ty newoperator; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2078 |  | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 2079 |     expr1 = ast_for_expr(c, CHILD(n, 0)); | 
 | 2080 |     if (!expr1) | 
 | 2081 |         return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2082 |  | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 2083 |     expr2 = ast_for_expr(c, CHILD(n, 2)); | 
 | 2084 |     if (!expr2) | 
 | 2085 |         return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2086 |  | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 2087 |     newoperator = get_operator(CHILD(n, 1)); | 
 | 2088 |     if (!newoperator) | 
 | 2089 |         return NULL; | 
 | 2090 |  | 
 | 2091 |     result = BinOp(expr1, newoperator, expr2, LINENO(n), n->n_col_offset, | 
 | 2092 |                    c->c_arena); | 
 | 2093 |     if (!result) | 
 | 2094 |         return NULL; | 
 | 2095 |  | 
 | 2096 |     nops = (NCH(n) - 1) / 2; | 
 | 2097 |     for (i = 1; i < nops; i++) { | 
 | 2098 |         expr_ty tmp_result, tmp; | 
 | 2099 |         const node* next_oper = CHILD(n, i * 2 + 1); | 
 | 2100 |  | 
 | 2101 |         newoperator = get_operator(next_oper); | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 2102 |         if (!newoperator) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2103 |             return NULL; | 
 | 2104 |  | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 2105 |         tmp = ast_for_expr(c, CHILD(n, i * 2 + 2)); | 
 | 2106 |         if (!tmp) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2107 |             return NULL; | 
 | 2108 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 2109 |         tmp_result = BinOp(result, newoperator, tmp, | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 2110 |                            LINENO(next_oper), next_oper->n_col_offset, | 
 | 2111 |                            c->c_arena); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 2112 |         if (!tmp_result) | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 2113 |             return NULL; | 
 | 2114 |         result = tmp_result; | 
 | 2115 |     } | 
 | 2116 |     return result; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2117 | } | 
 | 2118 |  | 
| Neil Schemenauer | 982e8d6 | 2005-10-25 09:16:05 +0000 | [diff] [blame] | 2119 | static expr_ty | 
 | 2120 | ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr) | 
 | 2121 | { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 2122 |     /* trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME | 
| Jeremy Hylton | c7d3726 | 2006-02-27 17:29:29 +0000 | [diff] [blame] | 2123 |        subscriptlist: subscript (',' subscript)* [','] | 
 | 2124 |        subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop] | 
 | 2125 |      */ | 
| Neil Schemenauer | 982e8d6 | 2005-10-25 09:16:05 +0000 | [diff] [blame] | 2126 |     REQ(n, trailer); | 
 | 2127 |     if (TYPE(CHILD(n, 0)) == LPAR) { | 
 | 2128 |         if (NCH(n) == 2) | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 2129 |             return Call(left_expr, NULL, NULL, NULL, NULL, LINENO(n), | 
 | 2130 |                         n->n_col_offset, c->c_arena); | 
| Neil Schemenauer | 982e8d6 | 2005-10-25 09:16:05 +0000 | [diff] [blame] | 2131 |         else | 
| Jeremy Hylton | 9ebfbf0 | 2006-02-27 16:50:35 +0000 | [diff] [blame] | 2132 |             return ast_for_call(c, CHILD(n, 1), left_expr); | 
| Neil Schemenauer | 982e8d6 | 2005-10-25 09:16:05 +0000 | [diff] [blame] | 2133 |     } | 
| Jeremy Hylton | 9ebfbf0 | 2006-02-27 16:50:35 +0000 | [diff] [blame] | 2134 |     else if (TYPE(CHILD(n, 0)) == DOT ) { | 
| Benjamin Peterson | 3076006 | 2008-11-25 04:02:28 +0000 | [diff] [blame] | 2135 |         PyObject *attr_id = NEW_IDENTIFIER(CHILD(n, 1)); | 
 | 2136 |         if (!attr_id) | 
 | 2137 |             return NULL; | 
 | 2138 |         return Attribute(left_expr, attr_id, Load, | 
| Martin v. Löwis | 49c5da1 | 2006-03-01 22:49:05 +0000 | [diff] [blame] | 2139 |                          LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 9ebfbf0 | 2006-02-27 16:50:35 +0000 | [diff] [blame] | 2140 |     } | 
 | 2141 |     else { | 
 | 2142 |         REQ(CHILD(n, 0), LSQB); | 
| Neil Schemenauer | 982e8d6 | 2005-10-25 09:16:05 +0000 | [diff] [blame] | 2143 |         REQ(CHILD(n, 2), RSQB); | 
 | 2144 |         n = CHILD(n, 1); | 
| Jeremy Hylton | c7d3726 | 2006-02-27 17:29:29 +0000 | [diff] [blame] | 2145 |         if (NCH(n) == 1) { | 
| Neil Schemenauer | 982e8d6 | 2005-10-25 09:16:05 +0000 | [diff] [blame] | 2146 |             slice_ty slc = ast_for_slice(c, CHILD(n, 0)); | 
 | 2147 |             if (!slc) | 
 | 2148 |                 return NULL; | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 2149 |             return Subscript(left_expr, slc, Load, LINENO(n), n->n_col_offset, | 
 | 2150 |                              c->c_arena); | 
| Neil Schemenauer | 982e8d6 | 2005-10-25 09:16:05 +0000 | [diff] [blame] | 2151 |         } | 
 | 2152 |         else { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 2153 |             /* The grammar is ambiguous here. The ambiguity is resolved | 
| Jeremy Hylton | c7d3726 | 2006-02-27 17:29:29 +0000 | [diff] [blame] | 2154 |                by treating the sequence as a tuple literal if there are | 
 | 2155 |                no slice features. | 
 | 2156 |             */ | 
| Neil Schemenauer | 982e8d6 | 2005-10-25 09:16:05 +0000 | [diff] [blame] | 2157 |             int j; | 
 | 2158 |             slice_ty slc; | 
| Jeremy Hylton | c7d3726 | 2006-02-27 17:29:29 +0000 | [diff] [blame] | 2159 |             expr_ty e; | 
| Neal Norwitz | 6baa4c4 | 2007-02-26 19:14:12 +0000 | [diff] [blame] | 2160 |             int simple = 1; | 
| Jeremy Hylton | c7d3726 | 2006-02-27 17:29:29 +0000 | [diff] [blame] | 2161 |             asdl_seq *slices, *elts; | 
 | 2162 |             slices = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena); | 
| Neil Schemenauer | 982e8d6 | 2005-10-25 09:16:05 +0000 | [diff] [blame] | 2163 |             if (!slices) | 
 | 2164 |                 return NULL; | 
 | 2165 |             for (j = 0; j < NCH(n); j += 2) { | 
 | 2166 |                 slc = ast_for_slice(c, CHILD(n, j)); | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 2167 |                 if (!slc) | 
| Neil Schemenauer | 982e8d6 | 2005-10-25 09:16:05 +0000 | [diff] [blame] | 2168 |                     return NULL; | 
| Jeremy Hylton | c7d3726 | 2006-02-27 17:29:29 +0000 | [diff] [blame] | 2169 |                 if (slc->kind != Index_kind) | 
| Neal Norwitz | 6baa4c4 | 2007-02-26 19:14:12 +0000 | [diff] [blame] | 2170 |                     simple = 0; | 
| Neil Schemenauer | 982e8d6 | 2005-10-25 09:16:05 +0000 | [diff] [blame] | 2171 |                 asdl_seq_SET(slices, j / 2, slc); | 
 | 2172 |             } | 
| Jeremy Hylton | c7d3726 | 2006-02-27 17:29:29 +0000 | [diff] [blame] | 2173 |             if (!simple) { | 
 | 2174 |                 return Subscript(left_expr, ExtSlice(slices, c->c_arena), | 
| Martin v. Löwis | 49c5da1 | 2006-03-01 22:49:05 +0000 | [diff] [blame] | 2175 |                                  Load, LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | c7d3726 | 2006-02-27 17:29:29 +0000 | [diff] [blame] | 2176 |             } | 
 | 2177 |             /* extract Index values and put them in a Tuple */ | 
 | 2178 |             elts = asdl_seq_new(asdl_seq_LEN(slices), c->c_arena); | 
| Hye-Shik Chang | 4af5c8c | 2006-03-07 15:39:21 +0000 | [diff] [blame] | 2179 |             if (!elts) | 
 | 2180 |                 return NULL; | 
| Jeremy Hylton | c7d3726 | 2006-02-27 17:29:29 +0000 | [diff] [blame] | 2181 |             for (j = 0; j < asdl_seq_LEN(slices); ++j) { | 
 | 2182 |                 slc = (slice_ty)asdl_seq_GET(slices, j); | 
 | 2183 |                 assert(slc->kind == Index_kind  && slc->v.Index.value); | 
 | 2184 |                 asdl_seq_SET(elts, j, slc->v.Index.value); | 
 | 2185 |             } | 
| Martin v. Löwis | 49c5da1 | 2006-03-01 22:49:05 +0000 | [diff] [blame] | 2186 |             e = Tuple(elts, Load, LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | c7d3726 | 2006-02-27 17:29:29 +0000 | [diff] [blame] | 2187 |             if (!e) | 
 | 2188 |                 return NULL; | 
 | 2189 |             return Subscript(left_expr, Index(e, c->c_arena), | 
| Martin v. Löwis | 49c5da1 | 2006-03-01 22:49:05 +0000 | [diff] [blame] | 2190 |                              Load, LINENO(n), n->n_col_offset, c->c_arena); | 
| Neil Schemenauer | 982e8d6 | 2005-10-25 09:16:05 +0000 | [diff] [blame] | 2191 |         } | 
 | 2192 |     } | 
| Neil Schemenauer | 982e8d6 | 2005-10-25 09:16:05 +0000 | [diff] [blame] | 2193 | } | 
 | 2194 |  | 
 | 2195 | static expr_ty | 
| Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 2196 | ast_for_factor(struct compiling *c, const node *n) | 
 | 2197 | { | 
| Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 2198 |     expr_ty expression; | 
 | 2199 |  | 
| Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 2200 |     expression = ast_for_expr(c, CHILD(n, 1)); | 
 | 2201 |     if (!expression) | 
 | 2202 |         return NULL; | 
 | 2203 |  | 
 | 2204 |     switch (TYPE(CHILD(n, 0))) { | 
 | 2205 |         case PLUS: | 
 | 2206 |             return UnaryOp(UAdd, expression, LINENO(n), n->n_col_offset, | 
 | 2207 |                            c->c_arena); | 
 | 2208 |         case MINUS: | 
 | 2209 |             return UnaryOp(USub, expression, LINENO(n), n->n_col_offset, | 
 | 2210 |                            c->c_arena); | 
 | 2211 |         case TILDE: | 
 | 2212 |             return UnaryOp(Invert, expression, LINENO(n), | 
 | 2213 |                            n->n_col_offset, c->c_arena); | 
 | 2214 |     } | 
 | 2215 |     PyErr_Format(PyExc_SystemError, "unhandled factor: %d", | 
 | 2216 |                  TYPE(CHILD(n, 0))); | 
 | 2217 |     return NULL; | 
 | 2218 | } | 
 | 2219 |  | 
 | 2220 | static expr_ty | 
| Neil Schemenauer | 982e8d6 | 2005-10-25 09:16:05 +0000 | [diff] [blame] | 2221 | ast_for_power(struct compiling *c, const node *n) | 
 | 2222 | { | 
 | 2223 |     /* power: atom trailer* ('**' factor)* | 
 | 2224 |      */ | 
 | 2225 |     int i; | 
 | 2226 |     expr_ty e, tmp; | 
 | 2227 |     REQ(n, power); | 
 | 2228 |     e = ast_for_atom(c, CHILD(n, 0)); | 
 | 2229 |     if (!e) | 
 | 2230 |         return NULL; | 
 | 2231 |     if (NCH(n) == 1) | 
 | 2232 |         return e; | 
 | 2233 |     for (i = 1; i < NCH(n); i++) { | 
 | 2234 |         node *ch = CHILD(n, i); | 
 | 2235 |         if (TYPE(ch) != trailer) | 
 | 2236 |             break; | 
 | 2237 |         tmp = ast_for_trailer(c, ch, e); | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 2238 |         if (!tmp) | 
| Neil Schemenauer | 982e8d6 | 2005-10-25 09:16:05 +0000 | [diff] [blame] | 2239 |             return NULL; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2240 |         tmp->lineno = e->lineno; | 
 | 2241 |         tmp->col_offset = e->col_offset; | 
| Neil Schemenauer | 982e8d6 | 2005-10-25 09:16:05 +0000 | [diff] [blame] | 2242 |         e = tmp; | 
 | 2243 |     } | 
 | 2244 |     if (TYPE(CHILD(n, NCH(n) - 1)) == factor) { | 
 | 2245 |         expr_ty f = ast_for_expr(c, CHILD(n, NCH(n) - 1)); | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 2246 |         if (!f) | 
| Neil Schemenauer | 982e8d6 | 2005-10-25 09:16:05 +0000 | [diff] [blame] | 2247 |             return NULL; | 
| Martin v. Löwis | 49c5da1 | 2006-03-01 22:49:05 +0000 | [diff] [blame] | 2248 |         tmp = BinOp(e, Pow, f, LINENO(n), n->n_col_offset, c->c_arena); | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 2249 |         if (!tmp) | 
| Neil Schemenauer | 982e8d6 | 2005-10-25 09:16:05 +0000 | [diff] [blame] | 2250 |             return NULL; | 
| Neil Schemenauer | 982e8d6 | 2005-10-25 09:16:05 +0000 | [diff] [blame] | 2251 |         e = tmp; | 
 | 2252 |     } | 
 | 2253 |     return e; | 
 | 2254 | } | 
 | 2255 |  | 
| Guido van Rossum | 0368b72 | 2007-05-11 16:50:42 +0000 | [diff] [blame] | 2256 | static expr_ty | 
 | 2257 | ast_for_starred(struct compiling *c, const node *n) | 
 | 2258 | { | 
 | 2259 |     expr_ty tmp; | 
 | 2260 |     REQ(n, star_expr); | 
 | 2261 |  | 
 | 2262 |     tmp = ast_for_expr(c, CHILD(n, 1)); | 
 | 2263 |     if (!tmp) | 
 | 2264 |         return NULL; | 
 | 2265 |  | 
 | 2266 |     /* The Load context is changed later. */ | 
 | 2267 |     return Starred(tmp, Load, LINENO(n), n->n_col_offset, c->c_arena); | 
 | 2268 | } | 
 | 2269 |  | 
 | 2270 |  | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2271 | /* Do not name a variable 'expr'!  Will cause a compile error. | 
 | 2272 | */ | 
 | 2273 |  | 
 | 2274 | static expr_ty | 
 | 2275 | ast_for_expr(struct compiling *c, const node *n) | 
 | 2276 | { | 
 | 2277 |     /* handle the full range of simple expressions | 
| Thomas Wouters | dca3b9c | 2006-02-27 00:24:13 +0000 | [diff] [blame] | 2278 |        test: or_test ['if' or_test 'else' test] | lambdef | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 2279 |        test_nocond: or_test | lambdef_nocond | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 2280 |        or_test: and_test ('or' and_test)* | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2281 |        and_test: not_test ('and' not_test)* | 
 | 2282 |        not_test: 'not' not_test | comparison | 
 | 2283 |        comparison: expr (comp_op expr)* | 
 | 2284 |        expr: xor_expr ('|' xor_expr)* | 
 | 2285 |        xor_expr: and_expr ('^' and_expr)* | 
 | 2286 |        and_expr: shift_expr ('&' shift_expr)* | 
 | 2287 |        shift_expr: arith_expr (('<<'|'>>') arith_expr)* | 
 | 2288 |        arith_expr: term (('+'|'-') term)* | 
 | 2289 |        term: factor (('*'|'/'|'%'|'//') factor)* | 
 | 2290 |        factor: ('+'|'-'|'~') factor | power | 
 | 2291 |        power: atom trailer* ('**' factor)* | 
 | 2292 |     */ | 
 | 2293 |  | 
 | 2294 |     asdl_seq *seq; | 
 | 2295 |     int i; | 
 | 2296 |  | 
 | 2297 |  loop: | 
 | 2298 |     switch (TYPE(n)) { | 
 | 2299 |         case test: | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 2300 |         case test_nocond: | 
| Thomas Wouters | dca3b9c | 2006-02-27 00:24:13 +0000 | [diff] [blame] | 2301 |             if (TYPE(CHILD(n, 0)) == lambdef || | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 2302 |                 TYPE(CHILD(n, 0)) == lambdef_nocond) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2303 |                 return ast_for_lambdef(c, CHILD(n, 0)); | 
| Thomas Wouters | dca3b9c | 2006-02-27 00:24:13 +0000 | [diff] [blame] | 2304 |             else if (NCH(n) > 1) | 
 | 2305 |                 return ast_for_ifexpr(c, n); | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2306 |             /* Fallthrough */ | 
 | 2307 |         case or_test: | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2308 |         case and_test: | 
 | 2309 |             if (NCH(n) == 1) { | 
 | 2310 |                 n = CHILD(n, 0); | 
 | 2311 |                 goto loop; | 
 | 2312 |             } | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 2313 |             seq = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2314 |             if (!seq) | 
 | 2315 |                 return NULL; | 
 | 2316 |             for (i = 0; i < NCH(n); i += 2) { | 
 | 2317 |                 expr_ty e = ast_for_expr(c, CHILD(n, i)); | 
 | 2318 |                 if (!e) | 
 | 2319 |                     return NULL; | 
 | 2320 |                 asdl_seq_SET(seq, i / 2, e); | 
 | 2321 |             } | 
 | 2322 |             if (!strcmp(STR(CHILD(n, 1)), "and")) | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 2323 |                 return BoolOp(And, seq, LINENO(n), n->n_col_offset, | 
 | 2324 |                               c->c_arena); | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 2325 |             assert(!strcmp(STR(CHILD(n, 1)), "or")); | 
| Martin v. Löwis | 49c5da1 | 2006-03-01 22:49:05 +0000 | [diff] [blame] | 2326 |             return BoolOp(Or, seq, LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2327 |         case not_test: | 
 | 2328 |             if (NCH(n) == 1) { | 
 | 2329 |                 n = CHILD(n, 0); | 
 | 2330 |                 goto loop; | 
 | 2331 |             } | 
 | 2332 |             else { | 
 | 2333 |                 expr_ty expression = ast_for_expr(c, CHILD(n, 1)); | 
 | 2334 |                 if (!expression) | 
 | 2335 |                     return NULL; | 
 | 2336 |  | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 2337 |                 return UnaryOp(Not, expression, LINENO(n), n->n_col_offset, | 
 | 2338 |                                c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2339 |             } | 
 | 2340 |         case comparison: | 
 | 2341 |             if (NCH(n) == 1) { | 
 | 2342 |                 n = CHILD(n, 0); | 
 | 2343 |                 goto loop; | 
 | 2344 |             } | 
 | 2345 |             else { | 
 | 2346 |                 expr_ty expression; | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 2347 |                 asdl_int_seq *ops; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2348 |                 asdl_seq *cmps; | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 2349 |                 ops = asdl_int_seq_new(NCH(n) / 2, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2350 |                 if (!ops) | 
 | 2351 |                     return NULL; | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 2352 |                 cmps = asdl_seq_new(NCH(n) / 2, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2353 |                 if (!cmps) { | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2354 |                     return NULL; | 
 | 2355 |                 } | 
 | 2356 |                 for (i = 1; i < NCH(n); i += 2) { | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 2357 |                     cmpop_ty newoperator; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2358 |  | 
| Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 2359 |                     newoperator = ast_for_comp_op(c, CHILD(n, i)); | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 2360 |                     if (!newoperator) { | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2361 |                         return NULL; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2362 |                     } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2363 |  | 
 | 2364 |                     expression = ast_for_expr(c, CHILD(n, i + 1)); | 
| Neal Norwitz | e76adcd | 2005-11-15 05:04:31 +0000 | [diff] [blame] | 2365 |                     if (!expression) { | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2366 |                         return NULL; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2367 |                     } | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 2368 |  | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 2369 |                     asdl_seq_SET(ops, i / 2, newoperator); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2370 |                     asdl_seq_SET(cmps, i / 2, expression); | 
 | 2371 |                 } | 
 | 2372 |                 expression = ast_for_expr(c, CHILD(n, 0)); | 
| Neal Norwitz | e76adcd | 2005-11-15 05:04:31 +0000 | [diff] [blame] | 2373 |                 if (!expression) { | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2374 |                     return NULL; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2375 |                 } | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 2376 |  | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 2377 |                 return Compare(expression, ops, cmps, LINENO(n), | 
 | 2378 |                                n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2379 |             } | 
 | 2380 |             break; | 
 | 2381 |  | 
| Guido van Rossum | 0368b72 | 2007-05-11 16:50:42 +0000 | [diff] [blame] | 2382 |         case star_expr: | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 2383 |             return ast_for_starred(c, n); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2384 |         /* The next five cases all handle BinOps.  The main body of code | 
 | 2385 |            is the same in each case, but the switch turned inside out to | 
 | 2386 |            reuse the code for each type of operator. | 
 | 2387 |          */ | 
 | 2388 |         case expr: | 
 | 2389 |         case xor_expr: | 
 | 2390 |         case and_expr: | 
 | 2391 |         case shift_expr: | 
 | 2392 |         case arith_expr: | 
 | 2393 |         case term: | 
 | 2394 |             if (NCH(n) == 1) { | 
 | 2395 |                 n = CHILD(n, 0); | 
 | 2396 |                 goto loop; | 
 | 2397 |             } | 
 | 2398 |             return ast_for_binop(c, n); | 
 | 2399 |         case yield_expr: { | 
| Nick Coghlan | 1f7ce62 | 2012-01-13 21:43:40 +1000 | [diff] [blame] | 2400 |             node *an = NULL; | 
 | 2401 |             node *en = NULL; | 
 | 2402 |             int is_from = 0; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2403 |             expr_ty exp = NULL; | 
| Nick Coghlan | 1f7ce62 | 2012-01-13 21:43:40 +1000 | [diff] [blame] | 2404 |             if (NCH(n) > 1) | 
 | 2405 |                 an = CHILD(n, 1); /* yield_arg */ | 
 | 2406 |             if (an) { | 
 | 2407 |                 en = CHILD(an, NCH(an) - 1); | 
 | 2408 |                 if (NCH(an) == 2) { | 
 | 2409 |                     is_from = 1; | 
 | 2410 |                     exp = ast_for_expr(c, en); | 
 | 2411 |                 } | 
 | 2412 |                 else | 
 | 2413 |                     exp = ast_for_testlist(c, en); | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2414 |                 if (!exp) | 
 | 2415 |                     return NULL; | 
 | 2416 |             } | 
| Benjamin Peterson | 527c622 | 2012-01-14 08:58:23 -0500 | [diff] [blame] | 2417 |             if (is_from) | 
 | 2418 |                 return YieldFrom(exp, LINENO(n), n->n_col_offset, c->c_arena); | 
 | 2419 |             return Yield(exp, LINENO(n), n->n_col_offset, c->c_arena); | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2420 |         } | 
| Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 2421 |         case factor: | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2422 |             if (NCH(n) == 1) { | 
 | 2423 |                 n = CHILD(n, 0); | 
 | 2424 |                 goto loop; | 
 | 2425 |             } | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2426 |             return ast_for_factor(c, n); | 
| Neil Schemenauer | 982e8d6 | 2005-10-25 09:16:05 +0000 | [diff] [blame] | 2427 |         case power: | 
 | 2428 |             return ast_for_power(c, n); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2429 |         default: | 
| Neal Norwitz | 7979265 | 2005-11-14 04:25:03 +0000 | [diff] [blame] | 2430 |             PyErr_Format(PyExc_SystemError, "unhandled expr: %d", TYPE(n)); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2431 |             return NULL; | 
 | 2432 |     } | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 2433 |     /* should never get here unless if error is set */ | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2434 |     return NULL; | 
 | 2435 | } | 
 | 2436 |  | 
 | 2437 | static expr_ty | 
 | 2438 | ast_for_call(struct compiling *c, const node *n, expr_ty func) | 
 | 2439 | { | 
 | 2440 |     /* | 
 | 2441 |       arglist: (argument ',')* (argument [',']| '*' test [',' '**' test] | 
 | 2442 |                | '**' test) | 
| Nick Coghlan | 1f7ce62 | 2012-01-13 21:43:40 +1000 | [diff] [blame] | 2443 |       argument: [test '='] (test) [comp_for]        # Really [keyword '='] test | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2444 |     */ | 
 | 2445 |  | 
 | 2446 |     int i, nargs, nkeywords, ngens; | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 2447 |     asdl_seq *args; | 
 | 2448 |     asdl_seq *keywords; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2449 |     expr_ty vararg = NULL, kwarg = NULL; | 
 | 2450 |  | 
 | 2451 |     REQ(n, arglist); | 
 | 2452 |  | 
 | 2453 |     nargs = 0; | 
 | 2454 |     nkeywords = 0; | 
 | 2455 |     ngens = 0; | 
 | 2456 |     for (i = 0; i < NCH(n); i++) { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2457 |         node *ch = CHILD(n, i); | 
 | 2458 |         if (TYPE(ch) == argument) { | 
 | 2459 |             if (NCH(ch) == 1) | 
 | 2460 |                 nargs++; | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 2461 |             else if (TYPE(CHILD(ch, 1)) == comp_for) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2462 |                 ngens++; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2463 |             else | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2464 |                 nkeywords++; | 
 | 2465 |         } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2466 |     } | 
 | 2467 |     if (ngens > 1 || (ngens && (nargs || nkeywords))) { | 
| Jeremy Hylton | c960f26 | 2006-01-27 15:18:39 +0000 | [diff] [blame] | 2468 |         ast_error(n, "Generator expression must be parenthesized " | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2469 |                   "if not sole argument"); | 
 | 2470 |         return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2471 |     } | 
 | 2472 |  | 
 | 2473 |     if (nargs + nkeywords + ngens > 255) { | 
 | 2474 |       ast_error(n, "more than 255 arguments"); | 
 | 2475 |       return NULL; | 
 | 2476 |     } | 
 | 2477 |  | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 2478 |     args = asdl_seq_new(nargs + ngens, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2479 |     if (!args) | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 2480 |         return NULL; | 
 | 2481 |     keywords = asdl_seq_new(nkeywords, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2482 |     if (!keywords) | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 2483 |         return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2484 |     nargs = 0; | 
 | 2485 |     nkeywords = 0; | 
 | 2486 |     for (i = 0; i < NCH(n); i++) { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2487 |         node *ch = CHILD(n, i); | 
 | 2488 |         if (TYPE(ch) == argument) { | 
 | 2489 |             expr_ty e; | 
 | 2490 |             if (NCH(ch) == 1) { | 
 | 2491 |                 if (nkeywords) { | 
 | 2492 |                     ast_error(CHILD(ch, 0), | 
 | 2493 |                               "non-keyword arg after keyword arg"); | 
 | 2494 |                     return NULL; | 
 | 2495 |                 } | 
| Benjamin Peterson | 2d735bc | 2008-08-19 20:57:10 +0000 | [diff] [blame] | 2496 |                 if (vararg) { | 
 | 2497 |                     ast_error(CHILD(ch, 0), | 
 | 2498 |                               "only named arguments may follow *expression"); | 
 | 2499 |                     return NULL; | 
 | 2500 |                 } | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2501 |                 e = ast_for_expr(c, CHILD(ch, 0)); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2502 |                 if (!e) | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 2503 |                     return NULL; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2504 |                 asdl_seq_SET(args, nargs++, e); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 2505 |             } | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 2506 |             else if (TYPE(CHILD(ch, 1)) == comp_for) { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2507 |                 e = ast_for_genexp(c, ch); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2508 |                 if (!e) | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 2509 |                     return NULL; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2510 |                 asdl_seq_SET(args, nargs++, e); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2511 |             } | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2512 |             else { | 
 | 2513 |                 keyword_ty kw; | 
| Benjamin Peterson | 07a1f94 | 2008-07-01 20:03:27 +0000 | [diff] [blame] | 2514 |                 identifier key, tmp; | 
 | 2515 |                 int k; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2516 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 2517 |                 /* CHILD(ch, 0) is test, but must be an identifier? */ | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2518 |                 e = ast_for_expr(c, CHILD(ch, 0)); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2519 |                 if (!e) | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 2520 |                     return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2521 |                 /* f(lambda x: x[0] = 3) ends up getting parsed with | 
 | 2522 |                  * LHS test = lambda x: x[0], and RHS test = 3. | 
 | 2523 |                  * SF bug 132313 points out that complaining about a keyword | 
 | 2524 |                  * then is very confusing. | 
 | 2525 |                  */ | 
 | 2526 |                 if (e->kind == Lambda_kind) { | 
| Benjamin Peterson | c64ae92 | 2012-01-16 18:02:21 -0500 | [diff] [blame] | 2527 |                     ast_error(CHILD(ch, 0), "lambda cannot contain assignment"); | 
 | 2528 |                     return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2529 |                 } else if (e->kind != Name_kind) { | 
| Benjamin Peterson | c64ae92 | 2012-01-16 18:02:21 -0500 | [diff] [blame] | 2530 |                     ast_error(CHILD(ch, 0), "keyword can't be an expression"); | 
 | 2531 |                     return NULL; | 
| Benjamin Peterson | 70f5276 | 2009-06-28 23:32:44 +0000 | [diff] [blame] | 2532 |                 } else if (forbidden_name(e->v.Name.id, ch, 1)) { | 
| Benjamin Peterson | c64ae92 | 2012-01-16 18:02:21 -0500 | [diff] [blame] | 2533 |                     return NULL; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 2534 |                 } | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2535 |                 key = e->v.Name.id; | 
| Benjamin Peterson | 07a1f94 | 2008-07-01 20:03:27 +0000 | [diff] [blame] | 2536 |                 for (k = 0; k < nkeywords; k++) { | 
 | 2537 |                     tmp = ((keyword_ty)asdl_seq_GET(keywords, k))->arg; | 
 | 2538 |                     if (!PyUnicode_Compare(tmp, key)) { | 
 | 2539 |                         ast_error(CHILD(ch, 0), "keyword argument repeated"); | 
 | 2540 |                         return NULL; | 
 | 2541 |                     } | 
 | 2542 |                 } | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2543 |                 e = ast_for_expr(c, CHILD(ch, 2)); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2544 |                 if (!e) | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 2545 |                     return NULL; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2546 |                 kw = keyword(key, e, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2547 |                 if (!kw) | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 2548 |                     return NULL; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2549 |                 asdl_seq_SET(keywords, nkeywords++, kw); | 
 | 2550 |             } | 
 | 2551 |         } | 
 | 2552 |         else if (TYPE(ch) == STAR) { | 
 | 2553 |             vararg = ast_for_expr(c, CHILD(n, i+1)); | 
| Christian Heimes | dd15f6c | 2008-03-16 00:07:10 +0000 | [diff] [blame] | 2554 |             if (!vararg) | 
 | 2555 |                 return NULL; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2556 |             i++; | 
 | 2557 |         } | 
 | 2558 |         else if (TYPE(ch) == DOUBLESTAR) { | 
 | 2559 |             kwarg = ast_for_expr(c, CHILD(n, i+1)); | 
| Christian Heimes | dd15f6c | 2008-03-16 00:07:10 +0000 | [diff] [blame] | 2560 |             if (!kwarg) | 
 | 2561 |                 return NULL; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2562 |             i++; | 
 | 2563 |         } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2564 |     } | 
 | 2565 |  | 
| Martin v. Löwis | 49c5da1 | 2006-03-01 22:49:05 +0000 | [diff] [blame] | 2566 |     return Call(func, args, keywords, vararg, kwarg, func->lineno, func->col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2567 | } | 
 | 2568 |  | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2569 | static expr_ty | 
| Neil Schemenauer | c5dd10a | 2005-10-25 07:54:54 +0000 | [diff] [blame] | 2570 | ast_for_testlist(struct compiling *c, const node* n) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2571 | { | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 2572 |     /* testlist_comp: test (comp_for | (',' test)* [',']) */ | 
| Neil Schemenauer | c5dd10a | 2005-10-25 07:54:54 +0000 | [diff] [blame] | 2573 |     /* testlist: test (',' test)* [','] */ | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2574 |     assert(NCH(n) > 0); | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 2575 |     if (TYPE(n) == testlist_comp) { | 
| Neil Schemenauer | c5dd10a | 2005-10-25 07:54:54 +0000 | [diff] [blame] | 2576 |         if (NCH(n) > 1) | 
| Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 2577 |             assert(TYPE(CHILD(n, 1)) != comp_for); | 
| Neil Schemenauer | c5dd10a | 2005-10-25 07:54:54 +0000 | [diff] [blame] | 2578 |     } | 
 | 2579 |     else { | 
 | 2580 |         assert(TYPE(n) == testlist || | 
| Benjamin Peterson | 4905e80 | 2009-09-27 02:43:28 +0000 | [diff] [blame] | 2581 |                TYPE(n) == testlist_star_expr); | 
| Neil Schemenauer | c5dd10a | 2005-10-25 07:54:54 +0000 | [diff] [blame] | 2582 |     } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2583 |     if (NCH(n) == 1) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2584 |         return ast_for_expr(c, CHILD(n, 0)); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2585 |     else { | 
 | 2586 |         asdl_seq *tmp = seq_for_testlist(c, n); | 
 | 2587 |         if (!tmp) | 
 | 2588 |             return NULL; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2589 |         return Tuple(tmp, Load, LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2590 |     } | 
| Neil Schemenauer | c5dd10a | 2005-10-25 07:54:54 +0000 | [diff] [blame] | 2591 | } | 
 | 2592 |  | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2593 | static stmt_ty | 
 | 2594 | ast_for_expr_stmt(struct compiling *c, const node *n) | 
 | 2595 | { | 
 | 2596 |     REQ(n, expr_stmt); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 2597 |     /* expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2598 |                 | ('=' (yield_expr|testlist))*) | 
| Benjamin Peterson | 4905e80 | 2009-09-27 02:43:28 +0000 | [diff] [blame] | 2599 |        testlist_star_expr: (test|star_expr) (',' test|star_expr)* [','] | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2600 |        augassign: '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2601 |                 | '<<=' | '>>=' | '**=' | '//=' | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2602 |        test: ... here starts the operator precendence dance | 
 | 2603 |      */ | 
 | 2604 |  | 
 | 2605 |     if (NCH(n) == 1) { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2606 |         expr_ty e = ast_for_testlist(c, CHILD(n, 0)); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2607 |         if (!e) | 
 | 2608 |             return NULL; | 
 | 2609 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2610 |         return Expr(e, LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2611 |     } | 
 | 2612 |     else if (TYPE(CHILD(n, 1)) == augassign) { | 
 | 2613 |         expr_ty expr1, expr2; | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 2614 |         operator_ty newoperator; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2615 |         node *ch = CHILD(n, 0); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2616 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2617 |         expr1 = ast_for_testlist(c, ch); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2618 |         if (!expr1) | 
 | 2619 |             return NULL; | 
| Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 2620 |         if(!set_context(c, expr1, Store, ch)) | 
 | 2621 |             return NULL; | 
| Benjamin Peterson | bd27aef | 2009-10-03 20:27:13 +0000 | [diff] [blame] | 2622 |         /* set_context checks that most expressions are not the left side. | 
 | 2623 |           Augmented assignments can only have a name, a subscript, or an | 
 | 2624 |           attribute on the left, though, so we have to explicitly check for | 
 | 2625 |           those. */ | 
 | 2626 |         switch (expr1->kind) { | 
 | 2627 |             case Name_kind: | 
 | 2628 |             case Attribute_kind: | 
 | 2629 |             case Subscript_kind: | 
 | 2630 |                 break; | 
 | 2631 |             default: | 
 | 2632 |                 ast_error(ch, "illegal expression for augmented assignment"); | 
 | 2633 |                 return NULL; | 
 | 2634 |         } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2635 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2636 |         ch = CHILD(n, 2); | 
 | 2637 |         if (TYPE(ch) == testlist) | 
 | 2638 |             expr2 = ast_for_testlist(c, ch); | 
 | 2639 |         else | 
 | 2640 |             expr2 = ast_for_expr(c, ch); | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 2641 |         if (!expr2) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2642 |             return NULL; | 
 | 2643 |  | 
| Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 2644 |         newoperator = ast_for_augassign(c, CHILD(n, 1)); | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 2645 |         if (!newoperator) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2646 |             return NULL; | 
 | 2647 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2648 |         return AugAssign(expr1, newoperator, expr2, LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2649 |     } | 
 | 2650 |     else { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2651 |         int i; | 
 | 2652 |         asdl_seq *targets; | 
 | 2653 |         node *value; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2654 |         expr_ty expression; | 
 | 2655 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2656 |         /* a normal assignment */ | 
 | 2657 |         REQ(CHILD(n, 1), EQUAL); | 
 | 2658 |         targets = asdl_seq_new(NCH(n) / 2, c->c_arena); | 
 | 2659 |         if (!targets) | 
 | 2660 |             return NULL; | 
 | 2661 |         for (i = 0; i < NCH(n) - 2; i += 2) { | 
 | 2662 |             expr_ty e; | 
 | 2663 |             node *ch = CHILD(n, i); | 
 | 2664 |             if (TYPE(ch) == yield_expr) { | 
 | 2665 |                 ast_error(ch, "assignment to yield expression not possible"); | 
 | 2666 |                 return NULL; | 
 | 2667 |             } | 
 | 2668 |             e = ast_for_testlist(c, ch); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 2669 |             if (!e) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2670 |               return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2671 |  | 
| Amaury Forgeot d'Arc | 92dc80a | 2010-08-19 17:43:15 +0000 | [diff] [blame] | 2672 |             /* set context to assign */ | 
| Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 2673 |             if (!set_context(c, e, Store, CHILD(n, i))) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2674 |               return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2675 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2676 |             asdl_seq_SET(targets, i / 2, e); | 
 | 2677 |         } | 
 | 2678 |         value = CHILD(n, NCH(n) - 1); | 
| Benjamin Peterson | 4905e80 | 2009-09-27 02:43:28 +0000 | [diff] [blame] | 2679 |         if (TYPE(value) == testlist_star_expr) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2680 |             expression = ast_for_testlist(c, value); | 
 | 2681 |         else | 
 | 2682 |             expression = ast_for_expr(c, value); | 
 | 2683 |         if (!expression) | 
 | 2684 |             return NULL; | 
 | 2685 |         return Assign(targets, expression, LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2686 |     } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2687 | } | 
 | 2688 |  | 
| Benjamin Peterson | 78565b2 | 2009-06-28 19:19:51 +0000 | [diff] [blame] | 2689 |  | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2690 | static asdl_seq * | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 2691 | ast_for_exprlist(struct compiling *c, const node *n, expr_context_ty context) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2692 | { | 
 | 2693 |     asdl_seq *seq; | 
 | 2694 |     int i; | 
 | 2695 |     expr_ty e; | 
 | 2696 |  | 
 | 2697 |     REQ(n, exprlist); | 
 | 2698 |  | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 2699 |     seq = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2700 |     if (!seq) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2701 |         return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2702 |     for (i = 0; i < NCH(n); i += 2) { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2703 |         e = ast_for_expr(c, CHILD(n, i)); | 
 | 2704 |         if (!e) | 
 | 2705 |             return NULL; | 
 | 2706 |         asdl_seq_SET(seq, i / 2, e); | 
| Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 2707 |         if (context && !set_context(c, e, context, CHILD(n, i))) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2708 |             return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2709 |     } | 
 | 2710 |     return seq; | 
 | 2711 | } | 
 | 2712 |  | 
 | 2713 | static stmt_ty | 
 | 2714 | ast_for_del_stmt(struct compiling *c, const node *n) | 
 | 2715 | { | 
 | 2716 |     asdl_seq *expr_list; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 2717 |  | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2718 |     /* del_stmt: 'del' exprlist */ | 
 | 2719 |     REQ(n, del_stmt); | 
 | 2720 |  | 
 | 2721 |     expr_list = ast_for_exprlist(c, CHILD(n, 1), Del); | 
 | 2722 |     if (!expr_list) | 
 | 2723 |         return NULL; | 
| Martin v. Löwis | 49c5da1 | 2006-03-01 22:49:05 +0000 | [diff] [blame] | 2724 |     return Delete(expr_list, LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2725 | } | 
 | 2726 |  | 
 | 2727 | static stmt_ty | 
 | 2728 | ast_for_flow_stmt(struct compiling *c, const node *n) | 
 | 2729 | { | 
 | 2730 |     /* | 
 | 2731 |       flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | 
 | 2732 |                  | yield_stmt | 
 | 2733 |       break_stmt: 'break' | 
 | 2734 |       continue_stmt: 'continue' | 
 | 2735 |       return_stmt: 'return' [testlist] | 
 | 2736 |       yield_stmt: yield_expr | 
| Nick Coghlan | 1f7ce62 | 2012-01-13 21:43:40 +1000 | [diff] [blame] | 2737 |       yield_expr: 'yield' testlist | 'yield' 'from' test | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2738 |       raise_stmt: 'raise' [test [',' test [',' test]]] | 
 | 2739 |     */ | 
 | 2740 |     node *ch; | 
 | 2741 |  | 
 | 2742 |     REQ(n, flow_stmt); | 
 | 2743 |     ch = CHILD(n, 0); | 
 | 2744 |     switch (TYPE(ch)) { | 
 | 2745 |         case break_stmt: | 
| Martin v. Löwis | 49c5da1 | 2006-03-01 22:49:05 +0000 | [diff] [blame] | 2746 |             return Break(LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2747 |         case continue_stmt: | 
| Martin v. Löwis | 49c5da1 | 2006-03-01 22:49:05 +0000 | [diff] [blame] | 2748 |             return Continue(LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2749 |         case yield_stmt: { /* will reduce to yield_expr */ | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2750 |             expr_ty exp = ast_for_expr(c, CHILD(ch, 0)); | 
 | 2751 |             if (!exp) | 
 | 2752 |                 return NULL; | 
| Martin v. Löwis | 49c5da1 | 2006-03-01 22:49:05 +0000 | [diff] [blame] | 2753 |             return Expr(exp, LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2754 |         } | 
 | 2755 |         case return_stmt: | 
 | 2756 |             if (NCH(ch) == 1) | 
| Martin v. Löwis | 49c5da1 | 2006-03-01 22:49:05 +0000 | [diff] [blame] | 2757 |                 return Return(NULL, LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2758 |             else { | 
| Neil Schemenauer | c5dd10a | 2005-10-25 07:54:54 +0000 | [diff] [blame] | 2759 |                 expr_ty expression = ast_for_testlist(c, CHILD(ch, 1)); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2760 |                 if (!expression) | 
 | 2761 |                     return NULL; | 
| Martin v. Löwis | 49c5da1 | 2006-03-01 22:49:05 +0000 | [diff] [blame] | 2762 |                 return Return(expression, LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2763 |             } | 
 | 2764 |         case raise_stmt: | 
 | 2765 |             if (NCH(ch) == 1) | 
| Collin Winter | 828f04a | 2007-08-31 00:04:24 +0000 | [diff] [blame] | 2766 |                 return Raise(NULL, NULL, LINENO(n), n->n_col_offset, c->c_arena); | 
 | 2767 |             else if (NCH(ch) >= 2) { | 
 | 2768 |                 expr_ty cause = NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2769 |                 expr_ty expression = ast_for_expr(c, CHILD(ch, 1)); | 
 | 2770 |                 if (!expression) | 
 | 2771 |                     return NULL; | 
| Collin Winter | 828f04a | 2007-08-31 00:04:24 +0000 | [diff] [blame] | 2772 |                 if (NCH(ch) == 4) { | 
 | 2773 |                     cause = ast_for_expr(c, CHILD(ch, 3)); | 
 | 2774 |                     if (!cause) | 
 | 2775 |                         return NULL; | 
 | 2776 |                 } | 
 | 2777 |                 return Raise(expression, cause, LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2778 |             } | 
 | 2779 |         default: | 
| Neal Norwitz | 7979265 | 2005-11-14 04:25:03 +0000 | [diff] [blame] | 2780 |             PyErr_Format(PyExc_SystemError, | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2781 |                          "unexpected flow_stmt: %d", TYPE(ch)); | 
 | 2782 |             return NULL; | 
 | 2783 |     } | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 2784 |  | 
 | 2785 |     PyErr_SetString(PyExc_SystemError, "unhandled flow statement"); | 
 | 2786 |     return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2787 | } | 
 | 2788 |  | 
 | 2789 | static alias_ty | 
| Benjamin Peterson | 78565b2 | 2009-06-28 19:19:51 +0000 | [diff] [blame] | 2790 | alias_for_import_name(struct compiling *c, const node *n, int store) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2791 | { | 
 | 2792 |     /* | 
| Thomas Wouters | 8ae1295 | 2006-02-28 22:42:15 +0000 | [diff] [blame] | 2793 |       import_as_name: NAME ['as' NAME] | 
 | 2794 |       dotted_as_name: dotted_name ['as' NAME] | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2795 |       dotted_name: NAME ('.' NAME)* | 
 | 2796 |     */ | 
| Benjamin Peterson | 78565b2 | 2009-06-28 19:19:51 +0000 | [diff] [blame] | 2797 |     identifier str, name; | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 2798 |  | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2799 |  loop: | 
 | 2800 |     switch (TYPE(n)) { | 
| Benjamin Peterson | f63d615 | 2011-06-20 21:40:19 -0500 | [diff] [blame] | 2801 |         case import_as_name: { | 
| Benjamin Peterson | 78565b2 | 2009-06-28 19:19:51 +0000 | [diff] [blame] | 2802 |             node *name_node = CHILD(n, 0); | 
| Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 2803 |             str = NULL; | 
| Benjamin Peterson | 78565b2 | 2009-06-28 19:19:51 +0000 | [diff] [blame] | 2804 |             name = NEW_IDENTIFIER(name_node); | 
| Benjamin Peterson | 3076006 | 2008-11-25 04:02:28 +0000 | [diff] [blame] | 2805 |             if (!name) | 
 | 2806 |                 return NULL; | 
| Benjamin Peterson | 78565b2 | 2009-06-28 19:19:51 +0000 | [diff] [blame] | 2807 |             if (NCH(n) == 3) { | 
 | 2808 |                 node *str_node = CHILD(n, 2); | 
 | 2809 |                 str = NEW_IDENTIFIER(str_node); | 
 | 2810 |                 if (!str) | 
 | 2811 |                     return NULL; | 
| Benjamin Peterson | 70f5276 | 2009-06-28 23:32:44 +0000 | [diff] [blame] | 2812 |                 if (store && forbidden_name(str, str_node, 0)) | 
| Benjamin Peterson | 78565b2 | 2009-06-28 19:19:51 +0000 | [diff] [blame] | 2813 |                     return NULL; | 
 | 2814 |             } | 
 | 2815 |             else { | 
| Benjamin Peterson | 70f5276 | 2009-06-28 23:32:44 +0000 | [diff] [blame] | 2816 |                 if (forbidden_name(name, name_node, 0)) | 
| Benjamin Peterson | 78565b2 | 2009-06-28 19:19:51 +0000 | [diff] [blame] | 2817 |                     return NULL; | 
 | 2818 |             } | 
| Benjamin Peterson | 3076006 | 2008-11-25 04:02:28 +0000 | [diff] [blame] | 2819 |             return alias(name, str, c->c_arena); | 
| Benjamin Peterson | 78565b2 | 2009-06-28 19:19:51 +0000 | [diff] [blame] | 2820 |         } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2821 |         case dotted_as_name: | 
 | 2822 |             if (NCH(n) == 1) { | 
 | 2823 |                 n = CHILD(n, 0); | 
 | 2824 |                 goto loop; | 
 | 2825 |             } | 
 | 2826 |             else { | 
| Benjamin Peterson | 78565b2 | 2009-06-28 19:19:51 +0000 | [diff] [blame] | 2827 |                 node *asname_node = CHILD(n, 2); | 
 | 2828 |                 alias_ty a = alias_for_import_name(c, CHILD(n, 0), 0); | 
| Thomas Wouters | 00ee7ba | 2006-08-21 19:07:27 +0000 | [diff] [blame] | 2829 |                 if (!a) | 
 | 2830 |                     return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2831 |                 assert(!a->asname); | 
| Benjamin Peterson | 78565b2 | 2009-06-28 19:19:51 +0000 | [diff] [blame] | 2832 |                 a->asname = NEW_IDENTIFIER(asname_node); | 
| Benjamin Peterson | 3076006 | 2008-11-25 04:02:28 +0000 | [diff] [blame] | 2833 |                 if (!a->asname) | 
 | 2834 |                     return NULL; | 
| Benjamin Peterson | 70f5276 | 2009-06-28 23:32:44 +0000 | [diff] [blame] | 2835 |                 if (forbidden_name(a->asname, asname_node, 0)) | 
| Benjamin Peterson | 78565b2 | 2009-06-28 19:19:51 +0000 | [diff] [blame] | 2836 |                     return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2837 |                 return a; | 
 | 2838 |             } | 
 | 2839 |             break; | 
 | 2840 |         case dotted_name: | 
| Benjamin Peterson | 3076006 | 2008-11-25 04:02:28 +0000 | [diff] [blame] | 2841 |             if (NCH(n) == 1) { | 
| Benjamin Peterson | 78565b2 | 2009-06-28 19:19:51 +0000 | [diff] [blame] | 2842 |                 node *name_node = CHILD(n, 0); | 
 | 2843 |                 name = NEW_IDENTIFIER(name_node); | 
| Benjamin Peterson | 3076006 | 2008-11-25 04:02:28 +0000 | [diff] [blame] | 2844 |                 if (!name) | 
 | 2845 |                     return NULL; | 
| Benjamin Peterson | 70f5276 | 2009-06-28 23:32:44 +0000 | [diff] [blame] | 2846 |                 if (store && forbidden_name(name, name_node, 0)) | 
| Benjamin Peterson | 78565b2 | 2009-06-28 19:19:51 +0000 | [diff] [blame] | 2847 |                     return NULL; | 
| Benjamin Peterson | 3076006 | 2008-11-25 04:02:28 +0000 | [diff] [blame] | 2848 |                 return alias(name, NULL, c->c_arena); | 
 | 2849 |             } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2850 |             else { | 
 | 2851 |                 /* Create a string of the form "a.b.c" */ | 
| Tim Peters | e93e64f | 2006-01-08 02:28:41 +0000 | [diff] [blame] | 2852 |                 int i; | 
| Tim Peters | 5db42c4 | 2006-01-08 02:25:34 +0000 | [diff] [blame] | 2853 |                 size_t len; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2854 |                 char *s; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 2855 |                 PyObject *uni; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2856 |  | 
 | 2857 |                 len = 0; | 
 | 2858 |                 for (i = 0; i < NCH(n); i += 2) | 
 | 2859 |                     /* length of string plus one for the dot */ | 
 | 2860 |                     len += strlen(STR(CHILD(n, i))) + 1; | 
 | 2861 |                 len--; /* the last name doesn't have a dot */ | 
| Christian Heimes | 72b710a | 2008-05-26 13:28:38 +0000 | [diff] [blame] | 2862 |                 str = PyBytes_FromStringAndSize(NULL, len); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2863 |                 if (!str) | 
 | 2864 |                     return NULL; | 
| Christian Heimes | 72b710a | 2008-05-26 13:28:38 +0000 | [diff] [blame] | 2865 |                 s = PyBytes_AS_STRING(str); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2866 |                 if (!s) | 
 | 2867 |                     return NULL; | 
 | 2868 |                 for (i = 0; i < NCH(n); i += 2) { | 
 | 2869 |                     char *sch = STR(CHILD(n, i)); | 
 | 2870 |                     strcpy(s, STR(CHILD(n, i))); | 
 | 2871 |                     s += strlen(sch); | 
 | 2872 |                     *s++ = '.'; | 
 | 2873 |                 } | 
 | 2874 |                 --s; | 
 | 2875 |                 *s = '\0'; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 2876 |                 uni = PyUnicode_DecodeUTF8(PyBytes_AS_STRING(str), | 
 | 2877 |                                            PyBytes_GET_SIZE(str), | 
 | 2878 |                                            NULL); | 
 | 2879 |                 Py_DECREF(str); | 
 | 2880 |                 if (!uni) | 
 | 2881 |                     return NULL; | 
 | 2882 |                 str = uni; | 
| Martin v. Löwis | 5b22213 | 2007-06-10 09:51:05 +0000 | [diff] [blame] | 2883 |                 PyUnicode_InternInPlace(&str); | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2884 |                 PyArena_AddPyObject(c->c_arena, str); | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 2885 |                 return alias(str, NULL, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2886 |             } | 
 | 2887 |             break; | 
 | 2888 |         case STAR: | 
| Martin v. Löwis | 5b22213 | 2007-06-10 09:51:05 +0000 | [diff] [blame] | 2889 |             str = PyUnicode_InternFromString("*"); | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2890 |             PyArena_AddPyObject(c->c_arena, str); | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 2891 |             return alias(str, NULL, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2892 |         default: | 
| Neal Norwitz | 7979265 | 2005-11-14 04:25:03 +0000 | [diff] [blame] | 2893 |             PyErr_Format(PyExc_SystemError, | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2894 |                          "unexpected import name: %d", TYPE(n)); | 
 | 2895 |             return NULL; | 
 | 2896 |     } | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 2897 |  | 
 | 2898 |     PyErr_SetString(PyExc_SystemError, "unhandled import name condition"); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2899 |     return NULL; | 
 | 2900 | } | 
 | 2901 |  | 
 | 2902 | static stmt_ty | 
 | 2903 | ast_for_import_stmt(struct compiling *c, const node *n) | 
 | 2904 | { | 
 | 2905 |     /* | 
 | 2906 |       import_stmt: import_name | import_from | 
 | 2907 |       import_name: 'import' dotted_as_names | 
| Georg Brandl | e66c8c7 | 2007-03-19 18:56:50 +0000 | [diff] [blame] | 2908 |       import_from: 'from' (('.' | '...')* dotted_name | ('.' | '...')+) | 
 | 2909 |                    'import' ('*' | '(' import_as_names ')' | import_as_names) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2910 |     */ | 
| Martin v. Löwis | 49c5da1 | 2006-03-01 22:49:05 +0000 | [diff] [blame] | 2911 |     int lineno; | 
 | 2912 |     int col_offset; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2913 |     int i; | 
 | 2914 |     asdl_seq *aliases; | 
 | 2915 |  | 
 | 2916 |     REQ(n, import_stmt); | 
| Martin v. Löwis | 49c5da1 | 2006-03-01 22:49:05 +0000 | [diff] [blame] | 2917 |     lineno = LINENO(n); | 
 | 2918 |     col_offset = n->n_col_offset; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2919 |     n = CHILD(n, 0); | 
| Thomas Wouters | 8622e93 | 2006-02-27 17:14:45 +0000 | [diff] [blame] | 2920 |     if (TYPE(n) == import_name) { | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2921 |         n = CHILD(n, 1); | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2922 |         REQ(n, dotted_as_names); | 
 | 2923 |         aliases = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena); | 
 | 2924 |         if (!aliases) | 
 | 2925 |                 return NULL; | 
 | 2926 |         for (i = 0; i < NCH(n); i += 2) { | 
| Benjamin Peterson | 78565b2 | 2009-06-28 19:19:51 +0000 | [diff] [blame] | 2927 |             alias_ty import_alias = alias_for_import_name(c, CHILD(n, i), 1); | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 2928 |             if (!import_alias) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2929 |                 return NULL; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2930 |             asdl_seq_SET(aliases, i / 2, import_alias); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2931 |         } | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2932 |         return Import(aliases, lineno, col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2933 |     } | 
| Thomas Wouters | 8622e93 | 2006-02-27 17:14:45 +0000 | [diff] [blame] | 2934 |     else if (TYPE(n) == import_from) { | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2935 |         int n_children; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2936 |         int idx, ndots = 0; | 
 | 2937 |         alias_ty mod = NULL; | 
| Benjamin Peterson | 78565b2 | 2009-06-28 19:19:51 +0000 | [diff] [blame] | 2938 |         identifier modname = NULL; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 2939 |  | 
| Thomas Wouters | f7f438b | 2006-02-28 16:09:29 +0000 | [diff] [blame] | 2940 |        /* Count the number of dots (for relative imports) and check for the | 
 | 2941 |           optional module name */ | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2942 |         for (idx = 1; idx < NCH(n); idx++) { | 
 | 2943 |             if (TYPE(CHILD(n, idx)) == dotted_name) { | 
| Benjamin Peterson | 78565b2 | 2009-06-28 19:19:51 +0000 | [diff] [blame] | 2944 |                 mod = alias_for_import_name(c, CHILD(n, idx), 0); | 
 | 2945 |                 if (!mod) | 
 | 2946 |                     return NULL; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2947 |                 idx++; | 
 | 2948 |                 break; | 
| Georg Brandl | e66c8c7 | 2007-03-19 18:56:50 +0000 | [diff] [blame] | 2949 |             } else if (TYPE(CHILD(n, idx)) == ELLIPSIS) { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 2950 |                 /* three consecutive dots are tokenized as one ELLIPSIS */ | 
| Georg Brandl | e66c8c7 | 2007-03-19 18:56:50 +0000 | [diff] [blame] | 2951 |                 ndots += 3; | 
 | 2952 |                 continue; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2953 |             } else if (TYPE(CHILD(n, idx)) != DOT) { | 
 | 2954 |                 break; | 
 | 2955 |             } | 
 | 2956 |             ndots++; | 
 | 2957 |         } | 
 | 2958 |         idx++; /* skip over the 'import' keyword */ | 
| Thomas Wouters | f7f438b | 2006-02-28 16:09:29 +0000 | [diff] [blame] | 2959 |         switch (TYPE(CHILD(n, idx))) { | 
| Thomas Wouters | 106203c | 2006-02-27 17:05:19 +0000 | [diff] [blame] | 2960 |         case STAR: | 
 | 2961 |             /* from ... import * */ | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2962 |             n = CHILD(n, idx); | 
 | 2963 |             n_children = 1; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2964 |             break; | 
 | 2965 |         case LPAR: | 
 | 2966 |             /* from ... import (x, y, z) */ | 
 | 2967 |             n = CHILD(n, idx + 1); | 
 | 2968 |             n_children = NCH(n); | 
 | 2969 |             break; | 
 | 2970 |         case import_as_names: | 
 | 2971 |             /* from ... import x, y, z */ | 
 | 2972 |             n = CHILD(n, idx); | 
 | 2973 |             n_children = NCH(n); | 
| Thomas Wouters | 106203c | 2006-02-27 17:05:19 +0000 | [diff] [blame] | 2974 |             if (n_children % 2 == 0) { | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2975 |                 ast_error(n, "trailing comma not allowed without" | 
 | 2976 |                              " surrounding parentheses"); | 
 | 2977 |                 return NULL; | 
 | 2978 |             } | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2979 |             break; | 
 | 2980 |         default: | 
 | 2981 |             ast_error(n, "Unexpected node-type in from-import"); | 
 | 2982 |             return NULL; | 
 | 2983 |         } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2984 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2985 |         aliases = asdl_seq_new((n_children + 1) / 2, c->c_arena); | 
 | 2986 |         if (!aliases) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2987 |             return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2988 |  | 
 | 2989 |         /* handle "from ... import *" special b/c there's no children */ | 
| Thomas Wouters | 106203c | 2006-02-27 17:05:19 +0000 | [diff] [blame] | 2990 |         if (TYPE(n) == STAR) { | 
| Benjamin Peterson | 78565b2 | 2009-06-28 19:19:51 +0000 | [diff] [blame] | 2991 |             alias_ty import_alias = alias_for_import_name(c, n, 1); | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 2992 |             if (!import_alias) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2993 |                 return NULL; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2994 |                 asdl_seq_SET(aliases, 0, import_alias); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 2995 |         } | 
| Jeremy Hylton | a829313 | 2006-02-28 17:58:27 +0000 | [diff] [blame] | 2996 |         else { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 2997 |             for (i = 0; i < NCH(n); i += 2) { | 
| Benjamin Peterson | 78565b2 | 2009-06-28 19:19:51 +0000 | [diff] [blame] | 2998 |                 alias_ty import_alias = alias_for_import_name(c, CHILD(n, i), 1); | 
| Jeremy Hylton | a829313 | 2006-02-28 17:58:27 +0000 | [diff] [blame] | 2999 |                 if (!import_alias) | 
 | 3000 |                     return NULL; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3001 |                     asdl_seq_SET(aliases, i / 2, import_alias); | 
| Jeremy Hylton | a829313 | 2006-02-28 17:58:27 +0000 | [diff] [blame] | 3002 |             } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3003 |         } | 
| Thomas Wouters | f7f438b | 2006-02-28 16:09:29 +0000 | [diff] [blame] | 3004 |         if (mod != NULL) | 
 | 3005 |             modname = mod->name; | 
| Martin v. Löwis | 49c5da1 | 2006-03-01 22:49:05 +0000 | [diff] [blame] | 3006 |         return ImportFrom(modname, aliases, ndots, lineno, col_offset, | 
| Thomas Wouters | f7f438b | 2006-02-28 16:09:29 +0000 | [diff] [blame] | 3007 |                           c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3008 |     } | 
| Neal Norwitz | 7979265 | 2005-11-14 04:25:03 +0000 | [diff] [blame] | 3009 |     PyErr_Format(PyExc_SystemError, | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3010 |                  "unknown import statement: starts with command '%s'", | 
 | 3011 |                  STR(CHILD(n, 0))); | 
 | 3012 |     return NULL; | 
 | 3013 | } | 
 | 3014 |  | 
 | 3015 | static stmt_ty | 
 | 3016 | ast_for_global_stmt(struct compiling *c, const node *n) | 
 | 3017 | { | 
 | 3018 |     /* global_stmt: 'global' NAME (',' NAME)* */ | 
 | 3019 |     identifier name; | 
 | 3020 |     asdl_seq *s; | 
 | 3021 |     int i; | 
 | 3022 |  | 
 | 3023 |     REQ(n, global_stmt); | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 3024 |     s = asdl_seq_new(NCH(n) / 2, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3025 |     if (!s) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3026 |         return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3027 |     for (i = 1; i < NCH(n); i += 2) { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3028 |         name = NEW_IDENTIFIER(CHILD(n, i)); | 
 | 3029 |         if (!name) | 
 | 3030 |             return NULL; | 
 | 3031 |         asdl_seq_SET(s, i / 2, name); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3032 |     } | 
| Martin v. Löwis | 49c5da1 | 2006-03-01 22:49:05 +0000 | [diff] [blame] | 3033 |     return Global(s, LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3034 | } | 
 | 3035 |  | 
 | 3036 | static stmt_ty | 
| Jeremy Hylton | 81e9502 | 2007-02-27 06:50:52 +0000 | [diff] [blame] | 3037 | ast_for_nonlocal_stmt(struct compiling *c, const node *n) | 
 | 3038 | { | 
 | 3039 |     /* nonlocal_stmt: 'nonlocal' NAME (',' NAME)* */ | 
 | 3040 |     identifier name; | 
 | 3041 |     asdl_seq *s; | 
 | 3042 |     int i; | 
 | 3043 |  | 
 | 3044 |     REQ(n, nonlocal_stmt); | 
 | 3045 |     s = asdl_seq_new(NCH(n) / 2, c->c_arena); | 
 | 3046 |     if (!s) | 
 | 3047 |         return NULL; | 
 | 3048 |     for (i = 1; i < NCH(n); i += 2) { | 
 | 3049 |         name = NEW_IDENTIFIER(CHILD(n, i)); | 
 | 3050 |         if (!name) | 
 | 3051 |             return NULL; | 
 | 3052 |         asdl_seq_SET(s, i / 2, name); | 
 | 3053 |     } | 
 | 3054 |     return Nonlocal(s, LINENO(n), n->n_col_offset, c->c_arena); | 
 | 3055 | } | 
 | 3056 |  | 
 | 3057 | static stmt_ty | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3058 | ast_for_assert_stmt(struct compiling *c, const node *n) | 
 | 3059 | { | 
 | 3060 |     /* assert_stmt: 'assert' test [',' test] */ | 
 | 3061 |     REQ(n, assert_stmt); | 
 | 3062 |     if (NCH(n) == 2) { | 
 | 3063 |         expr_ty expression = ast_for_expr(c, CHILD(n, 1)); | 
 | 3064 |         if (!expression) | 
 | 3065 |             return NULL; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3066 |         return Assert(expression, NULL, LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3067 |     } | 
 | 3068 |     else if (NCH(n) == 4) { | 
 | 3069 |         expr_ty expr1, expr2; | 
 | 3070 |  | 
 | 3071 |         expr1 = ast_for_expr(c, CHILD(n, 1)); | 
 | 3072 |         if (!expr1) | 
 | 3073 |             return NULL; | 
 | 3074 |         expr2 = ast_for_expr(c, CHILD(n, 3)); | 
 | 3075 |         if (!expr2) | 
 | 3076 |             return NULL; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 3077 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3078 |         return Assert(expr1, expr2, LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3079 |     } | 
| Neal Norwitz | 7979265 | 2005-11-14 04:25:03 +0000 | [diff] [blame] | 3080 |     PyErr_Format(PyExc_SystemError, | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3081 |                  "improper number of parts to 'assert' statement: %d", | 
 | 3082 |                  NCH(n)); | 
 | 3083 |     return NULL; | 
 | 3084 | } | 
 | 3085 |  | 
 | 3086 | static asdl_seq * | 
 | 3087 | ast_for_suite(struct compiling *c, const node *n) | 
 | 3088 | { | 
 | 3089 |     /* suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT */ | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 3090 |     asdl_seq *seq; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3091 |     stmt_ty s; | 
 | 3092 |     int i, total, num, end, pos = 0; | 
 | 3093 |     node *ch; | 
 | 3094 |  | 
 | 3095 |     REQ(n, suite); | 
 | 3096 |  | 
 | 3097 |     total = num_stmts(n); | 
| Neal Norwitz | adb69fc | 2005-12-17 20:54:49 +0000 | [diff] [blame] | 3098 |     seq = asdl_seq_new(total, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3099 |     if (!seq) | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3100 |         return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3101 |     if (TYPE(CHILD(n, 0)) == simple_stmt) { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3102 |         n = CHILD(n, 0); | 
 | 3103 |         /* simple_stmt always ends with a NEWLINE, | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 3104 |            and may have a trailing SEMI | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3105 |         */ | 
 | 3106 |         end = NCH(n) - 1; | 
 | 3107 |         if (TYPE(CHILD(n, end - 1)) == SEMI) | 
 | 3108 |             end--; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3109 |         /* loop by 2 to skip semi-colons */ | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3110 |         for (i = 0; i < end; i += 2) { | 
 | 3111 |             ch = CHILD(n, i); | 
 | 3112 |             s = ast_for_stmt(c, ch); | 
 | 3113 |             if (!s) | 
 | 3114 |                 return NULL; | 
 | 3115 |             asdl_seq_SET(seq, pos++, s); | 
 | 3116 |         } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3117 |     } | 
 | 3118 |     else { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3119 |         for (i = 2; i < (NCH(n) - 1); i++) { | 
 | 3120 |             ch = CHILD(n, i); | 
 | 3121 |             REQ(ch, stmt); | 
 | 3122 |             num = num_stmts(ch); | 
 | 3123 |             if (num == 1) { | 
 | 3124 |                 /* small_stmt or compound_stmt with only one child */ | 
 | 3125 |                 s = ast_for_stmt(c, ch); | 
 | 3126 |                 if (!s) | 
 | 3127 |                     return NULL; | 
 | 3128 |                 asdl_seq_SET(seq, pos++, s); | 
 | 3129 |             } | 
 | 3130 |             else { | 
 | 3131 |                 int j; | 
 | 3132 |                 ch = CHILD(ch, 0); | 
 | 3133 |                 REQ(ch, simple_stmt); | 
 | 3134 |                 for (j = 0; j < NCH(ch); j += 2) { | 
 | 3135 |                     /* statement terminates with a semi-colon ';' */ | 
 | 3136 |                     if (NCH(CHILD(ch, j)) == 0) { | 
 | 3137 |                         assert((j + 1) == NCH(ch)); | 
 | 3138 |                         break; | 
 | 3139 |                     } | 
 | 3140 |                     s = ast_for_stmt(c, CHILD(ch, j)); | 
 | 3141 |                     if (!s) | 
 | 3142 |                         return NULL; | 
 | 3143 |                     asdl_seq_SET(seq, pos++, s); | 
 | 3144 |                 } | 
 | 3145 |             } | 
 | 3146 |         } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3147 |     } | 
 | 3148 |     assert(pos == seq->size); | 
 | 3149 |     return seq; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3150 | } | 
 | 3151 |  | 
 | 3152 | static stmt_ty | 
 | 3153 | ast_for_if_stmt(struct compiling *c, const node *n) | 
 | 3154 | { | 
 | 3155 |     /* if_stmt: 'if' test ':' suite ('elif' test ':' suite)* | 
 | 3156 |        ['else' ':' suite] | 
 | 3157 |     */ | 
 | 3158 |     char *s; | 
 | 3159 |  | 
 | 3160 |     REQ(n, if_stmt); | 
 | 3161 |  | 
 | 3162 |     if (NCH(n) == 4) { | 
 | 3163 |         expr_ty expression; | 
 | 3164 |         asdl_seq *suite_seq; | 
 | 3165 |  | 
 | 3166 |         expression = ast_for_expr(c, CHILD(n, 1)); | 
 | 3167 |         if (!expression) | 
 | 3168 |             return NULL; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 3169 |         suite_seq = ast_for_suite(c, CHILD(n, 3)); | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 3170 |         if (!suite_seq) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3171 |             return NULL; | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 3172 |  | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3173 |         return If(expression, suite_seq, NULL, LINENO(n), n->n_col_offset, | 
 | 3174 |                   c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3175 |     } | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 3176 |  | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3177 |     s = STR(CHILD(n, 4)); | 
 | 3178 |     /* s[2], the third character in the string, will be | 
 | 3179 |        's' for el_s_e, or | 
 | 3180 |        'i' for el_i_f | 
 | 3181 |     */ | 
 | 3182 |     if (s[2] == 's') { | 
 | 3183 |         expr_ty expression; | 
 | 3184 |         asdl_seq *seq1, *seq2; | 
 | 3185 |  | 
 | 3186 |         expression = ast_for_expr(c, CHILD(n, 1)); | 
 | 3187 |         if (!expression) | 
 | 3188 |             return NULL; | 
 | 3189 |         seq1 = ast_for_suite(c, CHILD(n, 3)); | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 3190 |         if (!seq1) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3191 |             return NULL; | 
 | 3192 |         seq2 = ast_for_suite(c, CHILD(n, 6)); | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 3193 |         if (!seq2) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3194 |             return NULL; | 
 | 3195 |  | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3196 |         return If(expression, seq1, seq2, LINENO(n), n->n_col_offset, | 
 | 3197 |                   c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3198 |     } | 
 | 3199 |     else if (s[2] == 'i') { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3200 |         int i, n_elif, has_else = 0; | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3201 |         expr_ty expression; | 
 | 3202 |         asdl_seq *suite_seq; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3203 |         asdl_seq *orelse = NULL; | 
 | 3204 |         n_elif = NCH(n) - 4; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3205 |         /* must reference the child n_elif+1 since 'else' token is third, | 
 | 3206 |            not fourth, child from the end. */ | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3207 |         if (TYPE(CHILD(n, (n_elif + 1))) == NAME | 
 | 3208 |             && STR(CHILD(n, (n_elif + 1)))[2] == 's') { | 
 | 3209 |             has_else = 1; | 
 | 3210 |             n_elif -= 3; | 
 | 3211 |         } | 
 | 3212 |         n_elif /= 4; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3213 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3214 |         if (has_else) { | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3215 |             asdl_seq *suite_seq2; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3216 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3217 |             orelse = asdl_seq_new(1, c->c_arena); | 
 | 3218 |             if (!orelse) | 
 | 3219 |                 return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3220 |             expression = ast_for_expr(c, CHILD(n, NCH(n) - 6)); | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 3221 |             if (!expression) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3222 |                 return NULL; | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3223 |             suite_seq = ast_for_suite(c, CHILD(n, NCH(n) - 4)); | 
 | 3224 |             if (!suite_seq) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3225 |                 return NULL; | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3226 |             suite_seq2 = ast_for_suite(c, CHILD(n, NCH(n) - 1)); | 
 | 3227 |             if (!suite_seq2) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3228 |                 return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3229 |  | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 3230 |             asdl_seq_SET(orelse, 0, | 
 | 3231 |                          If(expression, suite_seq, suite_seq2, | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3232 |                             LINENO(CHILD(n, NCH(n) - 6)), | 
 | 3233 |                             CHILD(n, NCH(n) - 6)->n_col_offset, | 
 | 3234 |                             c->c_arena)); | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3235 |             /* the just-created orelse handled the last elif */ | 
 | 3236 |             n_elif--; | 
 | 3237 |         } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3238 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3239 |         for (i = 0; i < n_elif; i++) { | 
 | 3240 |             int off = 5 + (n_elif - i - 1) * 4; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3241 |             asdl_seq *newobj = asdl_seq_new(1, c->c_arena); | 
 | 3242 |             if (!newobj) | 
 | 3243 |                 return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3244 |             expression = ast_for_expr(c, CHILD(n, off)); | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 3245 |             if (!expression) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3246 |                 return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3247 |             suite_seq = ast_for_suite(c, CHILD(n, off + 2)); | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 3248 |             if (!suite_seq) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3249 |                 return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3250 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3251 |             asdl_seq_SET(newobj, 0, | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 3252 |                          If(expression, suite_seq, orelse, | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3253 |                             LINENO(CHILD(n, off)), | 
 | 3254 |                             CHILD(n, off)->n_col_offset, c->c_arena)); | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3255 |             orelse = newobj; | 
 | 3256 |         } | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3257 |         expression = ast_for_expr(c, CHILD(n, 1)); | 
 | 3258 |         if (!expression) | 
 | 3259 |             return NULL; | 
 | 3260 |         suite_seq = ast_for_suite(c, CHILD(n, 3)); | 
 | 3261 |         if (!suite_seq) | 
 | 3262 |             return NULL; | 
 | 3263 |         return If(expression, suite_seq, orelse, | 
 | 3264 |                   LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3265 |     } | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 3266 |  | 
 | 3267 |     PyErr_Format(PyExc_SystemError, | 
 | 3268 |                  "unexpected token in 'if' statement: %s", s); | 
 | 3269 |     return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3270 | } | 
 | 3271 |  | 
 | 3272 | static stmt_ty | 
 | 3273 | ast_for_while_stmt(struct compiling *c, const node *n) | 
 | 3274 | { | 
 | 3275 |     /* while_stmt: 'while' test ':' suite ['else' ':' suite] */ | 
 | 3276 |     REQ(n, while_stmt); | 
 | 3277 |  | 
 | 3278 |     if (NCH(n) == 4) { | 
 | 3279 |         expr_ty expression; | 
 | 3280 |         asdl_seq *suite_seq; | 
 | 3281 |  | 
 | 3282 |         expression = ast_for_expr(c, CHILD(n, 1)); | 
 | 3283 |         if (!expression) | 
 | 3284 |             return NULL; | 
 | 3285 |         suite_seq = ast_for_suite(c, CHILD(n, 3)); | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 3286 |         if (!suite_seq) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3287 |             return NULL; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3288 |         return While(expression, suite_seq, NULL, LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3289 |     } | 
 | 3290 |     else if (NCH(n) == 7) { | 
 | 3291 |         expr_ty expression; | 
 | 3292 |         asdl_seq *seq1, *seq2; | 
 | 3293 |  | 
 | 3294 |         expression = ast_for_expr(c, CHILD(n, 1)); | 
 | 3295 |         if (!expression) | 
 | 3296 |             return NULL; | 
 | 3297 |         seq1 = ast_for_suite(c, CHILD(n, 3)); | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 3298 |         if (!seq1) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3299 |             return NULL; | 
 | 3300 |         seq2 = ast_for_suite(c, CHILD(n, 6)); | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 3301 |         if (!seq2) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3302 |             return NULL; | 
 | 3303 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3304 |         return While(expression, seq1, seq2, LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3305 |     } | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 3306 |  | 
 | 3307 |     PyErr_Format(PyExc_SystemError, | 
 | 3308 |                  "wrong number of tokens for 'while' statement: %d", | 
 | 3309 |                  NCH(n)); | 
 | 3310 |     return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3311 | } | 
 | 3312 |  | 
 | 3313 | static stmt_ty | 
 | 3314 | ast_for_for_stmt(struct compiling *c, const node *n) | 
 | 3315 | { | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 3316 |     asdl_seq *_target, *seq = NULL, *suite_seq; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3317 |     expr_ty expression; | 
| Benjamin Peterson | 2e4b0e1 | 2009-09-11 22:36:20 +0000 | [diff] [blame] | 3318 |     expr_ty target, first; | 
| Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 3319 |     const node *node_target; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3320 |     /* for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite] */ | 
 | 3321 |     REQ(n, for_stmt); | 
 | 3322 |  | 
 | 3323 |     if (NCH(n) == 9) { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3324 |         seq = ast_for_suite(c, CHILD(n, 8)); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3325 |         if (!seq) | 
 | 3326 |             return NULL; | 
 | 3327 |     } | 
 | 3328 |  | 
| Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 3329 |     node_target = CHILD(n, 1); | 
 | 3330 |     _target = ast_for_exprlist(c, node_target, Store); | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 3331 |     if (!_target) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3332 |         return NULL; | 
| Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 3333 |     /* Check the # of children rather than the length of _target, since | 
 | 3334 |        for x, in ... has 1 element in _target, but still requires a Tuple. */ | 
| Benjamin Peterson | 2e4b0e1 | 2009-09-11 22:36:20 +0000 | [diff] [blame] | 3335 |     first = (expr_ty)asdl_seq_GET(_target, 0); | 
| Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 3336 |     if (NCH(node_target) == 1) | 
| Benjamin Peterson | 2e4b0e1 | 2009-09-11 22:36:20 +0000 | [diff] [blame] | 3337 |         target = first; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3338 |     else | 
| Benjamin Peterson | 2e4b0e1 | 2009-09-11 22:36:20 +0000 | [diff] [blame] | 3339 |         target = Tuple(_target, Store, first->lineno, first->col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3340 |  | 
| Neil Schemenauer | c5dd10a | 2005-10-25 07:54:54 +0000 | [diff] [blame] | 3341 |     expression = ast_for_testlist(c, CHILD(n, 3)); | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 3342 |     if (!expression) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3343 |         return NULL; | 
 | 3344 |     suite_seq = ast_for_suite(c, CHILD(n, 5)); | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 3345 |     if (!suite_seq) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3346 |         return NULL; | 
 | 3347 |  | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 3348 |     return For(target, expression, suite_seq, seq, LINENO(n), n->n_col_offset, | 
 | 3349 |                c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3350 | } | 
 | 3351 |  | 
 | 3352 | static excepthandler_ty | 
 | 3353 | ast_for_except_clause(struct compiling *c, const node *exc, node *body) | 
 | 3354 | { | 
| Guido van Rossum | d59da4b | 2007-05-22 18:11:13 +0000 | [diff] [blame] | 3355 |     /* except_clause: 'except' [test ['as' test]] */ | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3356 |     REQ(exc, except_clause); | 
 | 3357 |     REQ(body, suite); | 
 | 3358 |  | 
 | 3359 |     if (NCH(exc) == 1) { | 
 | 3360 |         asdl_seq *suite_seq = ast_for_suite(c, body); | 
 | 3361 |         if (!suite_seq) | 
 | 3362 |             return NULL; | 
 | 3363 |  | 
| Neal Norwitz | ad74aa8 | 2008-03-31 05:14:30 +0000 | [diff] [blame] | 3364 |         return ExceptHandler(NULL, NULL, suite_seq, LINENO(exc), | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 3365 |                              exc->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3366 |     } | 
 | 3367 |     else if (NCH(exc) == 2) { | 
 | 3368 |         expr_ty expression; | 
 | 3369 |         asdl_seq *suite_seq; | 
 | 3370 |  | 
 | 3371 |         expression = ast_for_expr(c, CHILD(exc, 1)); | 
 | 3372 |         if (!expression) | 
 | 3373 |             return NULL; | 
 | 3374 |         suite_seq = ast_for_suite(c, body); | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 3375 |         if (!suite_seq) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3376 |             return NULL; | 
 | 3377 |  | 
| Neal Norwitz | ad74aa8 | 2008-03-31 05:14:30 +0000 | [diff] [blame] | 3378 |         return ExceptHandler(expression, NULL, suite_seq, LINENO(exc), | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 3379 |                              exc->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3380 |     } | 
 | 3381 |     else if (NCH(exc) == 4) { | 
 | 3382 |         asdl_seq *suite_seq; | 
 | 3383 |         expr_ty expression; | 
| Guido van Rossum | 16be03e | 2007-01-10 18:51:35 +0000 | [diff] [blame] | 3384 |         identifier e = NEW_IDENTIFIER(CHILD(exc, 3)); | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3385 |         if (!e) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3386 |             return NULL; | 
| Benjamin Peterson | 70f5276 | 2009-06-28 23:32:44 +0000 | [diff] [blame] | 3387 |         if (forbidden_name(e, CHILD(exc, 3), 0)) | 
 | 3388 |             return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3389 |         expression = ast_for_expr(c, CHILD(exc, 1)); | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 3390 |         if (!expression) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3391 |             return NULL; | 
 | 3392 |         suite_seq = ast_for_suite(c, body); | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 3393 |         if (!suite_seq) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3394 |             return NULL; | 
 | 3395 |  | 
| Neal Norwitz | ad74aa8 | 2008-03-31 05:14:30 +0000 | [diff] [blame] | 3396 |         return ExceptHandler(expression, e, suite_seq, LINENO(exc), | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 3397 |                              exc->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3398 |     } | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 3399 |  | 
 | 3400 |     PyErr_Format(PyExc_SystemError, | 
 | 3401 |                  "wrong number of children for 'except' clause: %d", | 
 | 3402 |                  NCH(exc)); | 
 | 3403 |     return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3404 | } | 
 | 3405 |  | 
 | 3406 | static stmt_ty | 
 | 3407 | ast_for_try_stmt(struct compiling *c, const node *n) | 
 | 3408 | { | 
| Neal Norwitz | f599f42 | 2005-12-17 21:33:47 +0000 | [diff] [blame] | 3409 |     const int nch = NCH(n); | 
 | 3410 |     int n_except = (nch - 3)/3; | 
| Benjamin Peterson | 43af12b | 2011-05-29 11:43:10 -0500 | [diff] [blame] | 3411 |     asdl_seq *body, *handlers = NULL, *orelse = NULL, *finally = NULL; | 
| Neal Norwitz | f599f42 | 2005-12-17 21:33:47 +0000 | [diff] [blame] | 3412 |  | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3413 |     REQ(n, try_stmt); | 
 | 3414 |  | 
| Neal Norwitz | f599f42 | 2005-12-17 21:33:47 +0000 | [diff] [blame] | 3415 |     body = ast_for_suite(c, CHILD(n, 2)); | 
 | 3416 |     if (body == NULL) | 
 | 3417 |         return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3418 |  | 
| Neal Norwitz | f599f42 | 2005-12-17 21:33:47 +0000 | [diff] [blame] | 3419 |     if (TYPE(CHILD(n, nch - 3)) == NAME) { | 
 | 3420 |         if (strcmp(STR(CHILD(n, nch - 3)), "finally") == 0) { | 
 | 3421 |             if (nch >= 9 && TYPE(CHILD(n, nch - 6)) == NAME) { | 
 | 3422 |                 /* we can assume it's an "else", | 
 | 3423 |                    because nch >= 9 for try-else-finally and | 
 | 3424 |                    it would otherwise have a type of except_clause */ | 
 | 3425 |                 orelse = ast_for_suite(c, CHILD(n, nch - 4)); | 
 | 3426 |                 if (orelse == NULL) | 
 | 3427 |                     return NULL; | 
 | 3428 |                 n_except--; | 
 | 3429 |             } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3430 |  | 
| Neal Norwitz | f599f42 | 2005-12-17 21:33:47 +0000 | [diff] [blame] | 3431 |             finally = ast_for_suite(c, CHILD(n, nch - 1)); | 
 | 3432 |             if (finally == NULL) | 
 | 3433 |                 return NULL; | 
 | 3434 |             n_except--; | 
 | 3435 |         } | 
 | 3436 |         else { | 
 | 3437 |             /* we can assume it's an "else", | 
 | 3438 |                otherwise it would have a type of except_clause */ | 
 | 3439 |             orelse = ast_for_suite(c, CHILD(n, nch - 1)); | 
 | 3440 |             if (orelse == NULL) | 
 | 3441 |                 return NULL; | 
 | 3442 |             n_except--; | 
 | 3443 |         } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3444 |     } | 
| Neal Norwitz | f599f42 | 2005-12-17 21:33:47 +0000 | [diff] [blame] | 3445 |     else if (TYPE(CHILD(n, nch - 3)) != except_clause) { | 
| Neal Norwitz | 7b3d5e1 | 2005-11-13 21:17:28 +0000 | [diff] [blame] | 3446 |         ast_error(n, "malformed 'try' statement"); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3447 |         return NULL; | 
 | 3448 |     } | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 3449 |  | 
| Neal Norwitz | f599f42 | 2005-12-17 21:33:47 +0000 | [diff] [blame] | 3450 |     if (n_except > 0) { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3451 |         int i; | 
| Neal Norwitz | f599f42 | 2005-12-17 21:33:47 +0000 | [diff] [blame] | 3452 |         /* process except statements to create a try ... except */ | 
| Benjamin Peterson | 43af12b | 2011-05-29 11:43:10 -0500 | [diff] [blame] | 3453 |         handlers = asdl_seq_new(n_except, c->c_arena); | 
| Neal Norwitz | f599f42 | 2005-12-17 21:33:47 +0000 | [diff] [blame] | 3454 |         if (handlers == NULL) | 
 | 3455 |             return NULL; | 
 | 3456 |  | 
 | 3457 |         for (i = 0; i < n_except; i++) { | 
 | 3458 |             excepthandler_ty e = ast_for_except_clause(c, CHILD(n, 3 + i * 3), | 
 | 3459 |                                                        CHILD(n, 5 + i * 3)); | 
 | 3460 |             if (!e) | 
 | 3461 |                 return NULL; | 
 | 3462 |             asdl_seq_SET(handlers, i, e); | 
 | 3463 |         } | 
| Neal Norwitz | f599f42 | 2005-12-17 21:33:47 +0000 | [diff] [blame] | 3464 |     } | 
 | 3465 |  | 
| Benjamin Peterson | 43af12b | 2011-05-29 11:43:10 -0500 | [diff] [blame] | 3466 |     assert(finally != NULL || asdl_seq_LEN(handlers)); | 
 | 3467 |     return Try(body, handlers, orelse, finally, LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3468 | } | 
 | 3469 |  | 
| Georg Brandl | 0c31562 | 2009-05-25 21:10:36 +0000 | [diff] [blame] | 3470 | /* with_item: test ['as' expr] */ | 
| Benjamin Peterson | bf1bbc1 | 2011-05-27 13:58:08 -0500 | [diff] [blame] | 3471 | static withitem_ty | 
 | 3472 | ast_for_with_item(struct compiling *c, const node *n) | 
| Guido van Rossum | c2e2074 | 2006-02-27 22:32:47 +0000 | [diff] [blame] | 3473 | { | 
 | 3474 |     expr_ty context_expr, optional_vars = NULL; | 
| Guido van Rossum | c2e2074 | 2006-02-27 22:32:47 +0000 | [diff] [blame] | 3475 |  | 
| Georg Brandl | 0c31562 | 2009-05-25 21:10:36 +0000 | [diff] [blame] | 3476 |     REQ(n, with_item); | 
 | 3477 |     context_expr = ast_for_expr(c, CHILD(n, 0)); | 
| Amaury Forgeot d'Arc | 92dc80a | 2010-08-19 17:43:15 +0000 | [diff] [blame] | 3478 |     if (!context_expr) | 
 | 3479 |         return NULL; | 
| Georg Brandl | 0c31562 | 2009-05-25 21:10:36 +0000 | [diff] [blame] | 3480 |     if (NCH(n) == 3) { | 
 | 3481 |         optional_vars = ast_for_expr(c, CHILD(n, 2)); | 
| Guido van Rossum | c2e2074 | 2006-02-27 22:32:47 +0000 | [diff] [blame] | 3482 |  | 
 | 3483 |         if (!optional_vars) { | 
 | 3484 |             return NULL; | 
 | 3485 |         } | 
| Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 3486 |         if (!set_context(c, optional_vars, Store, n)) { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3487 |             return NULL; | 
 | 3488 |         } | 
| Guido van Rossum | c2e2074 | 2006-02-27 22:32:47 +0000 | [diff] [blame] | 3489 |     } | 
 | 3490 |  | 
| Benjamin Peterson | bf1bbc1 | 2011-05-27 13:58:08 -0500 | [diff] [blame] | 3491 |     return withitem(context_expr, optional_vars, c->c_arena); | 
| Guido van Rossum | c2e2074 | 2006-02-27 22:32:47 +0000 | [diff] [blame] | 3492 | } | 
 | 3493 |  | 
| Georg Brandl | 0c31562 | 2009-05-25 21:10:36 +0000 | [diff] [blame] | 3494 | /* with_stmt: 'with' with_item (',' with_item)* ':' suite */ | 
 | 3495 | static stmt_ty | 
 | 3496 | ast_for_with_stmt(struct compiling *c, const node *n) | 
 | 3497 | { | 
| Benjamin Peterson | bf1bbc1 | 2011-05-27 13:58:08 -0500 | [diff] [blame] | 3498 |     int i, n_items; | 
 | 3499 |     asdl_seq *items, *body; | 
| Georg Brandl | 0c31562 | 2009-05-25 21:10:36 +0000 | [diff] [blame] | 3500 |  | 
 | 3501 |     REQ(n, with_stmt); | 
 | 3502 |  | 
| Benjamin Peterson | bf1bbc1 | 2011-05-27 13:58:08 -0500 | [diff] [blame] | 3503 |     n_items = (NCH(n) - 2) / 2; | 
 | 3504 |     items = asdl_seq_new(n_items, c->c_arena); | 
 | 3505 |     for (i = 1; i < NCH(n) - 2; i += 2) { | 
 | 3506 |         withitem_ty item = ast_for_with_item(c, CHILD(n, i)); | 
 | 3507 |         if (!item) | 
| Georg Brandl | 0c31562 | 2009-05-25 21:10:36 +0000 | [diff] [blame] | 3508 |             return NULL; | 
| Benjamin Peterson | bf1bbc1 | 2011-05-27 13:58:08 -0500 | [diff] [blame] | 3509 |         asdl_seq_SET(items, (i - 1) / 2, item); | 
| Georg Brandl | 0c31562 | 2009-05-25 21:10:36 +0000 | [diff] [blame] | 3510 |     } | 
 | 3511 |  | 
| Benjamin Peterson | bf1bbc1 | 2011-05-27 13:58:08 -0500 | [diff] [blame] | 3512 |     body = ast_for_suite(c, CHILD(n, NCH(n) - 1)); | 
 | 3513 |     if (!body) | 
 | 3514 |         return NULL; | 
 | 3515 |  | 
 | 3516 |     return With(items, body, LINENO(n), n->n_col_offset, c->c_arena); | 
| Georg Brandl | 0c31562 | 2009-05-25 21:10:36 +0000 | [diff] [blame] | 3517 | } | 
 | 3518 |  | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3519 | static stmt_ty | 
| Guido van Rossum | d59da4b | 2007-05-22 18:11:13 +0000 | [diff] [blame] | 3520 | ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3521 | { | 
| Guido van Rossum | 52cc1d8 | 2007-03-18 15:41:51 +0000 | [diff] [blame] | 3522 |     /* classdef: 'class' NAME ['(' arglist ')'] ':' suite */ | 
| Benjamin Peterson | 3076006 | 2008-11-25 04:02:28 +0000 | [diff] [blame] | 3523 |     PyObject *classname; | 
| Guido van Rossum | 52cc1d8 | 2007-03-18 15:41:51 +0000 | [diff] [blame] | 3524 |     asdl_seq *s; | 
| Benjamin Peterson | d951e7b | 2008-11-25 22:19:53 +0000 | [diff] [blame] | 3525 |     expr_ty call; | 
| Guido van Rossum | 52cc1d8 | 2007-03-18 15:41:51 +0000 | [diff] [blame] | 3526 |  | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3527 |     REQ(n, classdef); | 
 | 3528 |  | 
| Guido van Rossum | 52cc1d8 | 2007-03-18 15:41:51 +0000 | [diff] [blame] | 3529 |     if (NCH(n) == 4) { /* class NAME ':' suite */ | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3530 |         s = ast_for_suite(c, CHILD(n, 3)); | 
 | 3531 |         if (!s) | 
 | 3532 |             return NULL; | 
| Benjamin Peterson | 3076006 | 2008-11-25 04:02:28 +0000 | [diff] [blame] | 3533 |         classname = NEW_IDENTIFIER(CHILD(n, 1)); | 
 | 3534 |         if (!classname) | 
 | 3535 |             return NULL; | 
| Benjamin Peterson | 70f5276 | 2009-06-28 23:32:44 +0000 | [diff] [blame] | 3536 |         if (forbidden_name(classname, CHILD(n, 3), 0)) | 
 | 3537 |             return NULL; | 
| Benjamin Peterson | 3076006 | 2008-11-25 04:02:28 +0000 | [diff] [blame] | 3538 |         return ClassDef(classname, NULL, NULL, NULL, NULL, s, decorator_seq, | 
 | 3539 |                         LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3540 |     } | 
| Guido van Rossum | 52cc1d8 | 2007-03-18 15:41:51 +0000 | [diff] [blame] | 3541 |  | 
 | 3542 |     if (TYPE(CHILD(n, 3)) == RPAR) { /* class NAME '(' ')' ':' suite */ | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3543 |         s = ast_for_suite(c, CHILD(n,5)); | 
 | 3544 |         if (!s) | 
| Benjamin Peterson | 3076006 | 2008-11-25 04:02:28 +0000 | [diff] [blame] | 3545 |             return NULL; | 
 | 3546 |         classname = NEW_IDENTIFIER(CHILD(n, 1)); | 
 | 3547 |         if (!classname) | 
 | 3548 |             return NULL; | 
| Benjamin Peterson | 70f5276 | 2009-06-28 23:32:44 +0000 | [diff] [blame] | 3549 |         if (forbidden_name(classname, CHILD(n, 3), 0)) | 
 | 3550 |             return NULL; | 
| Benjamin Peterson | 3076006 | 2008-11-25 04:02:28 +0000 | [diff] [blame] | 3551 |         return ClassDef(classname, NULL, NULL, NULL, NULL, s, decorator_seq, | 
 | 3552 |                         LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3553 |     } | 
 | 3554 |  | 
| Guido van Rossum | 52cc1d8 | 2007-03-18 15:41:51 +0000 | [diff] [blame] | 3555 |     /* class NAME '(' arglist ')' ':' suite */ | 
 | 3556 |     /* build up a fake Call node so we can extract its pieces */ | 
| Benjamin Peterson | d951e7b | 2008-11-25 22:19:53 +0000 | [diff] [blame] | 3557 |     { | 
 | 3558 |         PyObject *dummy_name; | 
 | 3559 |         expr_ty dummy; | 
 | 3560 |         dummy_name = NEW_IDENTIFIER(CHILD(n, 1)); | 
 | 3561 |         if (!dummy_name) | 
 | 3562 |             return NULL; | 
 | 3563 |         dummy = Name(dummy_name, Load, LINENO(n), n->n_col_offset, c->c_arena); | 
 | 3564 |         call = ast_for_call(c, CHILD(n, 3), dummy); | 
 | 3565 |         if (!call) | 
 | 3566 |             return NULL; | 
 | 3567 |     } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3568 |     s = ast_for_suite(c, CHILD(n, 6)); | 
| Neal Norwitz | 84456bd | 2005-12-18 03:16:20 +0000 | [diff] [blame] | 3569 |     if (!s) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3570 |         return NULL; | 
| Benjamin Peterson | 3076006 | 2008-11-25 04:02:28 +0000 | [diff] [blame] | 3571 |     classname = NEW_IDENTIFIER(CHILD(n, 1)); | 
 | 3572 |     if (!classname) | 
 | 3573 |         return NULL; | 
| Benjamin Peterson | 70f5276 | 2009-06-28 23:32:44 +0000 | [diff] [blame] | 3574 |     if (forbidden_name(classname, CHILD(n, 1), 0)) | 
 | 3575 |         return NULL; | 
| Guido van Rossum | 52cc1d8 | 2007-03-18 15:41:51 +0000 | [diff] [blame] | 3576 |  | 
| Benjamin Peterson | 3076006 | 2008-11-25 04:02:28 +0000 | [diff] [blame] | 3577 |     return ClassDef(classname, call->v.Call.args, call->v.Call.keywords, | 
| Guido van Rossum | 52cc1d8 | 2007-03-18 15:41:51 +0000 | [diff] [blame] | 3578 |                     call->v.Call.starargs, call->v.Call.kwargs, s, | 
| Guido van Rossum | d59da4b | 2007-05-22 18:11:13 +0000 | [diff] [blame] | 3579 |                     decorator_seq, LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3580 | } | 
 | 3581 |  | 
 | 3582 | static stmt_ty | 
 | 3583 | ast_for_stmt(struct compiling *c, const node *n) | 
 | 3584 | { | 
 | 3585 |     if (TYPE(n) == stmt) { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3586 |         assert(NCH(n) == 1); | 
 | 3587 |         n = CHILD(n, 0); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3588 |     } | 
 | 3589 |     if (TYPE(n) == simple_stmt) { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3590 |         assert(num_stmts(n) == 1); | 
 | 3591 |         n = CHILD(n, 0); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3592 |     } | 
 | 3593 |     if (TYPE(n) == small_stmt) { | 
| Neal Norwitz | c150536 | 2006-12-28 06:47:50 +0000 | [diff] [blame] | 3594 |         n = CHILD(n, 0); | 
| Jeremy Hylton | 81e9502 | 2007-02-27 06:50:52 +0000 | [diff] [blame] | 3595 |         /* small_stmt: expr_stmt | del_stmt | pass_stmt | flow_stmt | 
 | 3596 |                   | import_stmt | global_stmt | nonlocal_stmt | assert_stmt | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3597 |         */ | 
 | 3598 |         switch (TYPE(n)) { | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3599 |             case expr_stmt: | 
 | 3600 |                 return ast_for_expr_stmt(c, n); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3601 |             case del_stmt: | 
 | 3602 |                 return ast_for_del_stmt(c, n); | 
 | 3603 |             case pass_stmt: | 
| Martin v. Löwis | 49c5da1 | 2006-03-01 22:49:05 +0000 | [diff] [blame] | 3604 |                 return Pass(LINENO(n), n->n_col_offset, c->c_arena); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3605 |             case flow_stmt: | 
 | 3606 |                 return ast_for_flow_stmt(c, n); | 
 | 3607 |             case import_stmt: | 
 | 3608 |                 return ast_for_import_stmt(c, n); | 
 | 3609 |             case global_stmt: | 
 | 3610 |                 return ast_for_global_stmt(c, n); | 
| Jeremy Hylton | 81e9502 | 2007-02-27 06:50:52 +0000 | [diff] [blame] | 3611 |             case nonlocal_stmt: | 
 | 3612 |                 return ast_for_nonlocal_stmt(c, n); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3613 |             case assert_stmt: | 
 | 3614 |                 return ast_for_assert_stmt(c, n); | 
 | 3615 |             default: | 
| Neal Norwitz | 7979265 | 2005-11-14 04:25:03 +0000 | [diff] [blame] | 3616 |                 PyErr_Format(PyExc_SystemError, | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3617 |                              "unhandled small_stmt: TYPE=%d NCH=%d\n", | 
 | 3618 |                              TYPE(n), NCH(n)); | 
 | 3619 |                 return NULL; | 
 | 3620 |         } | 
 | 3621 |     } | 
 | 3622 |     else { | 
 | 3623 |         /* compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | 
| Guido van Rossum | d59da4b | 2007-05-22 18:11:13 +0000 | [diff] [blame] | 3624 |                         | funcdef | classdef | decorated | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3625 |         */ | 
 | 3626 |         node *ch = CHILD(n, 0); | 
 | 3627 |         REQ(n, compound_stmt); | 
 | 3628 |         switch (TYPE(ch)) { | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3629 |             case if_stmt: | 
 | 3630 |                 return ast_for_if_stmt(c, ch); | 
 | 3631 |             case while_stmt: | 
 | 3632 |                 return ast_for_while_stmt(c, ch); | 
 | 3633 |             case for_stmt: | 
 | 3634 |                 return ast_for_for_stmt(c, ch); | 
 | 3635 |             case try_stmt: | 
 | 3636 |                 return ast_for_try_stmt(c, ch); | 
| Guido van Rossum | c2e2074 | 2006-02-27 22:32:47 +0000 | [diff] [blame] | 3637 |             case with_stmt: | 
 | 3638 |                 return ast_for_with_stmt(c, ch); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3639 |             case funcdef: | 
| Guido van Rossum | d59da4b | 2007-05-22 18:11:13 +0000 | [diff] [blame] | 3640 |                 return ast_for_funcdef(c, ch, NULL); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3641 |             case classdef: | 
| Guido van Rossum | d59da4b | 2007-05-22 18:11:13 +0000 | [diff] [blame] | 3642 |                 return ast_for_classdef(c, ch, NULL); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 3643 |             case decorated: | 
 | 3644 |                 return ast_for_decorated(c, ch); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3645 |             default: | 
| Neal Norwitz | 7979265 | 2005-11-14 04:25:03 +0000 | [diff] [blame] | 3646 |                 PyErr_Format(PyExc_SystemError, | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3647 |                              "unhandled small_stmt: TYPE=%d NCH=%d\n", | 
 | 3648 |                              TYPE(n), NCH(n)); | 
 | 3649 |                 return NULL; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3650 |         } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3651 |     } | 
 | 3652 | } | 
 | 3653 |  | 
 | 3654 | static PyObject * | 
| Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 3655 | parsenumber(struct compiling *c, const char *s) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3656 | { | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3657 |     const char *end; | 
 | 3658 |     long x; | 
 | 3659 |     double dx; | 
| Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 3660 |     Py_complex compl; | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3661 |     int imflag; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3662 |  | 
| Mark Dickinson | d3c827b | 2008-12-05 18:10:46 +0000 | [diff] [blame] | 3663 |     assert(s != NULL); | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3664 |     errno = 0; | 
 | 3665 |     end = s + strlen(s) - 1; | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3666 |     imflag = *end == 'j' || *end == 'J'; | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3667 |     if (s[0] == '0') { | 
 | 3668 |         x = (long) PyOS_strtoul((char *)s, (char **)&end, 0); | 
 | 3669 |         if (x < 0 && errno == 0) { | 
 | 3670 |             return PyLong_FromString((char *)s, | 
 | 3671 |                                      (char **)0, | 
 | 3672 |                                      0); | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3673 |         } | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3674 |     } | 
 | 3675 |     else | 
 | 3676 |         x = PyOS_strtol((char *)s, (char **)&end, 0); | 
 | 3677 |     if (*end == '\0') { | 
 | 3678 |         if (errno != 0) | 
 | 3679 |             return PyLong_FromString((char *)s, (char **)0, 0); | 
| Christian Heimes | 217cfd1 | 2007-12-02 14:31:20 +0000 | [diff] [blame] | 3680 |         return PyLong_FromLong(x); | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3681 |     } | 
 | 3682 |     /* XXX Huge floats may silently fail */ | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3683 |     if (imflag) { | 
| Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 3684 |         compl.real = 0.; | 
| Mark Dickinson | 725bfd8 | 2009-05-03 20:33:40 +0000 | [diff] [blame] | 3685 |         compl.imag = PyOS_string_to_double(s, (char **)&end, NULL); | 
 | 3686 |         if (compl.imag == -1.0 && PyErr_Occurred()) | 
 | 3687 |             return NULL; | 
 | 3688 |         return PyComplex_FromCComplex(compl); | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3689 |     } | 
 | 3690 |     else | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3691 |     { | 
| Mark Dickinson | 725bfd8 | 2009-05-03 20:33:40 +0000 | [diff] [blame] | 3692 |         dx = PyOS_string_to_double(s, NULL, NULL); | 
 | 3693 |         if (dx == -1.0 && PyErr_Occurred()) | 
 | 3694 |             return NULL; | 
 | 3695 |         return PyFloat_FromDouble(dx); | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3696 |     } | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3697 | } | 
 | 3698 |  | 
 | 3699 | static PyObject * | 
| Martin v. Löwis | d63a3b8 | 2011-09-28 07:41:54 +0200 | [diff] [blame] | 3700 | decode_utf8(struct compiling *c, const char **sPtr, const char *end) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3701 | { | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3702 |     char *s, *t; | 
 | 3703 |     t = s = (char *)*sPtr; | 
 | 3704 |     /* while (s < end && *s != '\\') s++; */ /* inefficient for u".." */ | 
 | 3705 |     while (s < end && (*s & 0x80)) s++; | 
 | 3706 |     *sPtr = s; | 
| Martin v. Löwis | d63a3b8 | 2011-09-28 07:41:54 +0200 | [diff] [blame] | 3707 |     return PyUnicode_DecodeUTF8(t, s - t, NULL); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3708 | } | 
 | 3709 |  | 
 | 3710 | static PyObject * | 
| Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 3711 | decode_unicode(struct compiling *c, const char *s, size_t len, int rawmode, const char *encoding) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3712 | { | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3713 |     PyObject *v, *u; | 
 | 3714 |     char *buf; | 
 | 3715 |     char *p; | 
 | 3716 |     const char *end; | 
| Guido van Rossum | 29fd712 | 2007-11-12 01:13:56 +0000 | [diff] [blame] | 3717 |  | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3718 |     if (encoding == NULL) { | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3719 |         u = NULL; | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3720 |     } else { | 
| Amaury Forgeot d'Arc | 9c74b14 | 2008-06-18 00:47:36 +0000 | [diff] [blame] | 3721 |         /* check for integer overflow */ | 
| Benjamin Peterson | b2e796a | 2009-10-28 21:59:39 +0000 | [diff] [blame] | 3722 |         if (len > PY_SIZE_MAX / 6) | 
| Amaury Forgeot d'Arc | 9c74b14 | 2008-06-18 00:47:36 +0000 | [diff] [blame] | 3723 |             return NULL; | 
| Benjamin Peterson | b2e796a | 2009-10-28 21:59:39 +0000 | [diff] [blame] | 3724 |         /* "ä" (2 bytes) may become "\U000000E4" (10 bytes), or 1:5 | 
 | 3725 |            "\ä" (3 bytes) may become "\u005c\U000000E4" (16 bytes), or ~1:6 */ | 
 | 3726 |         u = PyBytes_FromStringAndSize((char *)NULL, len * 6); | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3727 |         if (u == NULL) | 
 | 3728 |             return NULL; | 
| Christian Heimes | 72b710a | 2008-05-26 13:28:38 +0000 | [diff] [blame] | 3729 |         p = buf = PyBytes_AsString(u); | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3730 |         end = s + len; | 
 | 3731 |         while (s < end) { | 
 | 3732 |             if (*s == '\\') { | 
 | 3733 |                 *p++ = *s++; | 
 | 3734 |                 if (*s & 0x80) { | 
 | 3735 |                     strcpy(p, "u005c"); | 
 | 3736 |                     p += 5; | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3737 |                 } | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3738 |             } | 
 | 3739 |             if (*s & 0x80) { /* XXX inefficient */ | 
 | 3740 |                 PyObject *w; | 
| Martin v. Löwis | d63a3b8 | 2011-09-28 07:41:54 +0200 | [diff] [blame] | 3741 |                 int kind; | 
 | 3742 |                 void *data; | 
 | 3743 |                 Py_ssize_t len, i; | 
 | 3744 |                 w = decode_utf8(c, &s, end); | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3745 |                 if (w == NULL) { | 
 | 3746 |                     Py_DECREF(u); | 
 | 3747 |                     return NULL; | 
 | 3748 |                 } | 
| Martin v. Löwis | d63a3b8 | 2011-09-28 07:41:54 +0200 | [diff] [blame] | 3749 |                 kind = PyUnicode_KIND(w); | 
 | 3750 |                 data = PyUnicode_DATA(w); | 
 | 3751 |                 len = PyUnicode_GET_LENGTH(w); | 
 | 3752 |                 for (i = 0; i < len; i++) { | 
 | 3753 |                     Py_UCS4 chr = PyUnicode_READ(kind, data, i); | 
 | 3754 |                     sprintf(p, "\\U%08x", chr); | 
| Benjamin Peterson | b2e796a | 2009-10-28 21:59:39 +0000 | [diff] [blame] | 3755 |                     p += 10; | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3756 |                 } | 
| Benjamin Peterson | b2e796a | 2009-10-28 21:59:39 +0000 | [diff] [blame] | 3757 |                 /* Should be impossible to overflow */ | 
 | 3758 |                 assert(p - buf <= Py_SIZE(u)); | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3759 |                 Py_DECREF(w); | 
 | 3760 |             } else { | 
 | 3761 |                 *p++ = *s++; | 
 | 3762 |             } | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3763 |         } | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3764 |         len = p - buf; | 
 | 3765 |         s = buf; | 
 | 3766 |     } | 
 | 3767 |     if (rawmode) | 
 | 3768 |         v = PyUnicode_DecodeRawUnicodeEscape(s, len, NULL); | 
 | 3769 |     else | 
 | 3770 |         v = PyUnicode_DecodeUnicodeEscape(s, len, NULL); | 
 | 3771 |     Py_XDECREF(u); | 
 | 3772 |     return v; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3773 | } | 
 | 3774 |  | 
 | 3775 | /* s is a Python string literal, including the bracketing quote characters, | 
| Guido van Rossum | 98297ee | 2007-11-06 21:34:58 +0000 | [diff] [blame] | 3776 |  * and r &/or b prefixes (if any), and embedded escape sequences (if any). | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3777 |  * parsestr parses it, and returns the decoded Python string object. | 
 | 3778 |  */ | 
 | 3779 | static PyObject * | 
| Christian Heimes | 4d6ec85 | 2008-03-26 22:34:47 +0000 | [diff] [blame] | 3780 | parsestr(struct compiling *c, const node *n, int *bytesmode) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3781 | { | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3782 |     size_t len; | 
 | 3783 |     const char *s = STR(n); | 
 | 3784 |     int quote = Py_CHARMASK(*s); | 
 | 3785 |     int rawmode = 0; | 
 | 3786 |     int need_encoding; | 
| Guido van Rossum | 98297ee | 2007-11-06 21:34:58 +0000 | [diff] [blame] | 3787 |     if (isalpha(quote)) { | 
| Antoine Pitrou | 3a5d4cb | 2012-01-12 22:46:19 +0100 | [diff] [blame] | 3788 |         while (!*bytesmode || !rawmode) { | 
 | 3789 |             if (quote == 'b' || quote == 'B') { | 
 | 3790 |                 quote = *++s; | 
 | 3791 |                 *bytesmode = 1; | 
 | 3792 |             } | 
| Armin Ronacher | 6ecf77b | 2012-03-04 12:04:06 +0000 | [diff] [blame] | 3793 |             else if (quote == 'u' || quote == 'U') { | 
 | 3794 |                 quote = *++s; | 
 | 3795 |             } | 
| Antoine Pitrou | 3a5d4cb | 2012-01-12 22:46:19 +0100 | [diff] [blame] | 3796 |             else if (quote == 'r' || quote == 'R') { | 
 | 3797 |                 quote = *++s; | 
 | 3798 |                 rawmode = 1; | 
 | 3799 |             } | 
 | 3800 |             else { | 
 | 3801 |                 break; | 
 | 3802 |             } | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3803 |         } | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3804 |     } | 
 | 3805 |     if (quote != '\'' && quote != '\"') { | 
 | 3806 |         PyErr_BadInternalCall(); | 
 | 3807 |         return NULL; | 
 | 3808 |     } | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3809 |     s++; | 
 | 3810 |     len = strlen(s); | 
 | 3811 |     if (len > INT_MAX) { | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 3812 |         PyErr_SetString(PyExc_OverflowError, | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3813 |                         "string to parse is too long"); | 
 | 3814 |         return NULL; | 
 | 3815 |     } | 
 | 3816 |     if (s[--len] != quote) { | 
 | 3817 |         PyErr_BadInternalCall(); | 
 | 3818 |         return NULL; | 
 | 3819 |     } | 
 | 3820 |     if (len >= 4 && s[0] == quote && s[1] == quote) { | 
 | 3821 |         s += 2; | 
 | 3822 |         len -= 2; | 
 | 3823 |         if (s[--len] != quote || s[--len] != quote) { | 
 | 3824 |             PyErr_BadInternalCall(); | 
 | 3825 |             return NULL; | 
| Thomas Wouters | 00e41de | 2007-02-23 19:56:57 +0000 | [diff] [blame] | 3826 |         } | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3827 |     } | 
| Benjamin Peterson | 8dbca06 | 2008-04-05 14:49:54 +0000 | [diff] [blame] | 3828 |     if (!*bytesmode && !rawmode) { | 
| Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 3829 |         return decode_unicode(c, s, len, rawmode, c->c_encoding); | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3830 |     } | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3831 |     if (*bytesmode) { | 
 | 3832 |         /* Disallow non-ascii characters (but not escapes) */ | 
 | 3833 |         const char *c; | 
 | 3834 |         for (c = s; *c; c++) { | 
 | 3835 |             if (Py_CHARMASK(*c) >= 0x80) { | 
 | 3836 |                 ast_error(n, "bytes can only contain ASCII " | 
 | 3837 |                           "literal characters."); | 
 | 3838 |                 return NULL; | 
 | 3839 |             } | 
| Thomas Wouters | 00e41de | 2007-02-23 19:56:57 +0000 | [diff] [blame] | 3840 |         } | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3841 |     } | 
| Christian Heimes | 4d6ec85 | 2008-03-26 22:34:47 +0000 | [diff] [blame] | 3842 |     need_encoding = (!*bytesmode && c->c_encoding != NULL && | 
| Brett Cannon | da78043 | 2008-10-17 03:38:50 +0000 | [diff] [blame] | 3843 |                      strcmp(c->c_encoding, "utf-8") != 0); | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3844 |     if (rawmode || strchr(s, '\\') == NULL) { | 
 | 3845 |         if (need_encoding) { | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3846 |             PyObject *v, *u = PyUnicode_DecodeUTF8(s, len, NULL); | 
| Guido van Rossum | 29fd712 | 2007-11-12 01:13:56 +0000 | [diff] [blame] | 3847 |             if (u == NULL || !*bytesmode) | 
 | 3848 |                 return u; | 
| Christian Heimes | 4d6ec85 | 2008-03-26 22:34:47 +0000 | [diff] [blame] | 3849 |             v = PyUnicode_AsEncodedString(u, c->c_encoding, NULL); | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3850 |             Py_DECREF(u); | 
 | 3851 |             return v; | 
| Guido van Rossum | 29fd712 | 2007-11-12 01:13:56 +0000 | [diff] [blame] | 3852 |         } else if (*bytesmode) { | 
| Christian Heimes | 72b710a | 2008-05-26 13:28:38 +0000 | [diff] [blame] | 3853 |             return PyBytes_FromStringAndSize(s, len); | 
| Christian Heimes | 4d6ec85 | 2008-03-26 22:34:47 +0000 | [diff] [blame] | 3854 |         } else if (strcmp(c->c_encoding, "utf-8") == 0) { | 
| Guido van Rossum | 29fd712 | 2007-11-12 01:13:56 +0000 | [diff] [blame] | 3855 |             return PyUnicode_FromStringAndSize(s, len); | 
| Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 3856 |         } else { | 
| Guido van Rossum | 29fd712 | 2007-11-12 01:13:56 +0000 | [diff] [blame] | 3857 |             return PyUnicode_DecodeLatin1(s, len, NULL); | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3858 |         } | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3859 |     } | 
| Christian Heimes | 72b710a | 2008-05-26 13:28:38 +0000 | [diff] [blame] | 3860 |     return PyBytes_DecodeEscape(s, len, NULL, 1, | 
| Christian Heimes | 4d6ec85 | 2008-03-26 22:34:47 +0000 | [diff] [blame] | 3861 |                                  need_encoding ? c->c_encoding : NULL); | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3862 | } | 
 | 3863 |  | 
| Guido van Rossum | 29fd712 | 2007-11-12 01:13:56 +0000 | [diff] [blame] | 3864 | /* Build a Python string object out of a STRING+ atom.  This takes care of | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3865 |  * compile-time literal catenation, calling parsestr() on each piece, and | 
 | 3866 |  * pasting the intermediate results together. | 
 | 3867 |  */ | 
 | 3868 | static PyObject * | 
| Thomas Wouters | 00e41de | 2007-02-23 19:56:57 +0000 | [diff] [blame] | 3869 | parsestrplus(struct compiling *c, const node *n, int *bytesmode) | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3870 | { | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3871 |     PyObject *v; | 
 | 3872 |     int i; | 
 | 3873 |     REQ(CHILD(n, 0), STRING); | 
| Christian Heimes | 4d6ec85 | 2008-03-26 22:34:47 +0000 | [diff] [blame] | 3874 |     v = parsestr(c, CHILD(n, 0), bytesmode); | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3875 |     if (v != NULL) { | 
 | 3876 |         /* String literal concatenation */ | 
 | 3877 |         for (i = 1; i < NCH(n); i++) { | 
 | 3878 |             PyObject *s; | 
 | 3879 |             int subbm = 0; | 
| Christian Heimes | 4d6ec85 | 2008-03-26 22:34:47 +0000 | [diff] [blame] | 3880 |             s = parsestr(c, CHILD(n, i), &subbm); | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3881 |             if (s == NULL) | 
 | 3882 |                 goto onError; | 
 | 3883 |             if (*bytesmode != subbm) { | 
| Guido van Rossum | 29fd712 | 2007-11-12 01:13:56 +0000 | [diff] [blame] | 3884 |                 ast_error(n, "cannot mix bytes and nonbytes literals"); | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3885 |                 goto onError; | 
 | 3886 |             } | 
| Christian Heimes | 72b710a | 2008-05-26 13:28:38 +0000 | [diff] [blame] | 3887 |             if (PyBytes_Check(v) && PyBytes_Check(s)) { | 
 | 3888 |                 PyBytes_ConcatAndDel(&v, s); | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3889 |                 if (v == NULL) | 
 | 3890 |                     goto onError; | 
 | 3891 |             } | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3892 |             else { | 
 | 3893 |                 PyObject *temp = PyUnicode_Concat(v, s); | 
 | 3894 |                 Py_DECREF(s); | 
 | 3895 |                 Py_DECREF(v); | 
 | 3896 |                 v = temp; | 
 | 3897 |                 if (v == NULL) | 
 | 3898 |                     goto onError; | 
 | 3899 |             } | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 3900 |         } | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3901 |     } | 
 | 3902 |     return v; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3903 |  | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 3904 |   onError: | 
 | 3905 |     Py_XDECREF(v); | 
 | 3906 |     return NULL; | 
| Jeremy Hylton | 3e0055f | 2005-10-20 19:59:25 +0000 | [diff] [blame] | 3907 | } |