3
3
GetSingleVarNode , FunctionCallNode , getTokenType , getTokenValue , isTokenTypeLiteral , getStartLine ,
4
4
getStartColumn , getEndColumn , getEndLine , findOperators , splitTokens , DotObjectAccessNode , BracketObjectAccessNode ,
5
5
findTokenValueIndex , FunctionDefNode , CreateObjectNode , ObjectPropertyInfo , CreateArrayNode , ArrowFuncDefNode ,
6
- ExpressionOperators , IfNode , ForNode , WhileNode , ImportNode , NameAlias , ContinueNode , BreakNode , ReturnNode , CommentNode , getTokenLoc
6
+ ExpressionOperators , IfNode , ForNode , WhileNode , ImportNode , NameAlias , ContinueNode , BreakNode , ReturnNode , CommentNode , getTokenLoc , OperationTypes , LogicalNodeItem , LogicalOperators , LogicalOpNode , ComparisonOperators
7
7
} from '../common' ;
8
8
import { JspyParserError } from '../common/utils' ;
9
9
@@ -66,6 +66,12 @@ export class Parser {
66
66
return bodyAst . body ;
67
67
}
68
68
69
+ const findIndexes = ( tkns : Token [ ] , operation : OperationTypes , result : number [ ] ) : boolean => {
70
+ result . splice ( 0 , result . length ) ;
71
+ findOperators ( tkns , operation ) . forEach ( r => result . push ( r ) ) ;
72
+ return ! ! result . length ;
73
+ }
74
+
69
75
for ( let i = 0 ; i < instructions . length ; i ++ ) {
70
76
const instruction = instructions [ i ] ;
71
77
@@ -85,8 +91,11 @@ export class Parser {
85
91
const firstToken = instruction . tokens [ 0 ] ;
86
92
const secondToken = instruction . tokens . length > 1 ? instruction . tokens [ 1 ] : null ;
87
93
this . _currentToken = firstToken ;
94
+
95
+ const logicOpIndexes : number [ ] = [ ] ;
96
+ const comparisonOpIndexs : number [ ] = [ ] ;
97
+ const assignTokenIndexes : number [ ] = [ ] ;
88
98
89
- const assignTokens = splitTokens ( instruction . tokens , '=' ) ;
90
99
91
100
if ( getTokenType ( firstToken ) === TokenTypes . Comment ) {
92
101
ast . body . push ( new CommentNode ( getTokenValue ( firstToken ) as string , getTokenLoc ( firstToken ) ) ) ;
@@ -205,14 +214,68 @@ export class Parser {
205
214
const body = { } as AstBlock ; // empty for now
206
215
207
216
ast . body . push ( new ImportNode ( module , body , parts , getTokenLoc ( firstToken ) ) )
208
- } else if ( assignTokens . length > 1 ) {
217
+ } else if ( findIndexes ( instruction . tokens , OperationTypes . Assignment , assignTokenIndexes ) ) {
218
+ const assignTokens = splitTokens ( instruction . tokens , '=' ) ;
209
219
const target = this . createExpressionNode ( assignTokens [ 0 ] ) ;
210
220
const source = this . createExpressionNode ( assignTokens [ 1 ] ) ;
211
221
ast . body . push ( new AssignNode ( target , source , getTokenLoc ( assignTokens [ 0 ] [ 0 ] ) ) ) ;
222
+ } else if ( findIndexes ( instruction . tokens , OperationTypes . Logical , logicOpIndexes ) ) {
223
+ ast . body . push ( this . groupComparisonOperations ( logicOpIndexes , instruction ) ) ;
224
+ } else if ( findIndexes ( instruction . tokens , OperationTypes . Comparison , comparisonOpIndexs ) ) {
225
+ ast . body . push ( this . groupComparisonOperations ( comparisonOpIndexs , instruction ) ) ;
212
226
} else {
213
227
ast . body . push ( this . createExpressionNode ( instruction . tokens ) )
214
228
}
229
+
230
+ }
231
+ }
232
+
233
+ private groupComparisonOperations ( indexes : number [ ] , instruction : InstructionLine ) : AstNode {
234
+ let start = 0 ;
235
+ const slice = ( a : Token [ ] , begin : number , end : number ) : Token [ ] => {
236
+ // if expression is in brackets, then we need clean brackets
237
+ if ( getTokenValue ( a [ begin ] ) === '(' ) {
238
+ begin ++ ;
239
+ end -- ;
240
+ }
241
+
242
+ return a . slice ( begin , end ) ;
243
+ }
244
+
245
+ let leftNode : AstNode | null = null ;
246
+ for ( let i = 0 ; i < indexes . length ; i ++ ) {
247
+ const opToken = getTokenValue ( instruction . tokens [ indexes [ i ] ] ) as ComparisonOperators ;
248
+ leftNode = ( leftNode ) ? leftNode : this . createExpressionNode ( slice ( instruction . tokens , start , indexes [ i ] ) )
249
+
250
+ const endInd = ( i + 1 < indexes . length ) ? indexes [ i + 1 ] : instruction . tokens . length ;
251
+ const rightNode = this . createExpressionNode ( slice ( instruction . tokens , indexes [ i ] + 1 , endInd ) )
252
+
253
+ leftNode = new BinOpNode ( leftNode , opToken , rightNode , getTokenLoc ( instruction . tokens [ 0 ] ) ) ;
215
254
}
255
+
256
+ return leftNode as AstNode ;
257
+ }
258
+
259
+ private groupLogicalOperations ( logicOp : number [ ] , instruction : InstructionLine ) {
260
+ let start = 0 ;
261
+ const logicItems : LogicalNodeItem [ ] = [ ] ;
262
+ for ( let i = 0 ; i < logicOp . length ; i ++ ) {
263
+ const opToken = instruction . tokens [ logicOp [ i ] ] ;
264
+ const logicalSlice = instruction . tokens . slice ( start , logicOp [ i ] ) ;
265
+ logicItems . push ( {
266
+ node : this . createExpressionNode ( logicalSlice ) ,
267
+ op : getTokenValue ( opToken ) as LogicalOperators
268
+ } ) ;
269
+
270
+ start = logicOp [ i ] + 1 ;
271
+ }
272
+
273
+ logicItems . push ( {
274
+ node : this . createExpressionNode ( instruction . tokens . slice ( start ) )
275
+ } as LogicalNodeItem ) ;
276
+
277
+ const lop = new LogicalOpNode ( logicItems , getTokenLoc ( instruction . tokens [ 0 ] ) ) ;
278
+ return lop ;
216
279
}
217
280
218
281
private tokensToInstructionLines ( tokens : Token [ ] , startLine : number ) : InstructionLine [ ] {
@@ -222,7 +285,7 @@ export class Parser {
222
285
let currentLine = startLine ;
223
286
let line = new InstructionLine ( ) ;
224
287
for ( let i = 0 ; i < tokens . length ; i ++ ) {
225
- const token = tokens [ i ] ;
288
+ const token = tokens [ i ] ;
226
289
const sLine = getStartLine ( token ) ;
227
290
const sColumn = getStartColumn ( token ) ;
228
291
const value = getTokenValue ( token ) ;
@@ -304,7 +367,7 @@ export class Parser {
304
367
return new ArrowFuncDefNode ( funcAst , params , getTokenLoc ( tokens [ 0 ] ) ) ;
305
368
}
306
369
307
- // create expression
370
+ // create arithmetic expression
308
371
const ops = findOperators ( tokens ) ;
309
372
if ( ops . length ) {
310
373
// create binary node here
0 commit comments