@@ -143,12 +143,12 @@ func (c *compiler) compileAst(Ast ast.Ast, filename string, futureFlags int, don
143143 valueOnStack = true
144144 case * ast.Suite :
145145 c .Stmts (node .Body )
146- case ast.Expr :
146+ case * ast.Lambda :
147147 // Make None the first constant as lambda can't have a docstring
148148 c .Const (py .None )
149149 code .Name = "<lambda>"
150150 c .setQualname () // FIXME is this in the right place!
151- c .Expr (node )
151+ c .Expr (node . Body )
152152 valueOnStack = true
153153 case * ast.FunctionDef :
154154 code .Name = string (node .Name )
@@ -406,6 +406,65 @@ func (c *compiler) setQualname() {
406406 }
407407}
408408
409+ // Compile a function
410+ func (c * compiler ) compileFunc (Ast ast.Ast , Args * ast.Arguments , DecoratorList []ast.Expr , Returns ast.Expr ) {
411+ newSymTable := c .SymTable .FindChild (Ast )
412+ if newSymTable == nil {
413+ panic ("No symtable found for function" )
414+ }
415+ newC := newCompiler (c , compilerScopeFunction )
416+ code , err := newC .compileAst (Ast , c .Code .Filename , 0 , false , newSymTable )
417+ if err != nil {
418+ panic (err )
419+ }
420+ // FIXME need these set in code before we compile - (pass in node?)
421+ code .Argcount = int32 (len (Args .Args ))
422+ code .Kwonlyargcount = int32 (len (Args .Kwonlyargs ))
423+
424+ // Defaults
425+ for _ , expr := range Args .Defaults {
426+ c .Expr (expr )
427+ }
428+
429+ // KwDefaults
430+ if len (Args .Kwonlyargs ) != len (Args .KwDefaults ) {
431+ panic ("differing number of Kwonlyargs to KwDefaults" )
432+ }
433+ for i := range Args .KwDefaults {
434+ c .LoadConst (py .String (Args .Kwonlyargs [i ].Arg ))
435+ c .Expr (Args .KwDefaults [i ])
436+ }
437+
438+ // Annotations
439+ annotations := py.Tuple {}
440+ addAnnotation := func (args ... * ast.Arg ) {
441+ for _ , arg := range args {
442+ if arg != nil && arg .Annotation != nil {
443+ c .Expr (arg .Annotation )
444+ annotations = append (annotations , py .String (arg .Arg ))
445+ }
446+ }
447+ }
448+ addAnnotation (Args .Args ... )
449+ addAnnotation (Args .Vararg )
450+ addAnnotation (Args .Kwonlyargs ... )
451+ addAnnotation (Args .Kwarg )
452+ if Returns != nil {
453+ c .Expr (Returns )
454+ annotations = append (annotations , py .String ("return" ))
455+ }
456+ num_annotations := uint32 (len (annotations ))
457+ if num_annotations > 0 {
458+ num_annotations ++ // include the tuple
459+ c .LoadConst (annotations )
460+ }
461+
462+ posdefaults := uint32 (len (Args .Defaults ))
463+ kwdefaults := uint32 (len (Args .KwDefaults ))
464+ args := uint32 (posdefaults + (kwdefaults << 8 ) + (num_annotations << 16 ))
465+ c .makeClosure (code , args , newC )
466+ }
467+
409468// Compile statement
410469func (c * compiler ) Stmt (stmt ast.Stmt ) {
411470 switch node := stmt .(type ) {
@@ -415,62 +474,7 @@ func (c *compiler) Stmt(stmt ast.Stmt) {
415474 // Body []Stmt
416475 // DecoratorList []Expr
417476 // Returns Expr
418- newSymTable := c .SymTable .FindChild (stmt )
419- if newSymTable == nil {
420- panic ("No symtable found for function" )
421- }
422- newC := newCompiler (c , compilerScopeFunction )
423- code , err := newC .compileAst (node , c .Code .Filename , 0 , false , newSymTable )
424- if err != nil {
425- panic (err )
426- }
427- // FIXME need these set in code before we compile - (pass in node?)
428- code .Argcount = int32 (len (node .Args .Args ))
429- code .Name = string (node .Name )
430- code .Kwonlyargcount = int32 (len (node .Args .Kwonlyargs ))
431-
432- // Defaults
433- posdefaults := uint32 (len (node .Args .Defaults ))
434- for _ , expr := range node .Args .Defaults {
435- c .Expr (expr )
436- }
437-
438- // KwDefaults
439- if len (node .Args .Kwonlyargs ) != len (node .Args .KwDefaults ) {
440- panic ("differing number of Kwonlyargs to KwDefaults" )
441- }
442- kwdefaults := uint32 (len (node .Args .KwDefaults ))
443- for i := range node .Args .KwDefaults {
444- c .LoadConst (py .String (node .Args .Kwonlyargs [i ].Arg ))
445- c .Expr (node .Args .KwDefaults [i ])
446- }
447-
448- // Annotations
449- annotations := py.Tuple {}
450- addAnnotation := func (args ... * ast.Arg ) {
451- for _ , arg := range args {
452- if arg != nil && arg .Annotation != nil {
453- c .Expr (arg .Annotation )
454- annotations = append (annotations , py .String (arg .Arg ))
455- }
456- }
457- }
458- addAnnotation (node .Args .Args ... )
459- addAnnotation (node .Args .Vararg )
460- addAnnotation (node .Args .Kwonlyargs ... )
461- addAnnotation (node .Args .Kwarg )
462- if node .Returns != nil {
463- c .Expr (node .Returns )
464- annotations = append (annotations , py .String ("return" ))
465- }
466- num_annotations := uint32 (len (annotations ))
467- if num_annotations > 0 {
468- num_annotations ++ // include the tuple
469- c .LoadConst (annotations )
470- }
471-
472- args := uint32 (posdefaults + (kwdefaults << 8 ) + (num_annotations << 16 ))
473- c .makeClosure (code , args , newC )
477+ c .compileFunc (stmt , node .Args , node .DecoratorList , node .Returns )
474478 c .NameOp (string (node .Name ), ast .Store )
475479
476480 case * ast.ClassDef :
@@ -899,19 +903,7 @@ func (c *compiler) Expr(expr ast.Expr) {
899903 // Args *Arguments
900904 // Body Expr
901905 // newC := Compiler
902- newSymTable := c .SymTable .FindChild (expr )
903- if newSymTable == nil {
904- panic ("No symtable found for lambda" )
905- }
906- newC := newCompiler (c , compilerScopeLambda )
907- code , err := newC .compileAst (node .Body , c .Code .Filename , 0 , false , newSymTable )
908- if err != nil {
909- panic (err )
910- }
911-
912- code .Argcount = int32 (len (node .Args .Args ))
913- // FIXME node.Args - more work on lambda needed
914- c .makeClosure (code , 0 , newC )
906+ c .compileFunc (expr , node .Args , nil , nil )
915907 case * ast.IfExp :
916908 // Test Expr
917909 // Body Expr
0 commit comments