@@ -101,25 +101,8 @@ func evalWithSourceInfo(si SourceInfo, en *Env) (value Scmer) {
101101func Eval (expression Scmer , en * Env ) (value Scmer ) {
102102restart:
103103 switch expression .GetTag () {
104- case tagSourceInfo :
105- return evalWithSourceInfo (* expression .SourceInfo (), en )
106- case tagNil , tagBool , tagInt , tagFloat , tagDate , tagString , tagVector , tagFastDict , tagParser , tagAny , tagFunc , tagFuncEnv , tagProc , tagJIT , tagClosure , tagPromise :
107- // literals
108- return expression
109- case tagSymbol :
110- // get named variable
111- return en .FindRead (mustSymbol (expression )).Vars [mustSymbol (expression )]
112- case tagNthLocalVar :
113- // get numbered variable
114- idx := int (expression .NthLocalVar ())
115- if idx >= len (en .VarsNumbered ) {
116- buf := make ([]byte , 8192 )
117- n := runtime .Stack (buf , false )
118- panic (fmt .Sprintf ("NthLocalVar(%d) out of range (len=%d)\n %s" , idx , len (en .VarsNumbered ), buf [:n ]))
119- }
120- return en .VarsNumbered [idx ]
121104 case tagSlice :
122- // slice -> function call
105+ // Hot path: optimized queryplan/runtime code is dominated by call forms.
123106 list := expression .Slice ()
124107 if len (list ) == 0 {
125108 return expression
@@ -416,6 +399,10 @@ restart:
416399 args [i ] = Eval (x , en )
417400 }
418401 return fn (args ... )
402+ case tagProc :
403+ // Lambdas (procs)
404+ en , expression = prepareProcCall (procedure .Proc (), operands , en )
405+ goto restart
419406 case tagFuncEnv :
420407 // Native funcs with env
421408 fn := procedure .FuncEnv ()
@@ -431,10 +418,34 @@ restart:
431418 args [i ] = Eval (x , en )
432419 }
433420 return fn (en , args ... )
434- case tagProc :
435- // Lambdas (procs)
436- en , expression = prepareProcCall (procedure .Proc (), operands , en )
437- goto restart
421+ case tagClosure :
422+ fn := * (* func (uint32 , ... Scmer ) Scmer )(unsafe .Pointer (procedure .ptr ))
423+ id := uint32 (auxVal (procedure .aux ))
424+ if n := len (operands ); n <= 4 {
425+ var buf [4 ]Scmer
426+ for i := 0 ; i < n ; i ++ {
427+ buf [i ] = Eval (operands [i ], en )
428+ }
429+ return fn (id , buf [:n ]... )
430+ }
431+ args := make ([]Scmer , len (operands ))
432+ for i , x := range operands {
433+ args [i ] = Eval (x , en )
434+ }
435+ return fn (id , args ... )
436+ case tagPromise :
437+ if n := len (operands ); n <= 4 {
438+ var buf [4 ]Scmer
439+ for i := 0 ; i < n ; i ++ {
440+ buf [i ] = Eval (operands [i ], en )
441+ }
442+ return ApplyPromise (procedure , buf [:n ])
443+ }
444+ args := make ([]Scmer , len (operands ))
445+ for i , x := range operands {
446+ args [i ] = Eval (x , en )
447+ }
448+ return ApplyPromise (procedure , args )
438449 case tagSlice :
439450 // Associative list
440451 p := procedure .Slice ()
@@ -482,37 +493,26 @@ restart:
482493 args [i ] = Eval (x , en )
483494 }
484495 return jep .Native (args ... )
485- case tagClosure :
486- fn := * (* func (uint32 , ... Scmer ) Scmer )(unsafe .Pointer (procedure .ptr ))
487- id := uint32 (auxVal (procedure .aux ))
488- if n := len (operands ); n <= 4 {
489- var buf [4 ]Scmer
490- for i := 0 ; i < n ; i ++ {
491- buf [i ] = Eval (operands [i ], en )
492- }
493- return fn (id , buf [:n ]... )
494- }
495- args := make ([]Scmer , len (operands ))
496- for i , x := range operands {
497- args [i ] = Eval (x , en )
498- }
499- return fn (id , args ... )
500- case tagPromise :
501- if n := len (operands ); n <= 4 {
502- var buf [4 ]Scmer
503- for i := 0 ; i < n ; i ++ {
504- buf [i ] = Eval (operands [i ], en )
505- }
506- return ApplyPromise (procedure , buf [:n ])
507- }
508- args := make ([]Scmer , len (operands ))
509- for i , x := range operands {
510- args [i ] = Eval (x , en )
511- }
512- return ApplyPromise (procedure , args )
513496 default :
514497 panic ("Unknown function: " + list [0 ].String ())
515498 }
499+ case tagNthLocalVar :
500+ // Optimized lambda bodies resolve locals directly through numbered slots.
501+ idx := int (expression .NthLocalVar ())
502+ if idx >= len (en .VarsNumbered ) {
503+ buf := make ([]byte , 8192 )
504+ n := runtime .Stack (buf , false )
505+ panic (fmt .Sprintf ("NthLocalVar(%d) out of range (len=%d)\n %s" , idx , len (en .VarsNumbered ), buf [:n ]))
506+ }
507+ return en .VarsNumbered [idx ]
508+ case tagFunc , tagFuncEnv , tagProc , tagNil , tagBool , tagInt , tagFloat , tagDate , tagString , tagVector , tagFastDict , tagParser , tagJIT , tagClosure , tagPromise , tagAny :
509+ // Self-evaluating literals and optimizer-resolved native callables.
510+ return expression
511+ case tagSymbol :
512+ // Fallback for names not folded to numbered vars/native funcs by the optimizer.
513+ return en .FindRead (mustSymbol (expression )).Vars [mustSymbol (expression )]
514+ case tagSourceInfo :
515+ return evalWithSourceInfo (* expression .SourceInfo (), en )
516516 default :
517517 if expression .GetTag () >= 100 {
518518 // custom tags (e.g. TagTable) are opaque literals
0 commit comments