blob: 95d6a5c9a3224b539cbc976fcaf1f05d95fd1f42 [file] [log] [blame]
Jeremy Hylton4db62b12001-02-27 19:07:02 +00001#include "Python.h"
2#include "node.h"
3#include "token.h"
4#include "graminit.h"
5#include "compile.h"
6#include "symtable.h"
7
8#define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined"
Jeremy Hyltonad3d3f22001-02-28 17:47:12 +00009#define FUTURE_IMPORT_STAR "future statement does not support import *"
Jeremy Hylton4db62b12001-02-27 19:07:02 +000010
Jeremy Hylton1e35ce52001-08-20 20:32:33 +000011/* FUTURE_POSSIBLE() is provided to accomodate doc strings, which is
12 the only statement that can occur before a future statement.
13*/
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +000014#define FUTURE_POSSIBLE(FF) ((FF)->ff_last_lineno == -1)
15
Jeremy Hylton4db62b12001-02-27 19:07:02 +000016static int
Martin v. Löwis95292d62002-12-11 14:04:59 +000017future_check_features(PyFutureFeatures *ff, node *n, const char *filename)
Jeremy Hylton4db62b12001-02-27 19:07:02 +000018{
19 int i;
20 char *feature;
Anthony Baxter1a4ddae2004-08-31 10:07:13 +000021 node *ch, *nn;
Jeremy Hylton4db62b12001-02-27 19:07:02 +000022
Anthony Baxter1a4ddae2004-08-31 10:07:13 +000023 REQ(n, import_from);
24 nn = CHILD(n, 3 + (TYPE(CHILD(n, 3)) == LPAR));
25 if (TYPE(nn) == STAR) {
26 PyErr_SetString(PyExc_SyntaxError, FUTURE_IMPORT_STAR);
27 PyErr_SyntaxLocation(filename, nn->n_lineno);
28 return -1;
29 }
30 REQ(nn, import_as_names);
31 for (i = 0; i < NCH(nn); i += 2) {
32 ch = CHILD(nn, i);
Jeremy Hyltonad3d3f22001-02-28 17:47:12 +000033 REQ(ch, import_as_name);
34 feature = STR(CHILD(ch, 0));
Jeremy Hylton4db62b12001-02-27 19:07:02 +000035 if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) {
Jeremy Hyltonb857ba22001-08-10 21:41:33 +000036 continue;
Guido van Rossumb09f7ed2001-07-15 21:08:29 +000037 } else if (strcmp(feature, FUTURE_GENERATORS) == 0) {
Tim Peters2bbdba32002-04-12 01:20:10 +000038 continue;
Guido van Rossum4668b002001-08-08 05:00:18 +000039 } else if (strcmp(feature, FUTURE_DIVISION) == 0) {
Jeremy Hyltonb857ba22001-08-10 21:41:33 +000040 ff->ff_features |= CO_FUTURE_DIVISION;
Jeremy Hyltonad3d3f22001-02-28 17:47:12 +000041 } else if (strcmp(feature, "braces") == 0) {
42 PyErr_SetString(PyExc_SyntaxError,
43 "not a chance");
44 PyErr_SyntaxLocation(filename, CHILD(ch, 0)->n_lineno);
45 return -1;
Jeremy Hylton4db62b12001-02-27 19:07:02 +000046 } else {
47 PyErr_Format(PyExc_SyntaxError,
48 UNDEFINED_FUTURE_FEATURE, feature);
Jeremy Hyltonad3d3f22001-02-28 17:47:12 +000049 PyErr_SyntaxLocation(filename, CHILD(ch, 0)->n_lineno);
Jeremy Hylton4db62b12001-02-27 19:07:02 +000050 return -1;
51 }
52 }
53 return 0;
54}
55
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +000056static void
Martin v. Löwis95292d62002-12-11 14:04:59 +000057future_error(node *n, const char *filename)
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +000058{
59 PyErr_SetString(PyExc_SyntaxError,
60 "from __future__ imports must occur at the "
61 "beginning of the file");
Jeremy Hyltonad3d3f22001-02-28 17:47:12 +000062 PyErr_SyntaxLocation(filename, n->n_lineno);
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +000063}
64
Jeremy Hylton4db62b12001-02-27 19:07:02 +000065/* Relevant portions of the grammar:
66
67single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
68file_input: (NEWLINE | stmt)* ENDMARKER
69stmt: simple_stmt | compound_stmt
70simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
Jeremy Hyltonad3d3f22001-02-28 17:47:12 +000071small_stmt: expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
72 | import_stmt | global_stmt | exec_stmt | assert_stmt
73import_stmt: 'import' dotted_as_name (',' dotted_as_name)*
74 | 'from' dotted_name 'import' ('*' | import_as_name (',' import_as_name)*)
Jeremy Hylton4db62b12001-02-27 19:07:02 +000075import_as_name: NAME [NAME NAME]
76dotted_as_name: dotted_name [NAME NAME]
77dotted_name: NAME ('.' NAME)*
78*/
79
Jeremy Hylton1e35ce52001-08-20 20:32:33 +000080/* future_parse() finds future statements at the beginnning of a
81 module. The function calls itself recursively, rather than
82 factoring out logic for different kinds of statements into
83 different routines.
84
85 Return values:
Jeremy Hylton4db62b12001-02-27 19:07:02 +000086 -1 indicates an error occurred, e.g. unknown feature name
87 0 indicates no feature was found
88 1 indicates a feature was found
89*/
90
91static int
Martin v. Löwis95292d62002-12-11 14:04:59 +000092future_parse(PyFutureFeatures *ff, node *n, const char *filename)
Jeremy Hylton4db62b12001-02-27 19:07:02 +000093{
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +000094 int i, r;
Jeremy Hylton4db62b12001-02-27 19:07:02 +000095 loop:
Jeremy Hylton4db62b12001-02-27 19:07:02 +000096 switch (TYPE(n)) {
97
Jeremy Hylton280c81a2001-02-28 02:26:14 +000098 case single_input:
99 if (TYPE(CHILD(n, 0)) == simple_stmt) {
100 n = CHILD(n, 0);
101 goto loop;
102 }
103 return 0;
104
Jeremy Hylton4db62b12001-02-27 19:07:02 +0000105 case file_input:
Jeremy Hylton1e35ce52001-08-20 20:32:33 +0000106 /* Check each statement in the file, starting with the
107 first, and continuing until the first statement
108 that isn't a future statement.
109 */
Jeremy Hylton4db62b12001-02-27 19:07:02 +0000110 for (i = 0; i < NCH(n); i++) {
111 node *ch = CHILD(n, i);
112 if (TYPE(ch) == stmt) {
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +0000113 r = future_parse(ff, ch, filename);
Jeremy Hylton1e35ce52001-08-20 20:32:33 +0000114 /* Need to check both conditions below
115 to accomodate doc strings, which
116 causes r < 0.
117 */
118 if (r < 1 && !FUTURE_POSSIBLE(ff))
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +0000119 return r;
Jeremy Hylton4db62b12001-02-27 19:07:02 +0000120 }
121 }
122 return 0;
123
124 case simple_stmt:
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +0000125 if (NCH(n) == 2) {
Jeremy Hylton4db62b12001-02-27 19:07:02 +0000126 REQ(CHILD(n, 0), small_stmt);
127 n = CHILD(n, 0);
128 goto loop;
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +0000129 } else {
130 /* Deal with the special case of a series of
131 small statements on a single line. If a
132 future statement follows some other
133 statement, the SyntaxError is raised here.
134 In all other cases, the symtable pass
135 raises the exception.
136 */
137 int found = 0, end_of_future = 0;
138
139 for (i = 0; i < NCH(n); i += 2) {
140 if (TYPE(CHILD(n, i)) == small_stmt) {
141 r = future_parse(ff, CHILD(n, i),
142 filename);
143 if (r < 1)
144 end_of_future = 1;
145 else {
146 found = 1;
147 if (end_of_future) {
148 future_error(n,
149 filename);
150 return -1;
151 }
152 }
153 }
Jeremy Hylton4db62b12001-02-27 19:07:02 +0000154 }
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +0000155
156 /* If we found one and only one, then the
157 current lineno is legal.
158 */
159 if (found)
160 ff->ff_last_lineno = n->n_lineno + 1;
161 else
162 ff->ff_last_lineno = n->n_lineno;
163
164 if (end_of_future && found)
165 return 1;
166 else
167 return 0;
168 }
Jeremy Hylton4db62b12001-02-27 19:07:02 +0000169
170 case stmt:
171 if (TYPE(CHILD(n, 0)) == simple_stmt) {
172 n = CHILD(n, 0);
173 goto loop;
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +0000174 } else if (TYPE(CHILD(n, 0)) == expr_stmt) {
175 n = CHILD(n, 0);
176 goto loop;
Jeremy Hylton4db62b12001-02-27 19:07:02 +0000177 } else {
178 REQ(CHILD(n, 0), compound_stmt);
179 ff->ff_last_lineno = n->n_lineno;
180 return 0;
181 }
182
183 case small_stmt:
184 n = CHILD(n, 0);
185 goto loop;
186
187 case import_stmt: {
188 node *name;
189
Anthony Baxter1a4ddae2004-08-31 10:07:13 +0000190 n = CHILD(n, 0);
191 if (TYPE(n) != import_from) {
Jeremy Hylton4db62b12001-02-27 19:07:02 +0000192 ff->ff_last_lineno = n->n_lineno;
193 return 0;
194 }
195 name = CHILD(n, 1);
196 if (strcmp(STR(CHILD(name, 0)), "__future__") != 0)
197 return 0;
Jeremy Hyltonad3d3f22001-02-28 17:47:12 +0000198 if (future_check_features(ff, n, filename) < 0)
Jeremy Hylton4db62b12001-02-27 19:07:02 +0000199 return -1;
Jeremy Hylton280c81a2001-02-28 02:26:14 +0000200 ff->ff_last_lineno = n->n_lineno + 1;
Jeremy Hylton4db62b12001-02-27 19:07:02 +0000201 return 1;
202 }
203
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +0000204 /* The cases below -- all of them! -- are necessary to find
205 and skip doc strings. */
206 case expr_stmt:
207 case testlist:
208 case test:
209 case and_test:
210 case not_test:
211 case comparison:
212 case expr:
213 case xor_expr:
214 case and_expr:
215 case shift_expr:
216 case arith_expr:
217 case term:
218 case factor:
219 case power:
220 if (NCH(n) == 1) {
221 n = CHILD(n, 0);
222 goto loop;
223 }
Jeremy Hyltonc9add9a2005-02-04 18:38:43 +0000224 ff->ff_last_lineno = n->n_lineno;
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +0000225 break;
226
227 case atom:
228 if (TYPE(CHILD(n, 0)) == STRING
229 && ff->ff_found_docstring == 0) {
230 ff->ff_found_docstring = 1;
231 return 0;
232 }
233 ff->ff_last_lineno = n->n_lineno;
234 return 0;
235
Jeremy Hylton4db62b12001-02-27 19:07:02 +0000236 default:
237 ff->ff_last_lineno = n->n_lineno;
238 return 0;
239 }
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +0000240 return 0;
Jeremy Hylton4db62b12001-02-27 19:07:02 +0000241}
242
243PyFutureFeatures *
Martin v. Löwis95292d62002-12-11 14:04:59 +0000244PyNode_Future(node *n, const char *filename)
Jeremy Hylton4db62b12001-02-27 19:07:02 +0000245{
246 PyFutureFeatures *ff;
247
248 ff = (PyFutureFeatures *)PyMem_Malloc(sizeof(PyFutureFeatures));
249 if (ff == NULL)
250 return NULL;
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +0000251 ff->ff_found_docstring = 0;
252 ff->ff_last_lineno = -1;
Jeremy Hyltonb857ba22001-08-10 21:41:33 +0000253 ff->ff_features = 0;
Jeremy Hylton4db62b12001-02-27 19:07:02 +0000254
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +0000255 if (future_parse(ff, n, filename) < 0) {
Jeremy Hylton4db62b12001-02-27 19:07:02 +0000256 PyMem_Free((void *)ff);
257 return NULL;
258 }
259 return ff;
260}