From 4ba67b23a0765475c44cfea832b19b02473d7185 Mon Sep 17 00:00:00 2001 From: momoyon Date: Thu, 15 May 2025 10:31:07 +0500 Subject: [PATCH] [main.c] Can parse_access()... - [tests] Add new test parse_access.momo - [main.c] Remove unneccesary TODO --- main.c | 55 ++++++++++++++----------- tests/.parse_access.build.code.expected | 1 + tests/.parse_access.build.err.expected | 0 tests/.parse_access.build.in.expected | 1 + tests/.parse_access.build.out.expected | 2 + tests/.parse_access.code.expected | 1 + tests/.parse_access.err.expected | 0 tests/.parse_access.in.expected | 0 tests/.parse_access.out.expected | 0 tests/parse_access.momo | 2 + 10 files changed, 39 insertions(+), 23 deletions(-) create mode 100644 tests/.parse_access.build.code.expected create mode 100644 tests/.parse_access.build.err.expected create mode 100644 tests/.parse_access.build.in.expected create mode 100644 tests/.parse_access.build.out.expected create mode 100644 tests/.parse_access.code.expected create mode 100644 tests/.parse_access.err.expected create mode 100644 tests/.parse_access.in.expected create mode 100644 tests/.parse_access.out.expected create mode 100644 tests/parse_access.momo diff --git a/main.c b/main.c index b880699..62f05b3 100644 --- a/main.c +++ b/main.c @@ -343,7 +343,7 @@ typedef enum { struct Access_AST { Token lhs; // Eg: foo.bar // here `foo` is lhs union { - Access_AST *access; + AST *access; String_view ident_key; } rhs_as; Access_AST_rhs_kind rhs_kind; @@ -422,11 +422,11 @@ static Identifier_KV *identifier_map = {0}; /// -void usage(const char *program) { +static void usage(const char *program) { info("Usage: %s [subcommand] [flag(s)] ", program); } -void help(const char *program) { +static void help(const char *program) { usage(program); info(""); @@ -582,7 +582,7 @@ void print_ast_as_value(FILE *f, AST e) { fprintf(f, "."); switch (e.access->rhs_kind) { case ACC_RHS_ACCESS: { - + print_ast_as_value(f, *e.access->rhs_as.access); } break; case ACC_RHS_IDENT: { fprintf(f, SV_FMT, SV_ARG(e.access->rhs_as.ident_key)); @@ -803,8 +803,6 @@ AST *parse_equality(Arena *arena, Parser *p); AST *parse(Arena *arena, Parser *p); AST *parse_primary(Arena *arena, Parser *p) { - // NOTE: We can advance here because primary is the last rule - // TODO: Somehow parser_advance() here breaks it. Token t = parser_peek(p); if (t.type != TK_LEFT_PAREN) { @@ -993,26 +991,37 @@ AST *parse_access(Arena *arena, Parser *p) { Token t = parser_peek(p); if (t.type == TK_IDENT && parser_peek_by(p, 1).type == TK_DOT) { - AST *ast = (AST *)arena_alloc(arena, sizeof(AST)); - ast->loc = t.loc; - ast->access = (Access_AST *)arena_alloc(arena, sizeof(Access_AST)); - ast->kind = AST_ACCESS; - ast->access->lhs = parser_advance(p); // Eat IDENT - - parser_advance(p); // Skip . - - Token next = parser_peek(p); - - if (next.type == TK_IDENT) { - ast->access->rhs_kind = ACC_RHS_IDENT; - ast->access->rhs_as.ident_key = next.lexeme; - parser_advance(p); // Eat IDENT - return ast; - } else { + AST *current = ast; // Current access ast, we have to track this since access could be nested like `foo.bar.baz` + + while (true) { + current->loc = parser_peek(p).loc; + current->access = (Access_AST *)arena_alloc(arena, sizeof(Access_AST)); + current->kind = AST_ACCESS; + current->access->lhs = parser_advance(p); // Eat IDENT + + ASSERT(parser_match(p, TK_DOT), "We fucked up logic here"); // Skip . + + Token next = parser_peek(p); + if (next.type == TK_IDENT) { + Token next_next = parser_peek_by(p, 1); + if (next_next.type == TK_DOT) { + current->access->rhs_kind = ACC_RHS_ACCESS; + current->access->rhs_as.access = (AST *)arena_alloc(arena, sizeof(AST)); + current = current->access->rhs_as.access; + continue; + } else { + current->access->rhs_kind = ACC_RHS_IDENT; + current->access->rhs_as.ident_key = next.lexeme; + parser_advance(p); // Eat IDENT + return ast; + } + } + error_pretty(next.loc, (*p->lexer), "Expected identifier after . but got `%s`", token_type_as_str(next.type)); + return NULL; } - ASSERT(false, "parse_access() is unimplemented!"); + ASSERT(false, "UNREACHABLE!"); } return parse_subscript(arena, p); diff --git a/tests/.parse_access.build.code.expected b/tests/.parse_access.build.code.expected new file mode 100644 index 0000000..c227083 --- /dev/null +++ b/tests/.parse_access.build.code.expected @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/tests/.parse_access.build.err.expected b/tests/.parse_access.build.err.expected new file mode 100644 index 0000000..e69de29 diff --git a/tests/.parse_access.build.in.expected b/tests/.parse_access.build.in.expected new file mode 100644 index 0000000..c4d955f --- /dev/null +++ b/tests/.parse_access.build.in.expected @@ -0,0 +1 @@ +dump_ast \ No newline at end of file diff --git a/tests/.parse_access.build.out.expected b/tests/.parse_access.build.out.expected new file mode 100644 index 0000000..1416cc0 --- /dev/null +++ b/tests/.parse_access.build.out.expected @@ -0,0 +1,2 @@ +parse_access.momo:1:0 [ACCESS] 'foo.bar' +parse_access.momo:2:0 [ACCESS] 'foo.bar.baz' diff --git a/tests/.parse_access.code.expected b/tests/.parse_access.code.expected new file mode 100644 index 0000000..d7d17fc --- /dev/null +++ b/tests/.parse_access.code.expected @@ -0,0 +1 @@ +-1 \ No newline at end of file diff --git a/tests/.parse_access.err.expected b/tests/.parse_access.err.expected new file mode 100644 index 0000000..e69de29 diff --git a/tests/.parse_access.in.expected b/tests/.parse_access.in.expected new file mode 100644 index 0000000..e69de29 diff --git a/tests/.parse_access.out.expected b/tests/.parse_access.out.expected new file mode 100644 index 0000000..e69de29 diff --git a/tests/parse_access.momo b/tests/parse_access.momo new file mode 100644 index 0000000..468bda1 --- /dev/null +++ b/tests/parse_access.momo @@ -0,0 +1,2 @@ +foo.bar; +foo.bar.baz; -- 2.39.5