33 GetSingleVarNode , FunctionCallNode , getTokenType , getTokenValue , isTokenTypeLiteral , getStartLine ,
44 getStartColumn , getEndColumn , getEndLine , findOperators , splitTokens , DotObjectAccessNode , BracketObjectAccessNode ,
55 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
77} from '../common' ;
88import { JspyParserError } from '../common/utils' ;
99
@@ -66,6 +66,12 @@ export class Parser {
6666 return bodyAst . body ;
6767 }
6868
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+
6975 for ( let i = 0 ; i < instructions . length ; i ++ ) {
7076 const instruction = instructions [ i ] ;
7177
@@ -85,8 +91,11 @@ export class Parser {
8591 const firstToken = instruction . tokens [ 0 ] ;
8692 const secondToken = instruction . tokens . length > 1 ? instruction . tokens [ 1 ] : null ;
8793 this . _currentToken = firstToken ;
94+
95+ const logicOpIndexes : number [ ] = [ ] ;
96+ const comparisonOpIndexs : number [ ] = [ ] ;
97+ const assignTokenIndexes : number [ ] = [ ] ;
8898
89- const assignTokens = splitTokens ( instruction . tokens , '=' ) ;
9099
91100 if ( getTokenType ( firstToken ) === TokenTypes . Comment ) {
92101 ast . body . push ( new CommentNode ( getTokenValue ( firstToken ) as string , getTokenLoc ( firstToken ) ) ) ;
@@ -205,14 +214,68 @@ export class Parser {
205214 const body = { } as AstBlock ; // empty for now
206215
207216 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 , '=' ) ;
209219 const target = this . createExpressionNode ( assignTokens [ 0 ] ) ;
210220 const source = this . createExpressionNode ( assignTokens [ 1 ] ) ;
211221 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 ) ) ;
212226 } else {
213227 ast . body . push ( this . createExpressionNode ( instruction . tokens ) )
214228 }
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 ] ) ) ;
215254 }
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 ;
216279 }
217280
218281 private tokensToInstructionLines ( tokens : Token [ ] , startLine : number ) : InstructionLine [ ] {
@@ -222,7 +285,7 @@ export class Parser {
222285 let currentLine = startLine ;
223286 let line = new InstructionLine ( ) ;
224287 for ( let i = 0 ; i < tokens . length ; i ++ ) {
225- const token = tokens [ i ] ;
288+ const token = tokens [ i ] ;
226289 const sLine = getStartLine ( token ) ;
227290 const sColumn = getStartColumn ( token ) ;
228291 const value = getTokenValue ( token ) ;
@@ -304,7 +367,7 @@ export class Parser {
304367 return new ArrowFuncDefNode ( funcAst , params , getTokenLoc ( tokens [ 0 ] ) ) ;
305368 }
306369
307- // create expression
370+ // create arithmetic expression
308371 const ops = findOperators ( tokens ) ;
309372 if ( ops . length ) {
310373 // create binary node here
0 commit comments