|
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 |
| -func init() { |
28 |
| - py.Compile = Compile |
| 15 | +// Loop |
| 16 | +type loop struct { |
| 17 | + Start *Label |
| 18 | + End *Label |
| 19 | + IsForLoop bool |
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 |
| -func LegacyCompile(str, filename, mode string, flags int, dont_inherit bool) py.Object { |
45 |
| - dont_inherit_str := "False" |
46 |
| - if dont_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 |
| - var out bytes.Buffer |
64 |
| - cmd.Stdout = &out |
65 |
| - var stderr bytes.Buffer |
66 |
| - cmd.Stderr = &stderr |
67 |
| - err := cmd.Run() |
68 |
| - if err != 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 |
| - if err != nil { |
77 |
| - panic(err) |
| 22 | +// Loopstack |
| 23 | +type loopstack []loop |
| 24 | + |
| 25 | +// Push a loop |
| 26 | +func (ls *loopstack) Push(l loop) { |
| 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 (ls loopstack) Top() *loop { |
| 37 | + if len(ls) == 0 { |
| 38 | + return nil |
78 | 39 | }
|
79 |
| - return obj |
| 40 | + return &ls[len(ls)-1] |
| 41 | +} |
| 42 | + |
| 43 | +// State for the compiler |
| 44 | +type compiler struct { |
| 45 | + Code *py.Code // code being built up |
| 46 | + OpCodes Instructions |
| 47 | + loops loopstack |
| 48 | + SymTable *symtable.SymTable |
| 49 | +} |
| 50 | + |
| 51 | +// Set in py to avoid circular import |
| 52 | +func init() { |
| 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 | return code, nil
|
160 | 134 | }
|
161 | 135 |
|
162 |
| -// Loop |
163 |
| -type loop struct { |
164 |
| - Start *Label |
165 |
| - End *Label |
166 |
| - IsForLoop bool |
167 |
| -} |
168 |
| - |
169 |
| -// Loopstack |
170 |
| -type loopstack []loop |
171 |
| - |
172 |
| -// Push a loop |
173 |
| -func (ls *loopstack) Push(l loop) { |
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 (ls loopstack) Top() *loop { |
184 |
| - if len(ls) == 0 { |
185 |
| - return nil |
186 |
| - } |
187 |
| - return &ls[len(ls)-1] |
188 |
| -} |
189 |
| - |
190 |
| -// State for the compiler |
191 |
| -type compiler struct { |
192 |
| - Code *py.Code // code being built up |
193 |
| - OpCodes Instructions |
194 |
| - loops loopstack |
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