11import {
22 ArrowFuncDefNode ,
33 AssignNode , AstBlock , AstNode , BinOpNode , BracketObjectAccessNode , ConstNode , CreateArrayNode ,
4- CreateObjectNode , DotObjectAccessNode , ForNode , FuncDefNode , FunctionCallNode , FunctionDefNode , GetSingleVarNode , IfNode , OperationFuncs , Primitive , ReturnNode , SetSingleVarNode , WhileNode
4+ CreateObjectNode , DotObjectAccessNode , ForNode , FuncDefNode , FunctionCallNode , FunctionDefNode , GetSingleVarNode ,
5+ IfNode , OperationFuncs , Primitive , ReturnNode , SetSingleVarNode , WhileNode
56} from '../common' ;
67import { BlockContext , Scope } from './scope' ;
78
89export class Evaluator {
910
10- evalBlock ( ast : AstBlock , blockContext : BlockContext ) : unknown {
11+ static evalBlock ( ast : AstBlock , blockContext : BlockContext ) : unknown {
1112 let lastResult = null ;
1213
1314 for ( let node of ast ?. funcs || [ ] ) {
@@ -17,13 +18,13 @@ export class Evaluator {
1718 const newScope = blockContext . blockScope ;
1819
1920 newScope . set ( funcDef . funcAst . name ,
20- ( ...args : unknown [ ] ) : unknown => this . jspyFuncInvoker ( funcDef , blockContext , ...args )
21+ ( ...args : unknown [ ] ) : unknown => Evaluator . jspyFuncInvoker ( funcDef , blockContext , ...args )
2122 ) ;
2223 }
2324
2425 for ( const node of ast . body ) {
2526 if ( node . type === 'comment' ) { continue ; }
26- lastResult = this . evalNode ( node , blockContext ) ;
27+ lastResult = Evaluator . evalNode ( node , blockContext ) ;
2728
2829 if ( blockContext . returnCalled ) {
2930 const res = blockContext . returnObject ;
@@ -47,7 +48,7 @@ export class Evaluator {
4748 return lastResult ;
4849 }
4950
50- private jspyFuncInvoker ( funcDef : FuncDefNode , context : BlockContext , ...args : unknown [ ] ) : unknown {
51+ static jspyFuncInvoker ( funcDef : FuncDefNode , context : BlockContext , ...args : unknown [ ] ) : unknown {
5152
5253 const ast = Object . assign ( { } , funcDef . funcAst ) ;
5354 ast . type = 'func' ;
@@ -66,10 +67,10 @@ export class Evaluator {
6667 blockContext . blockScope . set ( funcDef . params [ i ] , args [ i ] ) ;
6768 }
6869
69- return this . evalBlock ( ast , blockContext ) ;
70+ return Evaluator . evalBlock ( ast , blockContext ) ;
7071 }
7172
72- private invokeFunction ( func : ( ...args : unknown [ ] ) => unknown , fps : unknown [ ] ) : unknown {
73+ private static invokeFunction ( func : ( ...args : unknown [ ] ) => unknown , fps : unknown [ ] ) : unknown {
7374 if ( fps . length === 0 ) { return func ( ) ; }
7475 if ( fps . length === 1 ) { return func ( fps [ 0 ] ) ; }
7576 if ( fps . length === 2 ) { return func ( fps [ 0 ] , fps [ 1 ] ) ; }
@@ -106,7 +107,7 @@ export class Evaluator {
106107 }
107108 }
108109
109- private evalNode ( node : AstNode , blockContext : BlockContext ) : unknown {
110+ private static evalNode ( node : AstNode , blockContext : BlockContext ) : unknown {
110111 if ( node . type === 'import' ) {
111112 // skip this for now. As modules are implemented externally
112113 return null ;
@@ -118,10 +119,10 @@ export class Evaluator {
118119
119120 if ( node . type === 'if' ) {
120121 const ifNode = node as IfNode ;
121- if ( this . evalNode ( ifNode . conditionNode , blockContext ) ) {
122- this . evalBlock ( { type : 'if' , body : ifNode . ifBody } as AstBlock , blockContext ) ;
122+ if ( Evaluator . evalNode ( ifNode . conditionNode , blockContext ) ) {
123+ Evaluator . evalBlock ( { type : 'if' , body : ifNode . ifBody } as AstBlock , blockContext ) ;
123124 } else if ( ifNode . elseBody ) {
124- this . evalBlock ( { type : 'if' , body : ifNode . elseBody } as AstBlock , blockContext ) ;
125+ Evaluator . evalBlock ( { type : 'if' , body : ifNode . elseBody } as AstBlock , blockContext ) ;
125126 }
126127
127128 return ;
@@ -131,7 +132,7 @@ export class Evaluator {
131132 const returnNode = node as ReturnNode ;
132133 blockContext . returnCalled = true ;
133134 blockContext . returnObject = returnNode . returnValue ?
134- this . evalNode ( returnNode . returnValue , blockContext )
135+ Evaluator . evalNode ( returnNode . returnValue , blockContext )
135136 : null ;
136137
137138 return blockContext . returnObject ;
@@ -150,11 +151,11 @@ export class Evaluator {
150151 if ( node . type === 'for' ) {
151152 const forNode = node as ForNode ;
152153
153- const array = this . evalNode ( forNode . sourceArray , blockContext ) as unknown [ ] | string ;
154+ const array = Evaluator . evalNode ( forNode . sourceArray , blockContext ) as unknown [ ] | string ;
154155
155156 for ( let item of array ) {
156157 blockContext . blockScope . set ( forNode . itemVarName , item ) ;
157- this . evalBlock ( { type :'for' , body : forNode . body } as AstBlock , blockContext ) ;
158+ Evaluator . evalBlock ( { type :'for' , body : forNode . body } as AstBlock , blockContext ) ;
158159 if ( blockContext . continueCalled ) { blockContext . continueCalled = false ; }
159160 if ( blockContext . breakCalled ) { break ; }
160161 }
@@ -165,8 +166,8 @@ export class Evaluator {
165166 if ( node . type === 'while' ) {
166167 const whileNode = node as WhileNode ;
167168
168- while ( this . evalNode ( whileNode . condition , blockContext ) ) {
169- this . evalBlock ( { type :'while' , body : whileNode . body } as AstBlock , blockContext ) ;
169+ while ( Evaluator . evalNode ( whileNode . condition , blockContext ) ) {
170+ Evaluator . evalBlock ( { type :'while' , body : whileNode . body } as AstBlock , blockContext ) ;
170171
171172 if ( blockContext . continueCalled ) { blockContext . continueCalled = false ; }
172173 if ( blockContext . breakCalled ) { break ; }
@@ -186,50 +187,50 @@ export class Evaluator {
186187
187188 if ( node . type === "binOp" ) {
188189 const binOpNode = ( node as BinOpNode ) ;
189- var left = this . evalNode ( binOpNode . left , blockContext ) ;
190- var right = this . evalNode ( binOpNode . right , blockContext ) ;
190+ var left = Evaluator . evalNode ( binOpNode . left , blockContext ) ;
191+ var right = Evaluator . evalNode ( binOpNode . right , blockContext ) ;
191192 return OperationFuncs [ binOpNode . op ] ( left as Primitive , right as Primitive ) ;
192193 }
193194
194195 if ( node . type === "arrowFuncDef" ) {
195196 const arrowFuncDef = node as ArrowFuncDefNode ;
196197
197- return ( ...args : unknown [ ] ) : unknown => this . jspyFuncInvoker ( arrowFuncDef , blockContext , ...args ) ;
198+ return ( ...args : unknown [ ] ) : unknown => Evaluator . jspyFuncInvoker ( arrowFuncDef , blockContext , ...args ) ;
198199 }
199200
200201 if ( node . type === "funcCall" ) {
201202 const funcCallNode = node as FunctionCallNode ;
202203 const func = blockContext . blockScope . get ( funcCallNode . name ) as ( ...args : unknown [ ] ) => unknown ;
203- const pms = funcCallNode . paramNodes ?. map ( n => this . evalNode ( n , blockContext ) ) || [ ]
204+ const pms = funcCallNode . paramNodes ?. map ( n => Evaluator . evalNode ( n , blockContext ) ) || [ ]
204205
205- return this . invokeFunction ( func , pms ) ;
206+ return Evaluator . invokeFunction ( func , pms ) ;
206207 }
207208
208209 if ( node . type === "assign" ) {
209210 const assignNode = node as AssignNode ;
210211
211212 if ( assignNode . target . type === 'getSingleVar' ) {
212213 const node = assignNode . target as SetSingleVarNode ;
213- blockContext . blockScope . set ( node . name , this . evalNode ( assignNode . source , blockContext ) ) ;
214+ blockContext . blockScope . set ( node . name , Evaluator . evalNode ( assignNode . source , blockContext ) ) ;
214215 } else if ( assignNode . target . type === 'dotObjectAccess' ) {
215216 const targetNode = assignNode . target as DotObjectAccessNode ;
216217
217218 // create a node for all but last property token
218219 // potentially it can go to parser
219220 const targetObjectNode = new DotObjectAccessNode ( targetNode . nestedProps . slice ( 0 , targetNode . nestedProps . length - 1 ) ) ;
220- const targetObject = this . evalNode ( targetObjectNode , blockContext ) as Record < string , unknown > ;
221+ const targetObject = Evaluator . evalNode ( targetObjectNode , blockContext ) as Record < string , unknown > ;
221222
222223 // not sure nested properties should be GetSingleVarNode
223224 // can be factored in the parser
224225 const lastPropertyName = ( targetNode . nestedProps [ targetNode . nestedProps . length - 1 ] as GetSingleVarNode ) . name
225226
226- targetObject [ lastPropertyName ] = this . evalNode ( assignNode . source , blockContext ) ;
227+ targetObject [ lastPropertyName ] = Evaluator . evalNode ( assignNode . source , blockContext ) ;
227228 } else if ( assignNode . target . type === 'bracketObjectAccess' ) {
228229 const targetNode = assignNode . target as BracketObjectAccessNode ;
229- const keyValue = this . evalNode ( targetNode . bracketBody , blockContext ) as string | number ;
230+ const keyValue = Evaluator . evalNode ( targetNode . bracketBody , blockContext ) as string | number ;
230231 const targetObject = blockContext . blockScope . get ( targetNode . propertyName as string ) as Record < string , unknown > ;
231232
232- targetObject [ keyValue ] = this . evalNode ( assignNode . source , blockContext ) ;
233+ targetObject [ keyValue ] = Evaluator . evalNode ( assignNode . source , blockContext ) ;
233234 } else {
234235 throw Error ( 'Not implemented Assign operation' ) ;
235236 // get chaining calls
@@ -240,15 +241,15 @@ export class Evaluator {
240241
241242 if ( node . type === 'bracketObjectAccess' ) {
242243 const sbNode = node as BracketObjectAccessNode ;
243- const key = this . evalNode ( sbNode . bracketBody , blockContext ) as string ;
244+ const key = Evaluator . evalNode ( sbNode . bracketBody , blockContext ) as string ;
244245 const obj = blockContext . blockScope . get ( sbNode . propertyName as string ) as Record < string , unknown > ;
245246 return ( obj [ key ] === undefined ) ? null : obj [ key ] ;
246247 }
247248
248249 if ( node . type === "dotObjectAccess" ) {
249250 const dotObject = node as DotObjectAccessNode ;
250251
251- let startObject = this . evalNode ( dotObject . nestedProps [ 0 ] , blockContext ) as any ;
252+ let startObject = Evaluator . evalNode ( dotObject . nestedProps [ 0 ] , blockContext ) as any ;
252253 for ( let i = 1 ; i < dotObject . nestedProps . length ; i ++ ) {
253254 const nestedProp = dotObject . nestedProps [ i ] ;
254255
@@ -261,13 +262,13 @@ export class Evaluator {
261262 } else if ( nestedProp . type === 'bracketObjectAccess' ) {
262263 const node = nestedProp as BracketObjectAccessNode ;
263264 startObject = startObject [ node . propertyName ] as unknown ;
264- startObject = startObject [ this . evalNode ( node . bracketBody , blockContext ) as string ] as unknown ;
265+ startObject = startObject [ Evaluator . evalNode ( node . bracketBody , blockContext ) as string ] as unknown ;
265266 } else if ( nestedProp . type === 'funcCall' ) {
266267 const funcCallNode = nestedProp as FunctionCallNode ;
267268 const func = startObject [ funcCallNode . name ] as ( ...args : unknown [ ] ) => unknown ;
268- const pms = funcCallNode . paramNodes ?. map ( n => this . evalNode ( n , blockContext ) ) || [ ]
269+ const pms = funcCallNode . paramNodes ?. map ( n => Evaluator . evalNode ( n , blockContext ) ) || [ ]
269270
270- startObject = this . invokeFunction ( func . bind ( startObject ) , pms ) ;
271+ startObject = Evaluator . invokeFunction ( func . bind ( startObject ) , pms ) ;
271272
272273 } else {
273274 throw Error ( "Can't resolve dotObjectAccess node" )
@@ -283,7 +284,7 @@ export class Evaluator {
283284 const obj = { } as Record < string , unknown > ;
284285
285286 for ( const p of createObjectNode . props ) {
286- obj [ this . evalNode ( p . name , blockContext ) as string ] = this . evalNode ( p . value , blockContext ) ;
287+ obj [ Evaluator . evalNode ( p . name , blockContext ) as string ] = Evaluator . evalNode ( p . value , blockContext ) ;
287288 }
288289
289290 return obj ;
@@ -294,7 +295,7 @@ export class Evaluator {
294295 const res = [ ] as unknown [ ] ;
295296
296297 for ( const item of arrayNode . items ) {
297- res . push ( this . evalNode ( item , blockContext ) ) ;
298+ res . push ( Evaluator . evalNode ( item , blockContext ) ) ;
298299 }
299300
300301 return res ;
0 commit comments