mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	viml/parser/expressions: Make curly braces name actually work
This commit is contained in:
		| @@ -909,6 +909,55 @@ static inline void east_set_error(ExprAST *const ret_ast, | |||||||
|       } \ |       } \ | ||||||
|     } while (0) |     } while (0) | ||||||
|  |  | ||||||
|  | /// Add identifier which should constitute complex identifier node | ||||||
|  | /// | ||||||
|  | /// This one is to be called only in case want_node is kENodeOperator. | ||||||
|  | /// | ||||||
|  | /// @param  new_ident_node_code  Code used to create a new identifier node and | ||||||
|  | ///                              update want_node and ast_stack, without | ||||||
|  | ///                              a trailing semicolon. | ||||||
|  | /// @param  hl  Highlighting name to use, passed as an argument to #HL. | ||||||
|  | #define ADD_IDENT(new_ident_node_code, hl) \ | ||||||
|  |     do { \ | ||||||
|  |       assert(want_node == kENodeOperator); \ | ||||||
|  |       /* Operator: may only be curly braces name, but only under certain */ \ | ||||||
|  |       /* conditions. */ \ | ||||||
|  | \ | ||||||
|  |       /* First condition is that there is no space before a part of complex */ \ | ||||||
|  |       /* identifier. */ \ | ||||||
|  |       if (prev_token.type == kExprLexSpacing) { \ | ||||||
|  |         OP_MISSING; \ | ||||||
|  |       } \ | ||||||
|  |       switch ((*top_node_p)->type) { \ | ||||||
|  |         /* Second is that previous node is one of the identifiers: */ \ | ||||||
|  |         /* complex, plain, curly braces. */ \ | ||||||
|  | \ | ||||||
|  |         /* TODO(ZyX-I): Extend syntax to allow ${expr}. This is needed to */ \ | ||||||
|  |         /* handle environment variables like those bash uses for */ \ | ||||||
|  |         /* `export -f`: their names consist not only of alphanumeric */ \ | ||||||
|  |         /* characetrs. */ \ | ||||||
|  |         case kExprNodeComplexIdentifier: \ | ||||||
|  |         case kExprNodePlainIdentifier: \ | ||||||
|  |         case kExprNodeCurlyBracesIdentifier: { \ | ||||||
|  |           NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeComplexIdentifier); \ | ||||||
|  |           cur_node->len = 0; \ | ||||||
|  |           cur_node->children = *top_node_p; \ | ||||||
|  |           *top_node_p = cur_node; \ | ||||||
|  |           kvi_push(ast_stack, &cur_node->children->next); \ | ||||||
|  |           ExprASTNode **const new_top_node_p = kv_last(ast_stack); \ | ||||||
|  |           assert(*new_top_node_p == NULL); \ | ||||||
|  |           new_ident_node_code; \ | ||||||
|  |           *new_top_node_p = cur_node; \ | ||||||
|  |           HL_CUR_TOKEN(hl); \ | ||||||
|  |           break; \ | ||||||
|  |         } \ | ||||||
|  |         default: { \ | ||||||
|  |           OP_MISSING; \ | ||||||
|  |           break; \ | ||||||
|  |         } \ | ||||||
|  |       } \ | ||||||
|  |     } while (0) | ||||||
|  |  | ||||||
| /// Parse one VimL expression | /// Parse one VimL expression | ||||||
| /// | /// | ||||||
| /// @param  pstate  Parser state. | /// @param  pstate  Parser state. | ||||||
| @@ -1272,40 +1321,18 @@ viml_pexpr_parse_figure_brace_closing_error: | |||||||
|             want_node = kENodeArgument; |             want_node = kENodeArgument; | ||||||
|             lambda_node = cur_node; |             lambda_node = cur_node; | ||||||
|           } else { |           } else { | ||||||
|             // Operator: may only be curly braces name, but only under certain |             ADD_IDENT( | ||||||
|             // conditions. |                 do { | ||||||
|  |                   NEW_NODE_WITH_CUR_POS(cur_node, | ||||||
|             // First condition is that there is no space before {. |                                         kExprNodeCurlyBracesIdentifier); | ||||||
|             if (prev_token.type == kExprLexSpacing) { |                   cur_node->data.fig.opening_hl_idx = kv_size(*pstate->colors); | ||||||
|               OP_MISSING; |                   cur_node->data.fig.type_guesses.allow_lambda = false; | ||||||
|             } |                   cur_node->data.fig.type_guesses.allow_dict = false; | ||||||
|             switch ((*top_node_p)->type) { |                   cur_node->data.fig.type_guesses.allow_ident = true; | ||||||
|               // Second is that previous node is one of the identifiers: |  | ||||||
|               // complex, plain, curly braces. |  | ||||||
|  |  | ||||||
|               // TODO(ZyX-I): Extend syntax to allow ${expr}. This is needed to |  | ||||||
|               // handle environment variables like those bash uses for |  | ||||||
|               // `export -f`: their names consist not only of alphanumeric |  | ||||||
|               // characetrs. |  | ||||||
|               case kExprNodeComplexIdentifier: |  | ||||||
|               case kExprNodePlainIdentifier: |  | ||||||
|               case kExprNodeCurlyBracesIdentifier: { |  | ||||||
|                 NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeComplexIdentifier); |  | ||||||
|                 cur_node->len = 0; |  | ||||||
|                 viml_pexpr_handle_bop(&ast_stack, cur_node, &want_node); |  | ||||||
|                 ExprASTNode *const new_top_node = *kv_last(ast_stack); |  | ||||||
|                 assert(new_top_node->next == NULL); |  | ||||||
|                 NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeCurlyBracesIdentifier); |  | ||||||
|                 new_top_node->next = cur_node; |  | ||||||
|                   kvi_push(ast_stack, &cur_node->children); |                   kvi_push(ast_stack, &cur_node->children); | ||||||
|                 HL_CUR_TOKEN(Curly); |                   want_node = kENodeValue; | ||||||
|                 break; |                 } while (0), | ||||||
|               } |                 Curly); | ||||||
|               default: { |  | ||||||
|                 OP_MISSING; |  | ||||||
|                 break; |  | ||||||
|               } |  | ||||||
|             } |  | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|         break; |         break; | ||||||
| @@ -1351,8 +1378,6 @@ viml_pexpr_parse_figure_brace_closing_error: | |||||||
|           want_node = (want_node == kENodeArgument |           want_node = (want_node == kENodeArgument | ||||||
|                        ? kENodeArgumentSeparator |                        ? kENodeArgumentSeparator | ||||||
|                        : kENodeOperator); |                        : kENodeOperator); | ||||||
|           // FIXME: It is not valid to have scope inside complex identifier, |  | ||||||
|           //        check that. |  | ||||||
|           NEW_NODE_WITH_CUR_POS(cur_node, kExprNodePlainIdentifier); |           NEW_NODE_WITH_CUR_POS(cur_node, kExprNodePlainIdentifier); | ||||||
|           cur_node->data.var.scope = cur_token.data.var.scope; |           cur_node->data.var.scope = cur_token.data.var.scope; | ||||||
|           const size_t scope_shift = (cur_token.data.var.scope == 0 |           const size_t scope_shift = (cur_token.data.var.scope == 0 | ||||||
| @@ -1374,9 +1399,23 @@ viml_pexpr_parse_figure_brace_closing_error: | |||||||
|                                   cur_token.len - scope_shift, |                                   cur_token.len - scope_shift, | ||||||
|                                   HL(Identifier)); |                                   HL(Identifier)); | ||||||
|           } |           } | ||||||
|  |         // FIXME: Actually, g{foo}g:foo is valid: "1?g{foo}g:foo" is like | ||||||
|  |         //        "g{foo}g" and not an error. | ||||||
|  |         } else { | ||||||
|  |           if (cur_token.data.var.scope == 0) { | ||||||
|  |             ADD_IDENT( | ||||||
|  |                 do { | ||||||
|  |                   NEW_NODE_WITH_CUR_POS(cur_node, kExprNodePlainIdentifier); | ||||||
|  |                   cur_node->data.var.scope = cur_token.data.var.scope; | ||||||
|  |                   cur_node->data.var.ident = pline.data + cur_token.start.col; | ||||||
|  |                   cur_node->data.var.ident_len = cur_token.len; | ||||||
|  |                   want_node = kENodeOperator; | ||||||
|  |                 } while (0), | ||||||
|  |                 Identifier); | ||||||
|           } else { |           } else { | ||||||
|             OP_MISSING; |             OP_MISSING; | ||||||
|           } |           } | ||||||
|  |         } | ||||||
|         break; |         break; | ||||||
|       } |       } | ||||||
|       case kExprLexParenthesis: { |       case kExprLexParenthesis: { | ||||||
| @@ -1453,7 +1492,8 @@ viml_pexpr_parse_no_paren_closing_error: {} | |||||||
|               // intentionally inconsistent and he is not very happy with the |               // intentionally inconsistent and he is not very happy with the | ||||||
|               // situation himself. |               // situation himself. | ||||||
|               if ((*top_node_p)->type != kExprNodePlainIdentifier |               if ((*top_node_p)->type != kExprNodePlainIdentifier | ||||||
|                   && (*top_node_p)->type != kExprNodeComplexIdentifier) { |                   && (*top_node_p)->type != kExprNodeComplexIdentifier | ||||||
|  |                   && (*top_node_p)->type != kExprNodeCurlyBracesIdentifier) { | ||||||
|                 OP_MISSING; |                 OP_MISSING; | ||||||
|               } |               } | ||||||
|             } |             } | ||||||
|   | |||||||
| @@ -1059,7 +1059,7 @@ describe('Expressions parser', function() | |||||||
|       hl('CallingParenthesis', ')'), |       hl('CallingParenthesis', ')'), | ||||||
|     }) |     }) | ||||||
|   end) |   end) | ||||||
|   itp('works with identifiers', function() |   itp('works with variable names, including curly braces ones', function() | ||||||
|     check_parsing('var', 0, { |     check_parsing('var', 0, { | ||||||
|         ast = { |         ast = { | ||||||
|           'PlainIdentifier(scope=0,ident=var):0:0:var', |           'PlainIdentifier(scope=0,ident=var):0:0:var', | ||||||
| @@ -1084,16 +1084,6 @@ describe('Expressions parser', function() | |||||||
|       hl('IdentifierScope', 'g'), |       hl('IdentifierScope', 'g'), | ||||||
|       hl('IdentifierScopeDelimiter', ':'), |       hl('IdentifierScopeDelimiter', ':'), | ||||||
|     }) |     }) | ||||||
|   end) |  | ||||||
|   itp('works with curly braces', function() |  | ||||||
|     check_parsing('{}', 0, { |  | ||||||
|       ast = { |  | ||||||
|         'DictLiteral(-di):0:0:{', |  | ||||||
|       }, |  | ||||||
|     }, { |  | ||||||
|       hl('Dict', '{'), |  | ||||||
|       hl('Dict', '}'), |  | ||||||
|     }) |  | ||||||
|     check_parsing('{a}', 0, { |     check_parsing('{a}', 0, { | ||||||
|       --           012 |       --           012 | ||||||
|       ast = { |       ast = { | ||||||
| @@ -1167,6 +1157,209 @@ describe('Expressions parser', function() | |||||||
|       hl('Register', '@a'), |       hl('Register', '@a'), | ||||||
|       hl('Curly', '}'), |       hl('Curly', '}'), | ||||||
|     }) |     }) | ||||||
|  |     check_parsing('{@a}{@b}', 0, { | ||||||
|  |       --           01234567 | ||||||
|  |       ast = { | ||||||
|  |         { | ||||||
|  |           'ComplexIdentifier:0:4:', | ||||||
|  |           children = { | ||||||
|  |             { | ||||||
|  |               'CurlyBracesIdentifier(-di):0:0:{', | ||||||
|  |               children = { | ||||||
|  |                 'Register(name=a):0:1:@a', | ||||||
|  |               }, | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |               'CurlyBracesIdentifier(--i):0:4:{', | ||||||
|  |               children = { | ||||||
|  |                 'Register(name=b):0:5:@b', | ||||||
|  |               }, | ||||||
|  |             }, | ||||||
|  |           }, | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |     }, { | ||||||
|  |       hl('Curly', '{'), | ||||||
|  |       hl('Register', '@a'), | ||||||
|  |       hl('Curly', '}'), | ||||||
|  |       hl('Curly', '{'), | ||||||
|  |       hl('Register', '@b'), | ||||||
|  |       hl('Curly', '}'), | ||||||
|  |     }) | ||||||
|  |     check_parsing('g:{@a}', 0, { | ||||||
|  |       --           01234567 | ||||||
|  |       ast = { | ||||||
|  |         { | ||||||
|  |           'ComplexIdentifier:0:2:', | ||||||
|  |           children = { | ||||||
|  |             'PlainIdentifier(scope=g,ident=):0:0:g:', | ||||||
|  |             { | ||||||
|  |               'CurlyBracesIdentifier(--i):0:2:{', | ||||||
|  |               children = { | ||||||
|  |                 'Register(name=a):0:3:@a', | ||||||
|  |               }, | ||||||
|  |             }, | ||||||
|  |           }, | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |     }, { | ||||||
|  |       hl('IdentifierScope', 'g'), | ||||||
|  |       hl('IdentifierScopeDelimiter', ':'), | ||||||
|  |       hl('Curly', '{'), | ||||||
|  |       hl('Register', '@a'), | ||||||
|  |       hl('Curly', '}'), | ||||||
|  |     }) | ||||||
|  |     check_parsing('{@a}_test', 0, { | ||||||
|  |       --           012345678 | ||||||
|  |       ast = { | ||||||
|  |         { | ||||||
|  |           'ComplexIdentifier:0:4:', | ||||||
|  |           children = { | ||||||
|  |             { | ||||||
|  |               'CurlyBracesIdentifier(-di):0:0:{', | ||||||
|  |               children = { | ||||||
|  |                 'Register(name=a):0:1:@a', | ||||||
|  |               }, | ||||||
|  |             }, | ||||||
|  |             'PlainIdentifier(scope=0,ident=_test):0:4:_test', | ||||||
|  |           }, | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |     }, { | ||||||
|  |       hl('Curly', '{'), | ||||||
|  |       hl('Register', '@a'), | ||||||
|  |       hl('Curly', '}'), | ||||||
|  |       hl('Identifier', '_test'), | ||||||
|  |     }) | ||||||
|  |     check_parsing('g:{@a}_test', 0, { | ||||||
|  |       --           01234567890 | ||||||
|  |       ast = { | ||||||
|  |         { | ||||||
|  |           'ComplexIdentifier:0:2:', | ||||||
|  |           children = { | ||||||
|  |             'PlainIdentifier(scope=g,ident=):0:0:g:', | ||||||
|  |             { | ||||||
|  |               'ComplexIdentifier:0:6:', | ||||||
|  |               children = { | ||||||
|  |                 { | ||||||
|  |                   'CurlyBracesIdentifier(--i):0:2:{', | ||||||
|  |                   children = { | ||||||
|  |                     'Register(name=a):0:3:@a', | ||||||
|  |                   }, | ||||||
|  |                 }, | ||||||
|  |                 'PlainIdentifier(scope=0,ident=_test):0:6:_test', | ||||||
|  |               }, | ||||||
|  |             }, | ||||||
|  |           }, | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |     }, { | ||||||
|  |       hl('IdentifierScope', 'g'), | ||||||
|  |       hl('IdentifierScopeDelimiter', ':'), | ||||||
|  |       hl('Curly', '{'), | ||||||
|  |       hl('Register', '@a'), | ||||||
|  |       hl('Curly', '}'), | ||||||
|  |       hl('Identifier', '_test'), | ||||||
|  |     }) | ||||||
|  |     check_parsing('g:{@a}_test()', 0, { | ||||||
|  |       --           0123456789012 | ||||||
|  |       ast = { | ||||||
|  |         { | ||||||
|  |           'Call:0:11:(', | ||||||
|  |           children = { | ||||||
|  |             { | ||||||
|  |               'ComplexIdentifier:0:2:', | ||||||
|  |               children = { | ||||||
|  |                 'PlainIdentifier(scope=g,ident=):0:0:g:', | ||||||
|  |                 { | ||||||
|  |                   'ComplexIdentifier:0:6:', | ||||||
|  |                   children = { | ||||||
|  |                     { | ||||||
|  |                       'CurlyBracesIdentifier(--i):0:2:{', | ||||||
|  |                       children = { | ||||||
|  |                         'Register(name=a):0:3:@a', | ||||||
|  |                       }, | ||||||
|  |                     }, | ||||||
|  |                     'PlainIdentifier(scope=0,ident=_test):0:6:_test', | ||||||
|  |                   }, | ||||||
|  |                 }, | ||||||
|  |               }, | ||||||
|  |             }, | ||||||
|  |           }, | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |     }, { | ||||||
|  |       hl('IdentifierScope', 'g'), | ||||||
|  |       hl('IdentifierScopeDelimiter', ':'), | ||||||
|  |       hl('Curly', '{'), | ||||||
|  |       hl('Register', '@a'), | ||||||
|  |       hl('Curly', '}'), | ||||||
|  |       hl('Identifier', '_test'), | ||||||
|  |       hl('CallingParenthesis', '('), | ||||||
|  |       hl('CallingParenthesis', ')'), | ||||||
|  |     }) | ||||||
|  |     check_parsing('{@a} ()', 0, { | ||||||
|  |       --           0123456789012 | ||||||
|  |       ast = { | ||||||
|  |         { | ||||||
|  |           'Call:0:4: (', | ||||||
|  |           children = { | ||||||
|  |             { | ||||||
|  |               'CurlyBracesIdentifier(-di):0:0:{', | ||||||
|  |               children = { | ||||||
|  |                 'Register(name=a):0:1:@a', | ||||||
|  |               }, | ||||||
|  |             }, | ||||||
|  |           }, | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |     }, { | ||||||
|  |       hl('Curly', '{'), | ||||||
|  |       hl('Register', '@a'), | ||||||
|  |       hl('Curly', '}'), | ||||||
|  |       hl('CallingParenthesis', '(', 1), | ||||||
|  |       hl('CallingParenthesis', ')'), | ||||||
|  |     }) | ||||||
|  |     check_parsing('g:{@a} ()', 0, { | ||||||
|  |       --           0123456789012 | ||||||
|  |       ast = { | ||||||
|  |         { | ||||||
|  |           'Call:0:6: (', | ||||||
|  |           children = { | ||||||
|  |             { | ||||||
|  |               'ComplexIdentifier:0:2:', | ||||||
|  |               children = { | ||||||
|  |                 'PlainIdentifier(scope=g,ident=):0:0:g:', | ||||||
|  |                 { | ||||||
|  |                   'CurlyBracesIdentifier(--i):0:2:{', | ||||||
|  |                   children = { | ||||||
|  |                     'Register(name=a):0:3:@a', | ||||||
|  |                   }, | ||||||
|  |                 }, | ||||||
|  |               }, | ||||||
|  |             }, | ||||||
|  |           }, | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |     }, { | ||||||
|  |       hl('IdentifierScope', 'g'), | ||||||
|  |       hl('IdentifierScopeDelimiter', ':'), | ||||||
|  |       hl('Curly', '{'), | ||||||
|  |       hl('Register', '@a'), | ||||||
|  |       hl('Curly', '}'), | ||||||
|  |       hl('CallingParenthesis', '(', 1), | ||||||
|  |       hl('CallingParenthesis', ')'), | ||||||
|  |     }) | ||||||
|  |   end) | ||||||
|  |   itp('works with lambdas and dictionaries', function() | ||||||
|  |     check_parsing('{}', 0, { | ||||||
|  |       ast = { | ||||||
|  |         'DictLiteral(-di):0:0:{', | ||||||
|  |       }, | ||||||
|  |     }, { | ||||||
|  |       hl('Dict', '{'), | ||||||
|  |       hl('Dict', '}'), | ||||||
|  |     }) | ||||||
|     check_parsing('{->@a}', 0, { |     check_parsing('{->@a}', 0, { | ||||||
|       ast = { |       ast = { | ||||||
|         { |         { | ||||||
| @@ -1971,8 +2164,175 @@ describe('Expressions parser', function() | |||||||
|       hl('Comma', ','), |       hl('Comma', ','), | ||||||
|       hl('Dict', '}'), |       hl('Dict', '}'), | ||||||
|     }) |     }) | ||||||
|  |     check_parsing('{({f -> g})(@h)(@i)}', 0, { | ||||||
|  |       --           01234567890123456789 | ||||||
|  |       --           0         1 | ||||||
|  |       ast = { | ||||||
|  |         { | ||||||
|  |           'CurlyBracesIdentifier(-di):0:0:{', | ||||||
|  |           children = { | ||||||
|  |             { | ||||||
|  |               'Call:0:15:(', | ||||||
|  |               children = { | ||||||
|  |                 { | ||||||
|  |                   'Call:0:11:(', | ||||||
|  |                   children = { | ||||||
|  |                     { | ||||||
|  |                       'Nested:0:1:(', | ||||||
|  |                       children = { | ||||||
|  |                         { | ||||||
|  |                           'Lambda(\\di):0:2:{', | ||||||
|  |                           children = { | ||||||
|  |                             'PlainIdentifier(scope=0,ident=f):0:3:f', | ||||||
|  |                             { | ||||||
|  |                               'Arrow:0:4: ->', | ||||||
|  |                               children = { | ||||||
|  |                                 'PlainIdentifier(scope=0,ident=g):0:7: g', | ||||||
|  |                               }, | ||||||
|  |                             }, | ||||||
|  |                           }, | ||||||
|  |                         }, | ||||||
|  |                       }, | ||||||
|  |                     }, | ||||||
|  |                     'Register(name=h):0:12:@h', | ||||||
|  |                   }, | ||||||
|  |                 }, | ||||||
|  |                 'Register(name=i):0:16:@i', | ||||||
|  |               }, | ||||||
|  |             }, | ||||||
|  |           }, | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |     }, { | ||||||
|  |       hl('Curly', '{'), | ||||||
|  |       hl('NestingParenthesis', '('), | ||||||
|  |       hl('Lambda', '{'), | ||||||
|  |       hl('Identifier', 'f'), | ||||||
|  |       hl('Arrow', '->', 1), | ||||||
|  |       hl('Identifier', 'g', 1), | ||||||
|  |       hl('Lambda', '}'), | ||||||
|  |       hl('NestingParenthesis', ')'), | ||||||
|  |       hl('CallingParenthesis', '('), | ||||||
|  |       hl('Register', '@h'), | ||||||
|  |       hl('CallingParenthesis', ')'), | ||||||
|  |       hl('CallingParenthesis', '('), | ||||||
|  |       hl('Register', '@i'), | ||||||
|  |       hl('CallingParenthesis', ')'), | ||||||
|  |       hl('Curly', '}'), | ||||||
|  |     }) | ||||||
|  |     -- FIXME the below should not crash | ||||||
|  |     check_parsing('a:{{b, c -> @d + @e + ({f -> g})(@h)}(@i)}j', 0, { | ||||||
|  |       --           01234567890123456789012345678901234567890123456 | ||||||
|  |       --           0         1         2         3         4 | ||||||
|  |       ast = { | ||||||
|  |         { | ||||||
|  |           'ComplexIdentifier:0:2:', | ||||||
|  |           children = { | ||||||
|  |             'PlainIdentifier(scope=a,ident=):0:0:g:', | ||||||
|  |             { | ||||||
|  |               'ComplexIdentifier:0:6:', | ||||||
|  |               children = { | ||||||
|  |                 { | ||||||
|  |                   'CurlyBracesIdentifier(--i):0:2:{', | ||||||
|  |                   children = { | ||||||
|  |                     { | ||||||
|  |                       'Call:0:37:(', | ||||||
|  |                       children = { | ||||||
|  |                         { | ||||||
|  |                           'Lambda(\\di):0:3:{', | ||||||
|  |                           children = { | ||||||
|  |                             { | ||||||
|  |                               'Comma:0:5:,', | ||||||
|  |                               children = { | ||||||
|  |                                 'PlainIdentifier(scope=0,ident=b):0:4:b', | ||||||
|  |                                 'PlainIdentifier(scope=0,ident=c):0:6: c', | ||||||
|  |                               }, | ||||||
|  |                             }, | ||||||
|  |                             { | ||||||
|  |                               'Arrow:0:8: ->', | ||||||
|  |                               children = { | ||||||
|  |                                 { | ||||||
|  |                                   'BinaryPlus:0:19: +', | ||||||
|  |                                   children = { | ||||||
|  |                                     { | ||||||
|  |                                       'BinaryPlus:0:14: +', | ||||||
|  |                                       children = { | ||||||
|  |                                         'Register(name=d):0:11: @d', | ||||||
|  |                                         'Register(name=e):0:16: @e', | ||||||
|  |                                       }, | ||||||
|  |                                     }, | ||||||
|  |                                     { | ||||||
|  |                                       'Call:0:32:(', | ||||||
|  |                                       children = { | ||||||
|  |                                         { | ||||||
|  |                                           'NestingParenthesis:0:21: (', | ||||||
|  |                                           children = { | ||||||
|  |                                             { | ||||||
|  |                                               'Lambda(\\di):0:23:{', | ||||||
|  |                                               children = { | ||||||
|  |                                                 'PlainIdentifier(scope=0,ident=f):0:24:f', | ||||||
|  |                                                 { | ||||||
|  |                                                   'Arrow:0:25: ->', | ||||||
|  |                                                   children = { | ||||||
|  |                                                     'PlainIdentifier(scope=0,ident=g):0:28: g', | ||||||
|  |                                                   }, | ||||||
|  |                                                 }, | ||||||
|  |                                               }, | ||||||
|  |                                             }, | ||||||
|  |                                           }, | ||||||
|  |                                         }, | ||||||
|  |                                         'Register(name=h):0:33:@h', | ||||||
|  |                                       }, | ||||||
|  |                                     }, | ||||||
|  |                                   }, | ||||||
|  |                                 }, | ||||||
|  |                               }, | ||||||
|  |                             }, | ||||||
|  |                           }, | ||||||
|  |                         }, | ||||||
|  |                         'Register(name=i):0:38:@i', | ||||||
|  |                       }, | ||||||
|  |                     }, | ||||||
|  |                     'PlainIdentifier(scope=0,ident=j):0:42:j', | ||||||
|  |                   }, | ||||||
|  |                 }, | ||||||
|  |                 'PlainIdentifier(scope=0,ident=_test):0:42:_test', | ||||||
|  |               }, | ||||||
|  |             }, | ||||||
|  |           }, | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |     }, { | ||||||
|  |       hl('IdentifierScope', 'a'), | ||||||
|  |       hl('IdentifierScopeDelimiter', ':'), | ||||||
|  |       hl('Curly', '{'), | ||||||
|  |       hl('Lambda', '{'), | ||||||
|  |       hl('Identifier', 'b'), | ||||||
|  |       hl('Comma', ','), | ||||||
|  |       hl('Identifier', 'c', 1), | ||||||
|  |       hl('Arrow', '->', 1), | ||||||
|  |       hl('Register', '@d', 1), | ||||||
|  |       hl('BinaryPlus', '+', 1), | ||||||
|  |       hl('Register', '@e', 1), | ||||||
|  |       hl('BinaryPlus', '+', 1), | ||||||
|  |       hl('NestingParenthesis', '('), | ||||||
|  |       hl('Lambda', '{'), | ||||||
|  |       hl('Identifier', 'f'), | ||||||
|  |       hl('Arrow', '->', 1), | ||||||
|  |       hl('Identifier', 'g', 1), | ||||||
|  |       hl('Lambda', '}'), | ||||||
|  |       hl('NestingParenthesis', ')'), | ||||||
|  |       hl('CallingParenthesis', '('), | ||||||
|  |       hl('Register', '@h'), | ||||||
|  |       hl('CallingParenthesis', ')'), | ||||||
|  |       hl('Lambda', '}'), | ||||||
|  |       hl('CallingParenthesis', '('), | ||||||
|  |       hl('Register', '@i'), | ||||||
|  |       hl('CallingParenthesis', ')'), | ||||||
|  |       hl('Curly', '}'), | ||||||
|  |       hl('Identifier', 'j'), | ||||||
|  |     }) | ||||||
|   end) |   end) | ||||||
|   -- FIXME: Test sequence of arrows inside and outside lambdas. |   -- FIXME: Test sequence of arrows inside and outside lambdas. | ||||||
|   -- FIXME: Test multiple arguments calling. |  | ||||||
|   -- FIXME: Test autoload character and scope in lambda arguments. |   -- FIXME: Test autoload character and scope in lambda arguments. | ||||||
| end) | end) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 ZyX
					ZyX