aboutsummaryrefslogtreecommitdiff
path: root/parse.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-02-29 13:49:24 -0500
committerBruce Hill <bruce@bruce-hill.com>2024-02-29 13:49:24 -0500
commit4dc70c84d4226174d44f1b53599d08de7a4e83aa (patch)
treeb0a612f4a3b61331caa59874fac417142c208d89 /parse.c
parent8171a38b7130849e3049a4ea15a4fd06c154d9b0 (diff)
First working method calls
Diffstat (limited to 'parse.c')
-rw-r--r--parse.c48
1 files changed, 47 insertions, 1 deletions
diff --git a/parse.c b/parse.c
index 5d1880c9..b349bcb3 100644
--- a/parse.c
+++ b/parse.c
@@ -65,6 +65,7 @@ static inline bool comment(const char **pos);
static inline bool indent(parse_ctx_t *ctx, const char **pos);
static inline binop_e match_binary_operator(const char **pos);
static ast_t *parse_fncall_suffix(parse_ctx_t *ctx, ast_t *fn, bool is_extern);
+static ast_t *parse_method_call_suffix(parse_ctx_t *ctx, ast_t *self);
static ast_t *parse_field_suffix(parse_ctx_t *ctx, ast_t *lhs);
static ast_t *parse_index_suffix(parse_ctx_t *ctx, ast_t *lhs);
static arg_ast_t *parse_args(parse_ctx_t *ctx, const char **pos, bool allow_unnamed);
@@ -1150,6 +1151,7 @@ PARSER(parse_term) {
progress = (false
|| (new_term=parse_index_suffix(ctx, term))
|| (new_term=parse_field_suffix(ctx, term))
+ || (new_term=parse_method_call_suffix(ctx, term))
|| (new_term=parse_fncall_suffix(ctx, term, NORMAL_FUNCTION))
);
if (progress) term = new_term;
@@ -1157,6 +1159,46 @@ PARSER(parse_term) {
return term;
}
+ast_t *parse_method_call_suffix(parse_ctx_t *ctx, ast_t *self) {
+ if (!self) return NULL;
+
+ const char *start = self->start;
+ const char *pos = self->end;
+
+ spaces(&pos);
+ if (!match(&pos, ":")) return NULL;
+ const char *fn = get_id(&pos);
+ spaces(&pos);
+ if (!match(&pos, "(")) return NULL;
+ whitespace(&pos);
+
+ arg_ast_t *args = NULL;
+ for (;;) {
+ const char *arg_start = pos;
+ const char *name = get_id(&pos);
+ whitespace(&pos);
+ if (!name || !match(&pos, "="))
+ pos = arg_start;
+
+ ast_t *arg = optional(ctx, &pos, parse_expr);
+ if (!arg) {
+ if (name) parser_err(ctx, arg_start, pos, "I expected an argument here");
+ break;
+ }
+ args = new(arg_ast_t, .name=name, .value=arg, .next=args);
+ if (!match_separator(&pos))
+ break;
+ }
+ REVERSE_LIST(args);
+
+ whitespace(&pos);
+
+ if (!match(&pos, ")"))
+ parser_err(ctx, start, pos, "This parenthesis is unclosed");
+
+ return NewAST(ctx->file, start, pos, MethodCall, .self=self, .name=fn, .args=args);
+}
+
ast_t *parse_fncall_suffix(parse_ctx_t *ctx, ast_t *fn, bool is_extern) {
if (!fn) return NULL;
@@ -1249,6 +1291,7 @@ static ast_t *parse_infix_expr(parse_ctx_t *ctx, const char *pos, int min_tightn
progress = (false
|| (new_term=parse_index_suffix(ctx, key))
|| (new_term=parse_field_suffix(ctx, key))
+ || (new_term=parse_method_call_suffix(ctx, key))
|| (new_term=parse_fncall_suffix(ctx, key, NORMAL_FUNCTION))
);
if (progress) key = new_term;
@@ -1361,7 +1404,10 @@ PARSER(parse_statement) {
ast_t *new_stmt;
progress = false;
if (stmt->tag == Var)
- progress = (new_stmt=parse_fncall_suffix(ctx, stmt, NORMAL_FUNCTION));
+ progress = (false
+ || (new_stmt=parse_method_call_suffix(ctx, stmt))
+ || (new_stmt=parse_fncall_suffix(ctx, stmt, NORMAL_FUNCTION))
+ );
if (progress) stmt = new_stmt;
}