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