1
1
// compile python code
2
2
package compile
3
3
4
+ // FIXME line numbers
5
+ // FIXME name mangling
4
6
// FIXME kill ast.Identifier and turn into string?
5
7
6
8
import (
@@ -64,15 +66,16 @@ const (
64
66
65
67
// State for the compiler
66
68
type compiler struct {
67
- Code * py.Code // code being built up
68
- OpCodes Instructions
69
- loops loopstack
70
- SymTable * symtable.SymTable
71
- scopeType compilerScopeType
72
- qualname string
73
- private string
74
- parent * compiler
75
- depth int
69
+ Code * py.Code // code being built up
70
+ OpCodes Instructions
71
+ loops loopstack
72
+ SymTable * symtable.SymTable
73
+ scopeType compilerScopeType
74
+ qualname string
75
+ private string
76
+ parent * compiler
77
+ depth int
78
+ interactive bool
76
79
}
77
80
78
81
// Set in py to avoid circular import
@@ -105,76 +108,103 @@ func Compile(str, filename, mode string, futureFlags int, dont_inherit bool) (py
105
108
return nil , err
106
109
}
107
110
c := newCompiler (nil , compilerScopeModule )
108
- return c .compileAst (Ast , filename , futureFlags , dont_inherit , SymTable )
111
+ err = c .compileAst (Ast , filename , futureFlags , dont_inherit , SymTable )
112
+ if err != nil {
113
+ return nil , err
114
+ }
115
+ return c .Code , nil
109
116
}
110
117
111
- // Make a new compiler
118
+ // Make a new compiler object with empty code object
112
119
func newCompiler (parent * compiler , scopeType compilerScopeType ) * compiler {
120
+ code := & py.Code {
121
+ Firstlineno : 1 , // FIXME
122
+ Name : "<module>" , // FIXME
123
+ }
113
124
c := & compiler {
114
- // Code: code,
115
- // SymTable : SymTable ,
116
- parent : parent ,
117
- scopeType : scopeType ,
118
- depth : 1 ,
125
+ Code : code ,
126
+ parent : parent ,
127
+ scopeType : scopeType ,
128
+ depth : 1 ,
129
+ interactive : false ,
119
130
}
120
131
if parent != nil {
121
132
c .depth = parent .depth + 1
122
133
}
123
134
return c
124
135
}
125
136
126
- // As Compile but takes an Ast
127
- func (c * compiler ) compileAst (Ast ast.Ast , filename string , futureFlags int , dont_inherit bool , SymTable * symtable.SymTable ) (code * py.Code , err error ) {
137
+ // Create a new compiler object at Ast, using private for name mangling
138
+ func (c * compiler ) newCompilerScope (compilerScope compilerScopeType , Ast ast.Ast , private string ) (newC * compiler ) {
139
+ newSymTable := c .SymTable .FindChild (Ast )
140
+ if newSymTable == nil {
141
+ panic (fmt .Sprintf ("No symtable found for scope type %v" , compilerScope ))
142
+ }
143
+
144
+ newC = newCompiler (c , compilerScope )
145
+
146
+ /* use the class name for name mangling */
147
+ newC .private = private
148
+
149
+ if newSymTable .NeedsClassClosure {
150
+ // Cook up a implicit __class__ cell.
151
+ if compilerScope != compilerScopeClass {
152
+ panic ("class closure not in class" )
153
+ }
154
+ newSymTable .Symbols ["__class__" ] = symtable.Symbol {Scope : symtable .ScopeCell }
155
+ }
156
+
157
+ err := newC .compileAst (Ast , c .Code .Filename , 0 , false , newSymTable )
158
+ if err != nil {
159
+ panic (err )
160
+ }
161
+ return newC
162
+ }
163
+
164
+ // Compile an Ast with the current compiler
165
+ func (c * compiler ) compileAst (Ast ast.Ast , filename string , futureFlags int , dont_inherit bool , SymTable * symtable.SymTable ) (err error ) {
128
166
defer func () {
129
167
if r := recover (); r != nil {
130
168
err = py .MakeException (r )
131
169
}
132
170
}()
133
- //fmt.Println(ast.Dump(Ast))
134
- code = & py.Code {
135
- Filename : filename ,
136
- Firstlineno : 1 , // FIXME
137
- Name : "<module>" , // FIXME
138
- // Argcount: int32(len(node.Args.Args)),
139
- // Name: string(node.Name),
140
- // Kwonlyargcount: int32(len(node.Args.Kwonlyargs)),
141
- // Nlocals: int32(len(SymTable.Varnames)),
142
- }
143
- c .Code = code
144
171
c .SymTable = SymTable
172
+ code := c .Code
173
+ code .Filename = filename
145
174
code .Varnames = append (code .Varnames , SymTable .Varnames ... )
146
- code .Cellvars = SymTable .Find (symtable .ScopeCell , 0 )
147
- code .Freevars = SymTable .Find (symtable .ScopeFree , symtable .DefFreeClass )
175
+ code .Cellvars = append ( code . Cellvars , SymTable .Find (symtable .ScopeCell , 0 ) ... )
176
+ code .Freevars = append ( code . Freevars , SymTable .Find (symtable .ScopeFree , symtable .DefFreeClass ) ... )
148
177
code .Flags = c .codeFlags (SymTable ) | int32 (futureFlags & py .CO_COMPILER_FLAGS_MASK )
149
178
valueOnStack := false
150
179
switch node := Ast .(type ) {
151
180
case * ast.Module :
152
181
c .Stmts (c .docString (node .Body , false ))
153
182
case * ast.Interactive :
183
+ c .interactive = true
154
184
c .Stmts (node .Body )
155
185
case * ast.Expression :
156
186
c .Expr (node .Body )
157
187
valueOnStack = true
158
188
case * ast.Suite :
159
- c . Stmts ( node . Body )
189
+ panic ( "suite should not be possible" )
160
190
case * ast.Lambda :
161
191
// Make None the first constant as lambda can't have a docstring
162
192
c .Const (py .None )
163
193
code .Name = "<lambda>"
164
- c .setQualname () // FIXME is this in the right place!
194
+ c .setQualname ()
165
195
c .Expr (node .Body )
166
196
valueOnStack = true
167
197
case * ast.FunctionDef :
168
198
code .Name = string (node .Name )
169
- c .setQualname () // FIXME is this in the right place!
199
+ c .setQualname ()
170
200
c .Stmts (c .docString (node .Body , true ))
171
201
case * ast.ClassDef :
172
202
code .Name = string (node .Name )
173
203
/* load (global) __name__ ... */
174
204
c .NameOp ("__name__" , ast .Load )
175
205
/* ... and store it as __module__ */
176
206
c .NameOp ("__module__" , ast .Store )
177
- c .setQualname () // FIXME is this in the right place!
207
+ c .setQualname ()
178
208
if c .qualname == "" {
179
209
panic ("Need qualname" )
180
210
}
@@ -230,7 +260,7 @@ func (c *compiler) compileAst(Ast ast.Ast, filename string, futureFlags int, don
230
260
c .comprehensionGenerator (node .Generators , 0 , node .Elt , nil , Ast )
231
261
232
262
default :
233
- panic (py . ExceptionNewf ( py . SyntaxError , "Unknown ModuleBase: %v" , Ast ))
263
+ panic (fmt . Sprintf ( "Unknown ModuleBase: %v" , Ast ))
234
264
}
235
265
if ! c .OpCodes .EndsWithReturn () {
236
266
// add a return
@@ -243,7 +273,7 @@ func (c *compiler) compileAst(Ast ast.Ast, filename string, futureFlags int, don
243
273
code .Code = c .OpCodes .Assemble ()
244
274
code .Stacksize = int32 (c .OpCodes .StackDepth ())
245
275
code .Nlocals = int32 (len (code .Varnames ))
246
- return code , nil
276
+ return nil
247
277
}
248
278
249
279
// Check for docstring as first Expr in body and remove it and set the
@@ -385,9 +415,6 @@ func (c *compiler) getRefType(name string) symtable.Scope {
385
415
// makeClosure constructs the function or closure for a func/class/lambda etc
386
416
func (c * compiler ) makeClosure (code * py.Code , args uint32 , child * compiler , qualname string ) {
387
417
free := uint32 (len (code .Freevars ))
388
- if qualname == "" {
389
- qualname = c .qualname
390
- }
391
418
392
419
if free == 0 {
393
420
c .LoadConst (code )
@@ -493,18 +520,9 @@ func (c *compiler) setQualname() {
493
520
494
521
// Compile a function
495
522
func (c * compiler ) compileFunc (compilerScope compilerScopeType , Ast ast.Ast , Args * ast.Arguments , DecoratorList []ast.Expr , Returns ast.Expr ) {
496
- newSymTable := c .SymTable .FindChild (Ast )
497
- if newSymTable == nil {
498
- panic ("No symtable found for function" )
499
- }
500
- newC := newCompiler (c , compilerScope )
501
- code , err := newC .compileAst (Ast , c .Code .Filename , 0 , false , newSymTable )
502
- if err != nil {
503
- panic (err )
504
- }
505
- // FIXME need these set in code before we compile - (pass in node?)
506
- code .Argcount = int32 (len (Args .Args ))
507
- code .Kwonlyargcount = int32 (len (Args .Kwonlyargs ))
523
+ newC := c .newCompilerScope (compilerScope , Ast , "" )
524
+ newC .Code .Argcount = int32 (len (Args .Args ))
525
+ newC .Code .Kwonlyargcount = int32 (len (Args .Kwonlyargs ))
508
526
509
527
// Defaults
510
528
c .Exprs (Args .Defaults )
@@ -549,7 +567,7 @@ func (c *compiler) compileFunc(compilerScope compilerScopeType, Ast ast.Ast, Arg
549
567
posdefaults := uint32 (len (Args .Defaults ))
550
568
kwdefaults := uint32 (len (Args .KwDefaults ))
551
569
args := uint32 (posdefaults + (kwdefaults << 8 ) + (num_annotations << 16 ))
552
- c .makeClosure (code , args , newC , newC .qualname )
570
+ c .makeClosure (newC . Code , args , newC , newC .qualname )
553
571
554
572
// Call decorators
555
573
for _ = range DecoratorList {
@@ -575,23 +593,24 @@ func (c *compiler) class(Ast ast.Ast, class *ast.ClassDef) {
575
593
*/
576
594
577
595
/* 1. compile the class body into a code object */
578
- newSymTable := c .SymTable .FindChild (Ast )
579
- if newSymTable == nil {
580
- panic ("No symtable found for class" )
581
- }
582
- newC := newCompiler (c , compilerScopeClass )
596
+ newC := c .newCompilerScope (compilerScopeClass , Ast , string (class .Name ))
597
+ // newSymTable := c.SymTable.FindChild(Ast)
598
+ // if newSymTable == nil {
599
+ // panic("No symtable found for class")
600
+ // }
601
+ // newC := newCompiler(c, compilerScopeClass)
583
602
/* use the class name for name mangling */
584
603
newC .private = string (class .Name )
585
- code , err := newC .compileAst (Ast , c .Code .Filename , 0 , false , newSymTable )
586
- if err != nil {
587
- panic (err )
588
- }
604
+ // code, err := newC.compileAst(Ast, c.Code.Filename, 0, false, newSymTable)
605
+ // if err != nil {
606
+ // panic(err)
607
+ // }
589
608
590
609
/* 2. load the 'build_class' function */
591
610
c .Op (vm .LOAD_BUILD_CLASS )
592
611
593
612
/* 3. load a function (or closure) made from the code object */
594
- c .makeClosure (code , 0 , newC , string (class .Name ))
613
+ c .makeClosure (newC . Code , 0 , newC , string (class .Name ))
595
614
596
615
/* 4. load class name */
597
616
c .LoadConst (py .String (class .Name ))
@@ -1118,8 +1137,18 @@ func (c *compiler) Stmt(stmt ast.Stmt) {
1118
1137
// Implemented by symtable
1119
1138
case * ast.ExprStmt :
1120
1139
// Value Expr
1121
- c .Expr (node .Value )
1122
- c .Op (vm .POP_TOP )
1140
+ if c .interactive && c .depth <= 1 {
1141
+ c .Expr (node .Value )
1142
+ c .Op (vm .PRINT_EXPR )
1143
+ } else {
1144
+ switch node .Value .(type ) {
1145
+ case * ast.Str :
1146
+ case * ast.Num :
1147
+ default :
1148
+ c .Expr (node .Value )
1149
+ c .Op (vm .POP_TOP )
1150
+ }
1151
+ }
1123
1152
case * ast.Pass :
1124
1153
// Do nothing
1125
1154
case * ast.Break :
@@ -1160,7 +1189,7 @@ func (c *compiler) Stmt(stmt ast.Stmt) {
1160
1189
panic ("unknown loop type" )
1161
1190
}
1162
1191
default :
1163
- panic (py . ExceptionNewf ( py . SyntaxError , "Unknown StmtBase: %v" , stmt ))
1192
+ panic (fmt . Sprintf ( "Unknown StmtBase: %v" , stmt ))
1164
1193
}
1165
1194
}
1166
1195
@@ -1384,16 +1413,8 @@ func (c *compiler) comprehensionGenerator(generators []ast.Comprehension, gen_in
1384
1413
1385
1414
// Compile a comprehension
1386
1415
func (c * compiler ) comprehension (expr ast.Expr , generators []ast.Comprehension ) {
1387
- newSymTable := c .SymTable .FindChild (expr )
1388
- if newSymTable == nil {
1389
- panic ("No symtable found for comprehension" )
1390
- }
1391
- newC := newCompiler (c , compilerScopeComprehension )
1392
- code , err := newC .compileAst (expr , c .Code .Filename , 0 , false , newSymTable )
1393
- if err != nil {
1394
- panic (err )
1395
- }
1396
- c .makeClosure (code , 0 , newC , newC .Code .Name )
1416
+ newC := c .newCompilerScope (compilerScopeComprehension , expr , "" )
1417
+ c .makeClosure (newC .Code , 0 , newC , newC .Code .Name )
1397
1418
outermost_iter := generators [0 ].Iter
1398
1419
c .Expr (outermost_iter )
1399
1420
c .Op (vm .GET_ITER )
@@ -1825,6 +1846,6 @@ func (c *compiler) Expr(expr ast.Expr) {
1825
1846
// Ctx ExprContext
1826
1847
c .tupleOrList (vm .BUILD_TUPLE , node .Ctx , node .Elts )
1827
1848
default :
1828
- panic (py . ExceptionNewf ( py . SyntaxError , "Unknown ExprBase: %v" , expr ))
1849
+ panic (fmt . Sprintf ( "Unknown ExprBase: %v" , expr ))
1829
1850
}
1830
1851
}
0 commit comments