@@ -9,7 +9,7 @@ import { BlockContext, Scope } from './scope';
9
9
10
10
export class Evaluator {
11
11
12
- static evalBlock ( ast : AstBlock , blockContext : BlockContext ) : unknown {
12
+ evalBlock ( ast : AstBlock , blockContext : BlockContext ) : unknown {
13
13
let lastResult = null ;
14
14
15
15
for ( let node of ast ?. funcs || [ ] ) {
@@ -19,14 +19,14 @@ export class Evaluator {
19
19
const newScope = blockContext . blockScope ;
20
20
21
21
newScope . set ( funcDef . funcAst . name ,
22
- ( ...args : unknown [ ] ) : unknown => Evaluator . jspyFuncInvoker ( funcDef , blockContext , ...args )
22
+ ( ...args : unknown [ ] ) : unknown => this . jspyFuncInvoker ( funcDef , blockContext , ...args )
23
23
) ;
24
24
}
25
25
26
26
for ( const node of ast . body ) {
27
27
if ( node . type === 'comment' ) { continue ; }
28
28
try {
29
- lastResult = Evaluator . evalNode ( node , blockContext ) ;
29
+ lastResult = this . evalNode ( node , blockContext ) ;
30
30
31
31
if ( blockContext . returnCalled ) {
32
32
const res = blockContext . returnObject ;
@@ -50,7 +50,7 @@ export class Evaluator {
50
50
throw err ;
51
51
} else {
52
52
const loc = node . loc ? node . loc : [ 0 , 0 ]
53
- throw new JspyEvalError ( 'mainModule' , loc [ 0 ] , loc [ 1 ] , err . message )
53
+ throw new JspyEvalError ( ast . name , loc [ 0 ] , loc [ 1 ] , err . message )
54
54
}
55
55
}
56
56
@@ -59,13 +59,13 @@ export class Evaluator {
59
59
return lastResult ;
60
60
}
61
61
62
- static jspyFuncInvoker ( funcDef : FuncDefNode , context : BlockContext , ...args : unknown [ ] ) : unknown {
62
+ jspyFuncInvoker ( funcDef : FuncDefNode , context : BlockContext , ...args : unknown [ ] ) : unknown {
63
63
64
64
const ast = Object . assign ( { } , funcDef . funcAst ) ;
65
65
ast . type = 'func' ;
66
66
67
67
const blockContext = {
68
- namelessFuncsCount : 0 ,
68
+ moduleName : context . moduleName ,
69
69
blockScope : context . blockScope . clone ( )
70
70
} as BlockContext ;
71
71
@@ -78,10 +78,10 @@ export class Evaluator {
78
78
blockContext . blockScope . set ( funcDef . params [ i ] , args [ i ] ) ;
79
79
}
80
80
81
- return Evaluator . evalBlock ( ast , blockContext ) ;
81
+ return this . evalBlock ( ast , blockContext ) ;
82
82
}
83
83
84
- private static invokeFunction ( func : ( ...args : unknown [ ] ) => unknown , fps : unknown [ ] ) : unknown {
84
+ private invokeFunction ( func : ( ...args : unknown [ ] ) => unknown , fps : unknown [ ] ) : unknown {
85
85
if ( fps . length === 0 ) { return func ( ) ; }
86
86
if ( fps . length === 1 ) { return func ( fps [ 0 ] ) ; }
87
87
if ( fps . length === 2 ) { return func ( fps [ 0 ] , fps [ 1 ] ) ; }
@@ -118,7 +118,7 @@ export class Evaluator {
118
118
}
119
119
}
120
120
121
- private static evalNode ( node : AstNode , blockContext : BlockContext ) : unknown {
121
+ private evalNode ( node : AstNode , blockContext : BlockContext ) : unknown {
122
122
if ( node . type === 'import' ) {
123
123
// skip this for now. As modules are implemented externally
124
124
return null ;
@@ -130,10 +130,10 @@ export class Evaluator {
130
130
131
131
if ( node . type === 'if' ) {
132
132
const ifNode = node as IfNode ;
133
- if ( Evaluator . evalNode ( ifNode . conditionNode , blockContext ) ) {
134
- Evaluator . evalBlock ( { type : 'if' , body : ifNode . ifBody } as AstBlock , blockContext ) ;
133
+ if ( this . evalNode ( ifNode . conditionNode , blockContext ) ) {
134
+ this . evalBlock ( { type : 'if' , body : ifNode . ifBody } as AstBlock , blockContext ) ;
135
135
} else if ( ifNode . elseBody ) {
136
- Evaluator . evalBlock ( { type : 'if' , body : ifNode . elseBody } as AstBlock , blockContext ) ;
136
+ this . evalBlock ( { type : 'if' , body : ifNode . elseBody } as AstBlock , blockContext ) ;
137
137
}
138
138
139
139
return ;
@@ -143,7 +143,7 @@ export class Evaluator {
143
143
const returnNode = node as ReturnNode ;
144
144
blockContext . returnCalled = true ;
145
145
blockContext . returnObject = returnNode . returnValue ?
146
- Evaluator . evalNode ( returnNode . returnValue , blockContext )
146
+ this . evalNode ( returnNode . returnValue , blockContext )
147
147
: null ;
148
148
149
149
return blockContext . returnObject ;
@@ -162,11 +162,11 @@ export class Evaluator {
162
162
if ( node . type === 'for' ) {
163
163
const forNode = node as ForNode ;
164
164
165
- const array = Evaluator . evalNode ( forNode . sourceArray , blockContext ) as unknown [ ] | string ;
165
+ const array = this . evalNode ( forNode . sourceArray , blockContext ) as unknown [ ] | string ;
166
166
167
167
for ( let item of array ) {
168
168
blockContext . blockScope . set ( forNode . itemVarName , item ) ;
169
- Evaluator . evalBlock ( { type : 'for' , body : forNode . body } as AstBlock , blockContext ) ;
169
+ this . evalBlock ( { type : 'for' , body : forNode . body } as AstBlock , blockContext ) ;
170
170
if ( blockContext . continueCalled ) { blockContext . continueCalled = false ; }
171
171
if ( blockContext . breakCalled ) { break ; }
172
172
}
@@ -177,8 +177,8 @@ export class Evaluator {
177
177
if ( node . type === 'while' ) {
178
178
const whileNode = node as WhileNode ;
179
179
180
- while ( Evaluator . evalNode ( whileNode . condition , blockContext ) ) {
181
- Evaluator . evalBlock ( { type : 'while' , body : whileNode . body } as AstBlock , blockContext ) ;
180
+ while ( this . evalNode ( whileNode . condition , blockContext ) ) {
181
+ this . evalBlock ( { type : 'while' , body : whileNode . body } as AstBlock , blockContext ) ;
182
182
183
183
if ( blockContext . continueCalled ) { blockContext . continueCalled = false ; }
184
184
if ( blockContext . breakCalled ) { break ; }
@@ -198,50 +198,50 @@ export class Evaluator {
198
198
199
199
if ( node . type === "binOp" ) {
200
200
const binOpNode = ( node as BinOpNode ) ;
201
- var left = Evaluator . evalNode ( binOpNode . left , blockContext ) ;
202
- var right = Evaluator . evalNode ( binOpNode . right , blockContext ) ;
201
+ var left = this . evalNode ( binOpNode . left , blockContext ) ;
202
+ var right = this . evalNode ( binOpNode . right , blockContext ) ;
203
203
return OperationFuncs [ binOpNode . op ] ( left as Primitive , right as Primitive ) ;
204
204
}
205
205
206
206
if ( node . type === "arrowFuncDef" ) {
207
207
const arrowFuncDef = node as ArrowFuncDefNode ;
208
208
209
- return ( ...args : unknown [ ] ) : unknown => Evaluator . jspyFuncInvoker ( arrowFuncDef , blockContext , ...args ) ;
209
+ return ( ...args : unknown [ ] ) : unknown => this . jspyFuncInvoker ( arrowFuncDef , blockContext , ...args ) ;
210
210
}
211
211
212
212
if ( node . type === "funcCall" ) {
213
213
const funcCallNode = node as FunctionCallNode ;
214
214
const func = blockContext . blockScope . get ( funcCallNode . name ) as ( ...args : unknown [ ] ) => unknown ;
215
- const pms = funcCallNode . paramNodes ?. map ( n => Evaluator . evalNode ( n , blockContext ) ) || [ ]
215
+ const pms = funcCallNode . paramNodes ?. map ( n => this . evalNode ( n , blockContext ) ) || [ ]
216
216
217
- return Evaluator . invokeFunction ( func , pms ) ;
217
+ return this . invokeFunction ( func , pms ) ;
218
218
}
219
219
220
220
if ( node . type === "assign" ) {
221
221
const assignNode = node as AssignNode ;
222
222
223
223
if ( assignNode . target . type === 'getSingleVar' ) {
224
224
const node = assignNode . target as SetSingleVarNode ;
225
- blockContext . blockScope . set ( node . name , Evaluator . evalNode ( assignNode . source , blockContext ) ) ;
225
+ blockContext . blockScope . set ( node . name , this . evalNode ( assignNode . source , blockContext ) ) ;
226
226
} else if ( assignNode . target . type === 'dotObjectAccess' ) {
227
227
const targetNode = assignNode . target as DotObjectAccessNode ;
228
228
229
229
// create a node for all but last property token
230
230
// potentially it can go to parser
231
231
const targetObjectNode = new DotObjectAccessNode ( targetNode . nestedProps . slice ( 0 , targetNode . nestedProps . length - 1 ) , targetNode . loc ) ;
232
- const targetObject = Evaluator . evalNode ( targetObjectNode , blockContext ) as Record < string , unknown > ;
232
+ const targetObject = this . evalNode ( targetObjectNode , blockContext ) as Record < string , unknown > ;
233
233
234
234
// not sure nested properties should be GetSingleVarNode
235
235
// can be factored in the parser
236
236
const lastPropertyName = ( targetNode . nestedProps [ targetNode . nestedProps . length - 1 ] as GetSingleVarNode ) . name
237
237
238
- targetObject [ lastPropertyName ] = Evaluator . evalNode ( assignNode . source , blockContext ) ;
238
+ targetObject [ lastPropertyName ] = this . evalNode ( assignNode . source , blockContext ) ;
239
239
} else if ( assignNode . target . type === 'bracketObjectAccess' ) {
240
240
const targetNode = assignNode . target as BracketObjectAccessNode ;
241
- const keyValue = Evaluator . evalNode ( targetNode . bracketBody , blockContext ) as string | number ;
241
+ const keyValue = this . evalNode ( targetNode . bracketBody , blockContext ) as string | number ;
242
242
const targetObject = blockContext . blockScope . get ( targetNode . propertyName as string ) as Record < string , unknown > ;
243
243
244
- targetObject [ keyValue ] = Evaluator . evalNode ( assignNode . source , blockContext ) ;
244
+ targetObject [ keyValue ] = this . evalNode ( assignNode . source , blockContext ) ;
245
245
} else {
246
246
throw Error ( 'Not implemented Assign operation' ) ;
247
247
// get chaining calls
@@ -252,15 +252,15 @@ export class Evaluator {
252
252
253
253
if ( node . type === 'bracketObjectAccess' ) {
254
254
const sbNode = node as BracketObjectAccessNode ;
255
- const key = Evaluator . evalNode ( sbNode . bracketBody , blockContext ) as string ;
255
+ const key = this . evalNode ( sbNode . bracketBody , blockContext ) as string ;
256
256
const obj = blockContext . blockScope . get ( sbNode . propertyName as string ) as Record < string , unknown > ;
257
257
return ( obj [ key ] === undefined ) ? null : obj [ key ] ;
258
258
}
259
259
260
260
if ( node . type === "dotObjectAccess" ) {
261
261
const dotObject = node as DotObjectAccessNode ;
262
262
263
- let startObject = Evaluator . evalNode ( dotObject . nestedProps [ 0 ] , blockContext ) as any ;
263
+ let startObject = this . evalNode ( dotObject . nestedProps [ 0 ] , blockContext ) as any ;
264
264
for ( let i = 1 ; i < dotObject . nestedProps . length ; i ++ ) {
265
265
const nestedProp = dotObject . nestedProps [ i ] ;
266
266
@@ -273,13 +273,13 @@ export class Evaluator {
273
273
} else if ( nestedProp . type === 'bracketObjectAccess' ) {
274
274
const node = nestedProp as BracketObjectAccessNode ;
275
275
startObject = startObject [ node . propertyName ] as unknown ;
276
- startObject = startObject [ Evaluator . evalNode ( node . bracketBody , blockContext ) as string ] as unknown ;
276
+ startObject = startObject [ this . evalNode ( node . bracketBody , blockContext ) as string ] as unknown ;
277
277
} else if ( nestedProp . type === 'funcCall' ) {
278
278
const funcCallNode = nestedProp as FunctionCallNode ;
279
279
const func = startObject [ funcCallNode . name ] as ( ...args : unknown [ ] ) => unknown ;
280
- const pms = funcCallNode . paramNodes ?. map ( n => Evaluator . evalNode ( n , blockContext ) ) || [ ]
280
+ const pms = funcCallNode . paramNodes ?. map ( n => this . evalNode ( n , blockContext ) ) || [ ]
281
281
282
- startObject = Evaluator . invokeFunction ( func . bind ( startObject ) , pms ) ;
282
+ startObject = this . invokeFunction ( func . bind ( startObject ) , pms ) ;
283
283
284
284
} else {
285
285
throw Error ( "Can't resolve dotObjectAccess node" )
@@ -295,7 +295,7 @@ export class Evaluator {
295
295
const obj = { } as Record < string , unknown > ;
296
296
297
297
for ( const p of createObjectNode . props ) {
298
- obj [ Evaluator . evalNode ( p . name , blockContext ) as string ] = Evaluator . evalNode ( p . value , blockContext ) ;
298
+ obj [ this . evalNode ( p . name , blockContext ) as string ] = this . evalNode ( p . value , blockContext ) ;
299
299
}
300
300
301
301
return obj ;
@@ -306,7 +306,7 @@ export class Evaluator {
306
306
const res = [ ] as unknown [ ] ;
307
307
308
308
for ( const item of arrayNode . items ) {
309
- res . push ( Evaluator . evalNode ( item , blockContext ) ) ;
309
+ res . push ( this . evalNode ( item , blockContext ) ) ;
310
310
}
311
311
312
312
return res ;
0 commit comments