blob: 37d547621961dafcf38d0822e951033c3200bc3d [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"
9
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +000010#define FUTURE_POSSIBLE(FF) ((FF)->ff_last_lineno == -1)
11
Jeremy Hylton4db62b12001-02-27 19:07:02 +000012static int
13future_check_features(PyFutureFeatures *ff, node *n)
14{
15 int i;
16 char *feature;
17
18 REQ(n, import_stmt); /* must by from __future__ import ... */
19
20 for (i = 3; i < NCH(n); ++i) {
21 feature = STR(CHILD(CHILD(n, i), 0));
22 if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) {
23 ff->ff_nested_scopes = 1;
24 } else {
25 PyErr_Format(PyExc_SyntaxError,
26 UNDEFINED_FUTURE_FEATURE, feature);
27 return -1;
28 }
29 }
30 return 0;
31}
32
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +000033static void
34future_error(node *n, char *filename)
35{
36 PyErr_SetString(PyExc_SyntaxError,
37 "from __future__ imports must occur at the "
38 "beginning of the file");
39 /* XXX set filename and lineno */
40}
41
Jeremy Hylton4db62b12001-02-27 19:07:02 +000042/* Relevant portions of the grammar:
43
44single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
45file_input: (NEWLINE | stmt)* ENDMARKER
46stmt: simple_stmt | compound_stmt
47simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
48small_stmt: expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | exec_stmt | assert_stmt
49import_stmt: 'import' dotted_as_name (',' dotted_as_name)* | 'from' dotted_name 'import' ('*' | import_as_name (',' import_as_name)*)
50import_as_name: NAME [NAME NAME]
51dotted_as_name: dotted_name [NAME NAME]
52dotted_name: NAME ('.' NAME)*
53*/
54
55/* future_parse() return values:
56 -1 indicates an error occurred, e.g. unknown feature name
57 0 indicates no feature was found
58 1 indicates a feature was found
59*/
60
61static int
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +000062future_parse(PyFutureFeatures *ff, node *n, char *filename)
Jeremy Hylton4db62b12001-02-27 19:07:02 +000063{
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +000064 int i, r;
Jeremy Hylton4db62b12001-02-27 19:07:02 +000065 loop:
66
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +000067/* fprintf(stderr, "future_parse(%d, %d, %s, %d)\n",
68 TYPE(n), NCH(n), (n == NULL) ? "NULL" : STR(n),
69 n->n_lineno);
Jeremy Hylton4db62b12001-02-27 19:07:02 +000070*/
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +000071
Jeremy Hylton4db62b12001-02-27 19:07:02 +000072 switch (TYPE(n)) {
73
Jeremy Hylton280c81a2001-02-28 02:26:14 +000074 case single_input:
75 if (TYPE(CHILD(n, 0)) == simple_stmt) {
76 n = CHILD(n, 0);
77 goto loop;
78 }
79 return 0;
80
Jeremy Hylton4db62b12001-02-27 19:07:02 +000081 case file_input:
82 for (i = 0; i < NCH(n); i++) {
83 node *ch = CHILD(n, i);
84 if (TYPE(ch) == stmt) {
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +000085 r = future_parse(ff, ch, filename);
86 if (!FUTURE_POSSIBLE(ff))
87 return r;
Jeremy Hylton4db62b12001-02-27 19:07:02 +000088 }
89 }
90 return 0;
91
92 case simple_stmt:
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +000093 if (NCH(n) == 2) {
Jeremy Hylton4db62b12001-02-27 19:07:02 +000094 REQ(CHILD(n, 0), small_stmt);
95 n = CHILD(n, 0);
96 goto loop;
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +000097 } else {
98 /* Deal with the special case of a series of
99 small statements on a single line. If a
100 future statement follows some other
101 statement, the SyntaxError is raised here.
102 In all other cases, the symtable pass
103 raises the exception.
104 */
105 int found = 0, end_of_future = 0;
106
107 for (i = 0; i < NCH(n); i += 2) {
108 if (TYPE(CHILD(n, i)) == small_stmt) {
109 r = future_parse(ff, CHILD(n, i),
110 filename);
111 if (r < 1)
112 end_of_future = 1;
113 else {
114 found = 1;
115 if (end_of_future) {
116 future_error(n,
117 filename);
118 return -1;
119 }
120 }
121 }
Jeremy Hylton4db62b12001-02-27 19:07:02 +0000122 }
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +0000123
124 /* If we found one and only one, then the
125 current lineno is legal.
126 */
127 if (found)
128 ff->ff_last_lineno = n->n_lineno + 1;
129 else
130 ff->ff_last_lineno = n->n_lineno;
131
132 if (end_of_future && found)
133 return 1;
134 else
135 return 0;
136 }
Jeremy Hylton4db62b12001-02-27 19:07:02 +0000137
138 case stmt:
139 if (TYPE(CHILD(n, 0)) == simple_stmt) {
140 n = CHILD(n, 0);
141 goto loop;
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +0000142 } else if (TYPE(CHILD(n, 0)) == expr_stmt) {
143 n = CHILD(n, 0);
144 goto loop;
Jeremy Hylton4db62b12001-02-27 19:07:02 +0000145 } else {
146 REQ(CHILD(n, 0), compound_stmt);
147 ff->ff_last_lineno = n->n_lineno;
148 return 0;
149 }
150
151 case small_stmt:
152 n = CHILD(n, 0);
153 goto loop;
154
155 case import_stmt: {
156 node *name;
157
158 if (STR(CHILD(n, 0))[0] != 'f') { /* from */
159 ff->ff_last_lineno = n->n_lineno;
160 return 0;
161 }
162 name = CHILD(n, 1);
163 if (strcmp(STR(CHILD(name, 0)), "__future__") != 0)
164 return 0;
165 if (future_check_features(ff, n) < 0)
166 return -1;
Jeremy Hylton280c81a2001-02-28 02:26:14 +0000167 ff->ff_last_lineno = n->n_lineno + 1;
Jeremy Hylton4db62b12001-02-27 19:07:02 +0000168 return 1;
169 }
170
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +0000171 /* The cases below -- all of them! -- are necessary to find
172 and skip doc strings. */
173 case expr_stmt:
174 case testlist:
175 case test:
176 case and_test:
177 case not_test:
178 case comparison:
179 case expr:
180 case xor_expr:
181 case and_expr:
182 case shift_expr:
183 case arith_expr:
184 case term:
185 case factor:
186 case power:
187 if (NCH(n) == 1) {
188 n = CHILD(n, 0);
189 goto loop;
190 }
191 break;
192
193 case atom:
194 if (TYPE(CHILD(n, 0)) == STRING
195 && ff->ff_found_docstring == 0) {
196 ff->ff_found_docstring = 1;
197 return 0;
198 }
199 ff->ff_last_lineno = n->n_lineno;
200 return 0;
201
Jeremy Hylton4db62b12001-02-27 19:07:02 +0000202 default:
203 ff->ff_last_lineno = n->n_lineno;
204 return 0;
205 }
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +0000206 return 0;
Jeremy Hylton4db62b12001-02-27 19:07:02 +0000207}
208
209PyFutureFeatures *
210PyNode_Future(node *n, char *filename)
211{
212 PyFutureFeatures *ff;
213
214 ff = (PyFutureFeatures *)PyMem_Malloc(sizeof(PyFutureFeatures));
215 if (ff == NULL)
216 return NULL;
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +0000217 ff->ff_found_docstring = 0;
218 ff->ff_last_lineno = -1;
Jeremy Hylton4db62b12001-02-27 19:07:02 +0000219 ff->ff_nested_scopes = 0;
220
Jeremy Hylton39e2f3f2001-02-28 01:58:08 +0000221 if (future_parse(ff, n, filename) < 0) {
Jeremy Hylton4db62b12001-02-27 19:07:02 +0000222 PyMem_Free((void *)ff);
223 return NULL;
224 }
225 return ff;
226}
227