|
1 | 1 | // compile python code |
2 | | -// |
3 | | -// Need to port the 10,000 lines of compiling machinery, into a |
4 | | -// different module probably. |
5 | | -// |
6 | | -// In the mean time, cheat horrendously by calling python3.4 to do our |
7 | | -// dirty work under the hood! |
8 | 2 |
|
9 | 3 | package compile |
10 | 4 |
|
11 | 5 | import ( |
12 | | -"bytes" |
13 | 6 | "fmt" |
14 | | -"os" |
15 | | -"os/exec" |
16 | | -"strings" |
17 | 7 |
|
18 | 8 | "github.com/ncw/gpython/ast" |
19 | | -"github.com/ncw/gpython/marshal" |
20 | 9 | "github.com/ncw/gpython/parser" |
21 | 10 | "github.com/ncw/gpython/py" |
22 | 11 | "github.com/ncw/gpython/symtable" |
23 | 12 | "github.com/ncw/gpython/vm" |
24 | 13 | ) |
25 | 14 |
|
26 | | -// Set in py to avoid circular import |
27 | | -funcinit(){ |
28 | | -py.Compile=Compile |
| 15 | +// Loop |
| 16 | +typeloopstruct{ |
| 17 | +Start*Label |
| 18 | +End*Label |
| 19 | +IsForLoopbool |
29 | 20 | } |
30 | 21 |
|
31 | | -// Compile(source, filename, mode, flags, dont_inherit) -> code object |
32 | | -// |
33 | | -// Compile the source string (a Python module, statement or expression) |
34 | | -// into a code object that can be executed by exec() or eval(). |
35 | | -// The filename will be used for run-time error messages. |
36 | | -// The mode must be 'exec' to compile a module, 'single' to compile a |
37 | | -// single (interactive) statement, or 'eval' to compile an expression. |
38 | | -// The flags argument, if present, controls which future statements influence |
39 | | -// the compilation of the code. |
40 | | -// The dont_inherit argument, if non-zero, stops the compilation inheriting |
41 | | -// the effects of any future statements in effect in the code calling |
42 | | -// compile; if absent or zero these statements do influence the compilation, |
43 | | -// in addition to any features explicitly specified. |
44 | | -funcLegacyCompile(str, filename, modestring, flagsint, dont_inheritbool) py.Object{ |
45 | | -dont_inherit_str:="False" |
46 | | -ifdont_inherit{ |
47 | | -dont_inherit_str="True" |
48 | | - } |
49 | | -// FIXME escaping in filename |
50 | | -code:=fmt.Sprintf(`import sys, marshal |
51 | | -str = sys.stdin.buffer.read().decode("utf-8") |
52 | | -code = compile(str, "%s", "%s", %d, %s) |
53 | | -marshalled_code = marshal.dumps(code) |
54 | | -sys.stdout.buffer.write(marshalled_code) |
55 | | -sys.stdout.close()`, |
56 | | -filename, |
57 | | -mode, |
58 | | -flags, |
59 | | -dont_inherit_str, |
60 | | - ) |
61 | | -cmd:=exec.Command("python3.4", "-c", code) |
62 | | -cmd.Stdin=strings.NewReader(str) |
63 | | -varout bytes.Buffer |
64 | | -cmd.Stdout=&out |
65 | | -varstderr bytes.Buffer |
66 | | -cmd.Stderr=&stderr |
67 | | -err:=cmd.Run() |
68 | | -iferr!=nil{ |
69 | | -fmt.Fprintf(os.Stderr, "--- Failed to run python3.4 compile ---\n") |
70 | | -fmt.Fprintf(os.Stderr, "--------------------\n") |
71 | | -os.Stderr.Write(stderr.Bytes()) |
72 | | -fmt.Fprintf(os.Stderr, "--------------------\n") |
73 | | -panic(err) |
74 | | - } |
75 | | -obj, err:=marshal.ReadObject(bytes.NewBuffer(out.Bytes())) |
76 | | -iferr!=nil{ |
77 | | -panic(err) |
| 22 | +// Loopstack |
| 23 | +typeloopstack []loop |
| 24 | + |
| 25 | +// Push a loop |
| 26 | +func (ls*loopstack) Push(lloop){ |
| 27 | +*ls=append(*ls, l) |
| 28 | +} |
| 29 | + |
| 30 | +// Pop a loop |
| 31 | +func (ls*loopstack) Pop(){ |
| 32 | +*ls= (*ls)[:len(*ls)-1] |
| 33 | +} |
| 34 | + |
| 35 | +// Return current loop or nil for none |
| 36 | +func (lsloopstack) Top() *loop{ |
| 37 | +iflen(ls) ==0{ |
| 38 | +returnnil |
78 | 39 | } |
79 | | -returnobj |
| 40 | +return&ls[len(ls)-1] |
| 41 | +} |
| 42 | + |
| 43 | +// State for the compiler |
| 44 | +typecompilerstruct{ |
| 45 | +Code*py.Code// code being built up |
| 46 | +OpCodesInstructions |
| 47 | +loopsloopstack |
| 48 | +SymTable*symtable.SymTable |
| 49 | +} |
| 50 | + |
| 51 | +// Set in py to avoid circular import |
| 52 | +funcinit(){ |
| 53 | +py.Compile=Compile |
80 | 54 | } |
81 | 55 |
|
82 | 56 | // Compile(source, filename, mode, flags, dont_inherit) -> code object |
@@ -159,42 +133,6 @@ func CompileAst(Ast ast.Ast, filename string, flags int, dont_inherit bool, SymT |
159 | 133 | returncode, nil |
160 | 134 | } |
161 | 135 |
|
162 | | -// Loop |
163 | | -typeloopstruct{ |
164 | | -Start*Label |
165 | | -End*Label |
166 | | -IsForLoopbool |
167 | | -} |
168 | | - |
169 | | -// Loopstack |
170 | | -typeloopstack []loop |
171 | | - |
172 | | -// Push a loop |
173 | | -func (ls*loopstack) Push(lloop){ |
174 | | -*ls=append(*ls, l) |
175 | | -} |
176 | | - |
177 | | -// Pop a loop |
178 | | -func (ls*loopstack) Pop(){ |
179 | | -*ls= (*ls)[:len(*ls)-1] |
180 | | -} |
181 | | - |
182 | | -// Return current loop or nil for none |
183 | | -func (lsloopstack) Top() *loop{ |
184 | | -iflen(ls) ==0{ |
185 | | -returnnil |
186 | | - } |
187 | | -return&ls[len(ls)-1] |
188 | | -} |
189 | | - |
190 | | -// State for the compiler |
191 | | -typecompilerstruct{ |
192 | | -Code*py.Code// code being built up |
193 | | -OpCodesInstructions |
194 | | -loopsloopstack |
195 | | -SymTable*symtable.SymTable |
196 | | -} |
197 | | - |
198 | 136 | // Check for docstring as first Expr in body and remove it and set the |
199 | 137 | // first constant if found. |
200 | 138 | func (c*compiler) docString(body []ast.Stmt) []ast.Stmt{ |
|
0 commit comments