11import {
22 ArrowFuncDefNode ,
33 AssignNode , AstBlock , AstNode , BinOpNode , BracketObjectAccessNode , ConstNode , CreateArrayNode ,
4- CreateObjectNode , DotObjectAccessNode , FunctionCallNode , FunctionDefNode , GetSingleVarNode , IfNode , OperationFuncs , Primitive , SetSingleVarNode
4+ CreateObjectNode , DotObjectAccessNode , ForNode , FunctionCallNode , FunctionDefNode , GetSingleVarNode , IfNode , OperationFuncs , Primitive , SetSingleVarNode
55} from '../common' ;
66import { Scope } from './scope' ;
77
@@ -97,6 +97,20 @@ export class Evaluator {
9797 return ;
9898 }
9999
100+ if ( node . type === 'for' ) {
101+ const forNode = node as ForNode ;
102+ const newScope = scope ;
103+
104+ const array = this . evalNode ( forNode . sourceArray , newScope ) as unknown [ ] | string ;
105+
106+ for ( let item of array ) {
107+ newScope . set ( forNode . itemVarName , item ) ;
108+ this . evalBlock ( { body : forNode . body } as AstBlock , newScope ) ;
109+ }
110+ return ;
111+ }
112+
113+
100114 if ( node . type === "const" ) {
101115 return ( node as ConstNode ) . value ;
102116 }
@@ -185,15 +199,20 @@ export class Evaluator {
185199
186200 let startObject = this . evalNode ( dotObject . nestedProps [ 0 ] , scope ) as any ;
187201 for ( let i = 1 ; i < dotObject . nestedProps . length ; i ++ ) {
202+ const nestedProp = dotObject . nestedProps [ i ] ;
203+
204+ if ( ( dotObject . nestedProps [ i - 1 ] as any ) . nullCoelsing && ! startObject ) {
205+ startObject = { } ;
206+ }
188207
189- if ( dotObject . nestedProps [ i ] . type === 'getSingleVar' ) {
190- startObject = startObject [ ( dotObject . nestedProps [ i ] as SetSingleVarNode ) . name ] as unknown ;
191- } else if ( dotObject . nestedProps [ i ] . type === 'bracketObjectAccess' ) {
192- const node = dotObject . nestedProps [ i ] as BracketObjectAccessNode ;
208+ if ( nestedProp . type === 'getSingleVar' ) {
209+ startObject = startObject [ ( nestedProp as SetSingleVarNode ) . name ] as unknown ;
210+ } else if ( nestedProp . type === 'bracketObjectAccess' ) {
211+ const node = nestedProp as BracketObjectAccessNode ;
193212 startObject = startObject [ node . propertyName ] as unknown ;
194213 startObject = startObject [ this . evalNode ( node . bracketBody , scope ) as string ] as unknown ;
195- } else if ( dotObject . nestedProps [ i ] . type === 'funcCall' ) {
196- const funcCallNode = dotObject . nestedProps [ i ] as FunctionCallNode ;
214+ } else if ( nestedProp . type === 'funcCall' ) {
215+ const funcCallNode = nestedProp as FunctionCallNode ;
197216 const func = startObject [ funcCallNode . name ] as ( ...args : unknown [ ] ) => unknown ;
198217 const pms = funcCallNode . paramNodes ?. map ( n => this . evalNode ( n , scope ) ) || [ ]
199218
@@ -204,7 +223,8 @@ export class Evaluator {
204223 }
205224 }
206225
207- return startObject ;
226+ // no undefined values, make it rather null
227+ return ( startObject === undefined ) ? null : startObject ;
208228 }
209229
210230 if ( node . type === 'createObject' ) {
0 commit comments