commit 76ca5aba26366d1417a4f5e05d38c17a1cd25381
parent dfe1a0078939de5a486a7730ef423061594fa03d
Author: Drew DeVault <sir@cmpwn.com>
Date: Thu, 24 Dec 2020 14:17:29 -0500
parse: call expressions
Diffstat:
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: