harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 76ca5aba26366d1417a4f5e05d38c17a1cd25381
parent dfe1a0078939de5a486a7730ef423061594fa03d
Author: Drew DeVault <sir@cmpwn.com>
Date:   Thu, 24 Dec 2020 14:17:29 -0500

parse: call expressions

Diffstat:
Minclude/ast.h | 12++++++++++++
Msrc/parse.c | 42+++++++++++++++++++++++++++++++++++++++++-
2 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/include/ast.h b/include/ast.h @@ -108,6 +108,17 @@ struct ast_expression_binding { struct ast_expression_binding *next; }; +struct ast_call_argument { + bool variadic; + struct ast_expression *value; + struct ast_call_argument *next; +}; + +struct ast_expression_call { + struct ast_expression *lvalue; + struct ast_call_argument *args; +}; + struct ast_expression_constant { enum type_storage storage; union { @@ -151,6 +162,7 @@ struct ast_expression { struct ast_expression_assign assign; struct ast_expression_binarithm binarithm; struct ast_expression_binding binding; + struct ast_expression_call call; struct ast_expression_constant constant; struct ast_expression_list list; struct ast_expression_measure measure; diff --git a/src/parse.c b/src/parse.c @@ -527,6 +527,46 @@ parse_measurement_expression(struct parser *par) } static struct ast_expression * +parse_call_expression(struct parser *par, struct ast_expression *lvalue) +{ + trenter(TR_PARSE, "call"); + + struct ast_expression *expr = calloc(1, sizeof(struct ast_expression)); + expr->type = EXPR_CALL; + expr->call.lvalue = lvalue; + + struct token tok; + struct ast_call_argument *arg, **next = &expr->call.args; + while (lex(par->lex, &tok) != T_RPAREN) { + unlex(par->lex, &tok); + + arg = *next = calloc(1, sizeof(struct ast_call_argument)); + arg->value = parse_complex_expression(par); + + if (lex(par->lex, &tok) == T_ELLIPSIS) { + arg->variadic = true; + } else { + unlex(par->lex, &tok); + } + + switch (lex(par->lex, &tok)) { + case T_COMMA: + break; + case T_RPAREN: + unlex(par->lex, &tok); + break; + default: + synassert(false, &tok, T_COMMA, T_RPAREN, T_EOF); + } + + next = &arg->next; + } + + trleave(TR_PARSE, NULL); + return expr; +} + +static struct ast_expression * parse_postfix_expression(struct parser *par) { trace(TR_PARSE, "postfix"); @@ -555,7 +595,7 @@ parse_postfix_expression(struct parser *par) switch (lex(par->lex, &tok)) { case T_LPAREN: - assert(0); // TODO: call expression + return parse_call_expression(par, lvalue); case T_DOT: assert(0); // TODO: field access expression case T_LBRACKET: