11// compile python code
22package compile
33
4+ // FIXME line numbers
5+ // FIXME name mangling
46// FIXME kill ast.Identifier and turn into string?
57
68import (
@@ -64,15 +66,16 @@ const (
6466
6567// State for the compiler
6668type 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
7679}
7780
7881// Set in py to avoid circular import
@@ -105,76 +108,103 @@ func Compile(str, filename, mode string, futureFlags int, dont_inherit bool) (py
105108 return nil , err
106109 }
107110 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
109116}
110117
111- // Make a new compiler
118+ // Make a new compiler object with empty code object
112119func newCompiler (parent * compiler , scopeType compilerScopeType ) * compiler {
120+ code := & py.Code {
121+ Firstlineno : 1 , // FIXME
122+ Name : "<module>" , // FIXME
123+ }
113124 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 ,
119130 }
120131 if parent != nil {
121132 c .depth = parent .depth + 1
122133 }
123134 return c
124135}
125136
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 ) {
128166 defer func () {
129167 if r := recover (); r != nil {
130168 err = py .MakeException (r )
131169 }
132170 }()
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
144171 c .SymTable = SymTable
172+ code := c .Code
173+ code .Filename = filename
145174 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 ) ... )
148177 code .Flags = c .codeFlags (SymTable ) | int32 (futureFlags & py .CO_COMPILER_FLAGS_MASK )
149178 valueOnStack := false
150179 switch node := Ast .(type ) {
151180 case * ast.Module :
152181 c .Stmts (c .docString (node .Body , false ))
153182 case * ast.Interactive :
183+ c .interactive = true
154184 c .Stmts (node .Body )
155185 case * ast.Expression :
156186 c .Expr (node .Body )
157187 valueOnStack = true
158188 case * ast.Suite :
159- c . Stmts ( node . Body )
189+ panic ( "suite should not be possible" )
160190 case * ast.Lambda :
161191 // Make None the first constant as lambda can't have a docstring
162192 c .Const (py .None )
163193 code .Name = "<lambda>"
164- c .setQualname () // FIXME is this in the right place!
194+ c .setQualname ()
165195 c .Expr (node .Body )
166196 valueOnStack = true
167197 case * ast.FunctionDef :
168198 code .Name = string (node .Name )
169- c .setQualname () // FIXME is this in the right place!
199+ c .setQualname ()
170200 c .Stmts (c .docString (node .Body , true ))
171201 case * ast.ClassDef :
172202 code .Name = string (node .Name )
173203 /* load (global) __name__ ... */
174204 c .NameOp ("__name__" , ast .Load )
175205 /* ... and store it as __module__ */
176206 c .NameOp ("__module__" , ast .Store )
177- c .setQualname () // FIXME is this in the right place!
207+ c .setQualname ()
178208 if c .qualname == "" {
179209 panic ("Need qualname" )
180210 }
@@ -230,7 +260,7 @@ func (c *compiler) compileAst(Ast ast.Ast, filename string, futureFlags int, don
230260 c .comprehensionGenerator (node .Generators , 0 , node .Elt , nil , Ast )
231261
232262 default :
233- panic (py . ExceptionNewf ( py . SyntaxError , "Unknown ModuleBase: %v" , Ast ))
263+ panic (fmt . Sprintf ( "Unknown ModuleBase: %v" , Ast ))
234264 }
235265 if ! c .OpCodes .EndsWithReturn () {
236266 // add a return
@@ -243,7 +273,7 @@ func (c *compiler) compileAst(Ast ast.Ast, filename string, futureFlags int, don
243273 code .Code = c .OpCodes .Assemble ()
244274 code .Stacksize = int32 (c .OpCodes .StackDepth ())
245275 code .Nlocals = int32 (len (code .Varnames ))
246- return code , nil
276+ return nil
247277}
248278
249279// 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 {
385415// makeClosure constructs the function or closure for a func/class/lambda etc
386416func (c * compiler ) makeClosure (code * py.Code , args uint32 , child * compiler , qualname string ) {
387417 free := uint32 (len (code .Freevars ))
388- if qualname == "" {
389- qualname = c .qualname
390- }
391418
392419 if free == 0 {
393420 c .LoadConst (code )
@@ -493,18 +520,9 @@ func (c *compiler) setQualname() {
493520
494521// Compile a function
495522func (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 ))
508526
509527 // Defaults
510528 c .Exprs (Args .Defaults )
@@ -549,7 +567,7 @@ func (c *compiler) compileFunc(compilerScope compilerScopeType, Ast ast.Ast, Arg
549567 posdefaults := uint32 (len (Args .Defaults ))
550568 kwdefaults := uint32 (len (Args .KwDefaults ))
551569 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 )
553571
554572 // Call decorators
555573 for _ = range DecoratorList {
@@ -575,23 +593,24 @@ func (c *compiler) class(Ast ast.Ast, class *ast.ClassDef) {
575593 */
576594
577595 /* 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)
583602 /* use the class name for name mangling */
584603 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+ // }
589608
590609 /* 2. load the 'build_class' function */
591610 c .Op (vm .LOAD_BUILD_CLASS )
592611
593612 /* 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 ))
595614
596615 /* 4. load class name */
597616 c .LoadConst (py .String (class .Name ))
@@ -1118,8 +1137,18 @@ func (c *compiler) Stmt(stmt ast.Stmt) {
11181137 // Implemented by symtable
11191138 case * ast.ExprStmt :
11201139 // 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+ }
11231152 case * ast.Pass :
11241153 // Do nothing
11251154 case * ast.Break :
@@ -1160,7 +1189,7 @@ func (c *compiler) Stmt(stmt ast.Stmt) {
11601189 panic ("unknown loop type" )
11611190 }
11621191 default :
1163- panic (py . ExceptionNewf ( py . SyntaxError , "Unknown StmtBase: %v" , stmt ))
1192+ panic (fmt . Sprintf ( "Unknown StmtBase: %v" , stmt ))
11641193 }
11651194}
11661195
@@ -1384,16 +1413,8 @@ func (c *compiler) comprehensionGenerator(generators []ast.Comprehension, gen_in
13841413
13851414// Compile a comprehension
13861415func (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 )
13971418 outermost_iter := generators [0 ].Iter
13981419 c .Expr (outermost_iter )
13991420 c .Op (vm .GET_ITER )
@@ -1825,6 +1846,6 @@ func (c *compiler) Expr(expr ast.Expr) {
18251846 // Ctx ExprContext
18261847 c .tupleOrList (vm .BUILD_TUPLE , node .Ctx , node .Elts )
18271848 default :
1828- panic (py . ExceptionNewf ( py . SyntaxError , "Unknown ExprBase: %v" , expr ))
1849+ panic (fmt . Sprintf ( "Unknown ExprBase: %v" , expr ))
18291850 }
18301851}
0 commit comments