History

add hg and python

cinap_lenrek committed 15 years ago

Commit 4bb9e221 parent 987265c3706 files · +1228772 −-233Browse files

Showing the changes to sys/src/cmd/python/Python/future.c (1 of 3706 files). Show all

Unified · Split

sys/src/cmd/python/Python/future.c+136−0
@@ -0,0 +1,136 @@
1+#include "Python.h"
2+#include "Python-ast.h"
3+#include "node.h"
4+#include "token.h"
5+#include "graminit.h"
6+#include "code.h"
7+#include "compile.h"
8+#include "symtable.h"
9+
10+#define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined"
11+
12+static int
13+future_check_features(PyFutureFeatures *ff, stmt_ty s, const char *filename)
14+{
15+ int i;
16+ asdl_seq *names;
17+
18+ assert(s->kind == ImportFrom_kind);
19+
20+ names = s->v.ImportFrom.names;
21+ for (i = 0; i < asdl_seq_LEN(names); i++) {
22+ alias_ty name = (alias_ty)asdl_seq_GET(names, i);
23+ const char *feature = PyString_AsString(name->name);
24+ if (!feature)
25+ return 0;
26+ if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) {
27+ continue;
28+ } else if (strcmp(feature, FUTURE_GENERATORS) == 0) {
29+ continue;
30+ } else if (strcmp(feature, FUTURE_DIVISION) == 0) {
31+ ff->ff_features |= CO_FUTURE_DIVISION;
32+ } else if (strcmp(feature, FUTURE_ABSOLUTE_IMPORT) == 0) {
33+ ff->ff_features |= CO_FUTURE_ABSOLUTE_IMPORT;
34+ } else if (strcmp(feature, FUTURE_WITH_STATEMENT) == 0) {
35+ ff->ff_features |= CO_FUTURE_WITH_STATEMENT;
36+ } else if (strcmp(feature, "braces") == 0) {
37+ PyErr_SetString(PyExc_SyntaxError,
38+ "not a chance");
39+ PyErr_SyntaxLocation(filename, s->lineno);
40+ return 0;
41+ } else {
42+ PyErr_Format(PyExc_SyntaxError,
43+ UNDEFINED_FUTURE_FEATURE, feature);
44+ PyErr_SyntaxLocation(filename, s->lineno);
45+ return 0;
46+ }
47+ }
48+ return 1;
49+}
50+
51+static int
52+future_parse(PyFutureFeatures *ff, mod_ty mod, const char *filename)
53+{
54+ int i, found_docstring = 0, done = 0, prev_line = 0;
55+
56+ static PyObject *future;
57+ if (!future) {
58+ future = PyString_InternFromString("__future__");
59+ if (!future)
60+ return 0;
61+ }
62+
63+ if (!(mod->kind == Module_kind || mod->kind == Interactive_kind))
64+ return 1;
65+
66+ /* A subsequent pass will detect future imports that don't
67+ appear at the beginning of the file. There's one case,
68+ however, that is easier to handl here: A series of imports
69+ joined by semi-colons, where the first import is a future
70+ statement but some subsequent import has the future form
71+ but is preceded by a regular import.
72+ */
73+
74+
75+ for (i = 0; i < asdl_seq_LEN(mod->v.Module.body); i++) {
76+ stmt_ty s = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i);
77+
78+ if (done && s->lineno > prev_line)
79+ return 1;
80+ prev_line = s->lineno;
81+
82+ /* The tests below will return from this function unless it is
83+ still possible to find a future statement. The only things
84+ that can precede a future statement are another future
85+ statement and a doc string.
86+ */
87+
88+ if (s->kind == ImportFrom_kind) {
89+ if (s->v.ImportFrom.module == future) {
90+ if (done) {
91+ PyErr_SetString(PyExc_SyntaxError,
92+ ERR_LATE_FUTURE);
93+ PyErr_SyntaxLocation(filename,
94+ s->lineno);
95+ return 0;
96+ }
97+ if (!future_check_features(ff, s, filename))
98+ return 0;
99+ ff->ff_lineno = s->lineno;
100+ }
101+ else
102+ done = 1;
103+ }
104+ else if (s->kind == Expr_kind && !found_docstring) {
105+ expr_ty e = s->v.Expr.value;
106+ if (e->kind != Str_kind)
107+ done = 1;
108+ else
109+ found_docstring = 1;
110+ }
111+ else
112+ done = 1;
113+ }
114+ return 1;
115+}
116+
117+
118+PyFutureFeatures *
119+PyFuture_FromAST(mod_ty mod, const char *filename)
120+{
121+ PyFutureFeatures *ff;
122+
123+ ff = (PyFutureFeatures *)PyObject_Malloc(sizeof(PyFutureFeatures));
124+ if (ff == NULL) {
125+ PyErr_NoMemory();
126+ return NULL;
127+ }
128+ ff->ff_features = 0;
129+ ff->ff_lineno = -1;
130+
131+ if (!future_parse(ff, mod, filename)) {
132+ PyObject_Free(ff);
133+ return NULL;
134+ }
135+ return ff;
136+}