@@ -14,25 +14,31 @@ binary('=>', ASSIGN, true);
1414
1515// Compile
1616operator ( '=>' , ( a , b ) => {
17+ // Normalize params: () → [], x → [x], (a, b) → [a, b]
1718 a = a ?. [ 0 ] === '()' ? a [ 1 ] : a ;
18- a = ! a ? [ ] : a [ 0 ] === ',' ? a . slice ( 1 ) : [ a ] ;
19+ const ps = ! a ? [ ] : a [ 0 ] === ',' ? a . slice ( 1 ) : [ a ] ;
20+ // Check for rest param
1921 let restIdx = - 1 , restName = null ;
20- if ( a . length && Array . isArray ( a [ a . length - 1 ] ) && a [ a . length - 1 ] [ 0 ] === '...' ) {
21- restIdx = a . length - 1 ;
22- restName = a [ restIdx ] [ 1 ] ;
23- a = a . slice ( 0 , - 1 ) ;
22+ const last = ps [ ps . length - 1 ] ;
23+ if ( Array . isArray ( last ) && last [ 0 ] === '...' ) {
24+ restIdx = ps . length - 1 ;
25+ restName = last [ 1 ] ;
26+ ps . length -- ;
2427 }
2528 // Arrow body: {} is always block (need parens for object: ({...}))
2629 // Block body returns undefined unless explicit return
2730 const isBlock = b ?. [ 0 ] === '{}' ;
2831 b = compile ( isBlock ? [ '{' , b [ 1 ] ] : b ) ;
29- return ( ctx = null ) => {
30- ctx = Object . create ( ctx ) ;
31- return ( ...args ) => {
32- a . forEach ( ( p , i ) => ctx [ p ] = args [ i ] ) ;
33- if ( restName ) ctx [ restName ] = args . slice ( restIdx ) ;
34- try { const r = b ( ctx ) ; return isBlock ? undefined : r ; }
35- catch ( e ) { if ( e === RETURN ) return e [ 0 ] ; throw e ; }
36- } ;
32+ return ctx => ( ...args ) => {
33+ const l = { } ;
34+ ps . forEach ( ( p , i ) => l [ p ] = args [ i ] ) ;
35+ if ( restName ) l [ restName ] = args . slice ( restIdx ) ;
36+ const fnCtx = new Proxy ( l , {
37+ get : ( l , k ) => k in l ? l [ k ] : ctx ?. [ k ] ,
38+ set : ( l , k , v ) => ( ( k in l ? l : ctx ) [ k ] = v , true ) ,
39+ has : ( l , k ) => k in l || ( ctx ? k in ctx : false )
40+ } ) ;
41+ try { const r = b ( fnCtx ) ; return isBlock ? undefined : r ; }
42+ catch ( e ) { if ( e === RETURN ) return e [ 0 ] ; throw e ; }
3743 } ;
3844} ) ;
0 commit comments