mirror of
https://github.com/neovim/neovim.git
synced 2024-12-20 11:15:14 -07:00
viml/parser/expressions: Make commas actually work when calling
This commit is contained in:
parent
7980614650
commit
d4782fb1ca
@ -395,6 +395,43 @@ viml_pexpr_next_token_adv_return:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef UNIT_TESTING
|
||||||
|
#include <stdio.h>
|
||||||
|
REAL_FATTR_UNUSED
|
||||||
|
static inline void viml_pexpr_debug_print_ast_node(
|
||||||
|
const ExprASTNode *const *const eastnode_p,
|
||||||
|
const char *const prefix)
|
||||||
|
{
|
||||||
|
if (*eastnode_p == NULL) {
|
||||||
|
fprintf(stderr, "%s %p : NULL\n", prefix, (void *)eastnode_p);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "%s %p : %p : %c : %zu:%zu:%zu\n",
|
||||||
|
prefix, (void *)eastnode_p, (void *)(*eastnode_p),
|
||||||
|
(*eastnode_p)->type, (*eastnode_p)->start.line,
|
||||||
|
(*eastnode_p)->start.col, (*eastnode_p)->len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
REAL_FATTR_UNUSED
|
||||||
|
static inline void viml_pexpr_debug_print_ast_stack(
|
||||||
|
const ExprASTStack *const ast_stack,
|
||||||
|
const char *const msg)
|
||||||
|
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
|
||||||
|
{
|
||||||
|
fprintf(stderr, "\n%sstack: %zu:\n", msg, kv_size(*ast_stack));
|
||||||
|
for (size_t i = 0; i < kv_size(*ast_stack); i++) {
|
||||||
|
viml_pexpr_debug_print_ast_node(
|
||||||
|
(const ExprASTNode *const *)kv_A(*ast_stack, i),
|
||||||
|
"-");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#define PSTACK(msg) \
|
||||||
|
viml_pexpr_debug_print_ast_stack(&ast_stack, #msg)
|
||||||
|
#define PSTACK_P(msg) \
|
||||||
|
viml_pexpr_debug_print_ast_stack(ast_stack, #msg)
|
||||||
|
#define PNODE_P(eastnode_p, msg) \
|
||||||
|
viml_pexpr_debug_print_ast_node((const ExprASTNode *const *)ast_stack, #msg)
|
||||||
|
#endif
|
||||||
|
|
||||||
// start = s ternary_expr s EOC
|
// start = s ternary_expr s EOC
|
||||||
// ternary_expr = binop_expr
|
// ternary_expr = binop_expr
|
||||||
// ( s Question s ternary_expr s Colon s ternary_expr s )?
|
// ( s Question s ternary_expr s Colon s ternary_expr s )?
|
||||||
@ -560,6 +597,9 @@ static const ExprOpLvl node_type_to_op_lvl[] = {
|
|||||||
[kExprNodeOpMissing] = kEOpLvlMultiplication,
|
[kExprNodeOpMissing] = kEOpLvlMultiplication,
|
||||||
|
|
||||||
[kExprNodeNested] = kEOpLvlParens,
|
[kExprNodeNested] = kEOpLvlParens,
|
||||||
|
// Note: it is kEOpLvlSubscript for “binary operator” itself, but
|
||||||
|
// kEOpLvlParens when it comes to inside the parenthesis.
|
||||||
|
[kExprNodeCall] = kEOpLvlParens,
|
||||||
|
|
||||||
[kExprNodeUnknownFigure] = kEOpLvlParens,
|
[kExprNodeUnknownFigure] = kEOpLvlParens,
|
||||||
[kExprNodeLambda] = kEOpLvlParens,
|
[kExprNodeLambda] = kEOpLvlParens,
|
||||||
@ -578,7 +618,6 @@ static const ExprOpLvl node_type_to_op_lvl[] = {
|
|||||||
[kExprNodeUnaryPlus] = kEOpLvlUnary,
|
[kExprNodeUnaryPlus] = kEOpLvlUnary,
|
||||||
|
|
||||||
[kExprNodeSubscript] = kEOpLvlSubscript,
|
[kExprNodeSubscript] = kEOpLvlSubscript,
|
||||||
[kExprNodeCall] = kEOpLvlSubscript,
|
|
||||||
|
|
||||||
[kExprNodeComplexIdentifier] = kEOpLvlComplexIdentifier,
|
[kExprNodeComplexIdentifier] = kEOpLvlComplexIdentifier,
|
||||||
[kExprNodePlainIdentifier] = kEOpLvlComplexIdentifier,
|
[kExprNodePlainIdentifier] = kEOpLvlComplexIdentifier,
|
||||||
@ -593,6 +632,7 @@ static const ExprOpAssociativity node_type_to_op_ass[] = {
|
|||||||
[kExprNodeOpMissing] = kEOpAssNo,
|
[kExprNodeOpMissing] = kEOpAssNo,
|
||||||
|
|
||||||
[kExprNodeNested] = kEOpAssNo,
|
[kExprNodeNested] = kEOpAssNo,
|
||||||
|
[kExprNodeCall] = kEOpAssNo,
|
||||||
|
|
||||||
[kExprNodeUnknownFigure] = kEOpAssLeft,
|
[kExprNodeUnknownFigure] = kEOpAssLeft,
|
||||||
[kExprNodeLambda] = kEOpAssNo,
|
[kExprNodeLambda] = kEOpAssNo,
|
||||||
@ -619,7 +659,6 @@ static const ExprOpAssociativity node_type_to_op_ass[] = {
|
|||||||
[kExprNodeUnaryPlus] = kEOpAssNo,
|
[kExprNodeUnaryPlus] = kEOpAssNo,
|
||||||
|
|
||||||
[kExprNodeSubscript] = kEOpAssLeft,
|
[kExprNodeSubscript] = kEOpAssLeft,
|
||||||
[kExprNodeCall] = kEOpAssLeft,
|
|
||||||
|
|
||||||
[kExprNodePlainIdentifier] = kEOpAssLeft,
|
[kExprNodePlainIdentifier] = kEOpAssLeft,
|
||||||
[kExprNodeComplexIdentifier] = kEOpAssLeft,
|
[kExprNodeComplexIdentifier] = kEOpAssLeft,
|
||||||
@ -629,43 +668,6 @@ static const ExprOpAssociativity node_type_to_op_ass[] = {
|
|||||||
[kExprNodeListLiteral] = kEOpAssNo,
|
[kExprNodeListLiteral] = kEOpAssNo,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef UNIT_TESTING
|
|
||||||
#include <stdio.h>
|
|
||||||
REAL_FATTR_UNUSED
|
|
||||||
static inline void viml_pexpr_debug_print_ast_node(
|
|
||||||
const ExprASTNode *const *const eastnode_p,
|
|
||||||
const char *const prefix)
|
|
||||||
{
|
|
||||||
if (*eastnode_p == NULL) {
|
|
||||||
fprintf(stderr, "%s %p : NULL\n", prefix, (void *)eastnode_p);
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "%s %p : %p : %c : %zu:%zu:%zu\n",
|
|
||||||
prefix, (void *)eastnode_p, (void *)(*eastnode_p),
|
|
||||||
(*eastnode_p)->type, (*eastnode_p)->start.line,
|
|
||||||
(*eastnode_p)->start.col, (*eastnode_p)->len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
REAL_FATTR_UNUSED
|
|
||||||
static inline void viml_pexpr_debug_print_ast_stack(
|
|
||||||
const ExprASTStack *const ast_stack,
|
|
||||||
const char *const msg)
|
|
||||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
|
|
||||||
{
|
|
||||||
fprintf(stderr, "\n%sstack: %zu:\n", msg, kv_size(*ast_stack));
|
|
||||||
for (size_t i = 0; i < kv_size(*ast_stack); i++) {
|
|
||||||
viml_pexpr_debug_print_ast_node(
|
|
||||||
(const ExprASTNode *const *)kv_A(*ast_stack, i),
|
|
||||||
"-");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#define PSTACK(msg) \
|
|
||||||
viml_pexpr_debug_print_ast_stack(&ast_stack, #msg)
|
|
||||||
#define PSTACK_P(msg) \
|
|
||||||
viml_pexpr_debug_print_ast_stack(ast_stack, #msg)
|
|
||||||
#define PNODE_P(eastnode_p, msg) \
|
|
||||||
viml_pexpr_debug_print_ast_node((const ExprASTNode *const *)ast_stack, #msg)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Handle binary operator
|
/// Handle binary operator
|
||||||
///
|
///
|
||||||
/// This function is responsible for handling priority levels as well.
|
/// This function is responsible for handling priority levels as well.
|
||||||
@ -679,17 +681,24 @@ static void viml_pexpr_handle_bop(ExprASTStack *const ast_stack,
|
|||||||
ExprOpLvl top_node_lvl;
|
ExprOpLvl top_node_lvl;
|
||||||
ExprOpAssociativity top_node_ass;
|
ExprOpAssociativity top_node_ass;
|
||||||
assert(kv_size(*ast_stack));
|
assert(kv_size(*ast_stack));
|
||||||
const ExprOpLvl bop_node_lvl = node_type_to_op_lvl[bop_node->type];
|
#define NODE_LVL(typ) \
|
||||||
|
(bop_node->type == kExprNodeCall && typ == kExprNodeCall \
|
||||||
|
? kEOpLvlSubscript \
|
||||||
|
: node_type_to_op_lvl[typ])
|
||||||
|
#define NODE_ASS(typ) \
|
||||||
|
(bop_node->type == kExprNodeCall && typ == kExprNodeCall \
|
||||||
|
? kEOpAssLeft \
|
||||||
|
: node_type_to_op_ass[typ])
|
||||||
|
const ExprOpLvl bop_node_lvl = NODE_LVL(bop_node->type);
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
const ExprOpAssociativity bop_node_ass = node_type_to_op_ass[bop_node->type];
|
const ExprOpAssociativity bop_node_ass = NODE_ASS(bop_node->type);
|
||||||
#endif
|
#endif
|
||||||
do {
|
do {
|
||||||
ExprASTNode **new_top_node_p = kv_last(*ast_stack);
|
ExprASTNode **new_top_node_p = kv_last(*ast_stack);
|
||||||
ExprASTNode *new_top_node = *new_top_node_p;
|
ExprASTNode *new_top_node = *new_top_node_p;
|
||||||
assert(new_top_node != NULL);
|
assert(new_top_node != NULL);
|
||||||
const ExprOpLvl new_top_node_lvl = node_type_to_op_lvl[new_top_node->type];
|
const ExprOpLvl new_top_node_lvl = NODE_LVL(new_top_node->type);
|
||||||
const ExprOpAssociativity new_top_node_ass = (
|
const ExprOpAssociativity new_top_node_ass = NODE_ASS(new_top_node->type);
|
||||||
node_type_to_op_ass[new_top_node->type]);
|
|
||||||
assert(bop_node_lvl != new_top_node_lvl
|
assert(bop_node_lvl != new_top_node_lvl
|
||||||
|| bop_node_ass == new_top_node_ass);
|
|| bop_node_ass == new_top_node_ass);
|
||||||
if (top_node_p != NULL
|
if (top_node_p != NULL
|
||||||
@ -742,6 +751,8 @@ static void viml_pexpr_handle_bop(ExprASTStack *const ast_stack,
|
|||||||
*want_node_p = (*want_node_p == kENodeArgumentSeparator
|
*want_node_p = (*want_node_p == kENodeArgumentSeparator
|
||||||
? kENodeArgument
|
? kENodeArgument
|
||||||
: kENodeValue);
|
: kENodeValue);
|
||||||
|
#undef NODE_ASS
|
||||||
|
#undef NODE_LVL
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParserPosition literal based on ParserPosition pos with columns shifted
|
/// ParserPosition literal based on ParserPosition pos with columns shifted
|
||||||
|
@ -901,6 +901,48 @@ describe('Expressions parser', function()
|
|||||||
hl('CallingParenthesis', '('),
|
hl('CallingParenthesis', '('),
|
||||||
hl('Register', '@b'),
|
hl('Register', '@b'),
|
||||||
})
|
})
|
||||||
|
check_parsing('@a(@b, @c, @d, @e)', 0, {
|
||||||
|
-- 012345678901234567
|
||||||
|
-- 0 1
|
||||||
|
ast = {
|
||||||
|
{
|
||||||
|
'Call:0:2:(',
|
||||||
|
children = {
|
||||||
|
'Register(name=a):0:0:@a',
|
||||||
|
{
|
||||||
|
'Comma:0:5:,',
|
||||||
|
children = {
|
||||||
|
'Register(name=b):0:3:@b',
|
||||||
|
{
|
||||||
|
'Comma:0:9:,',
|
||||||
|
children = {
|
||||||
|
'Register(name=c):0:6: @c',
|
||||||
|
{
|
||||||
|
'Comma:0:13:,',
|
||||||
|
children = {
|
||||||
|
'Register(name=d):0:10: @d',
|
||||||
|
'Register(name=e):0:14: @e',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
hl('Register', '@a'),
|
||||||
|
hl('CallingParenthesis', '('),
|
||||||
|
hl('Register', '@b'),
|
||||||
|
hl('Comma', ','),
|
||||||
|
hl('Register', '@c', 1),
|
||||||
|
hl('Comma', ','),
|
||||||
|
hl('Register', '@d', 1),
|
||||||
|
hl('Comma', ','),
|
||||||
|
hl('Register', '@e', 1),
|
||||||
|
hl('CallingParenthesis', ')'),
|
||||||
|
})
|
||||||
end)
|
end)
|
||||||
itp('works with identifiers', function()
|
itp('works with identifiers', function()
|
||||||
check_parsing('var', 0, {
|
check_parsing('var', 0, {
|
||||||
|
Loading…
Reference in New Issue
Block a user