]> www.git.momoyon.org Git - lang.git/commitdiff
[main.c] Can parse_access()...
authormomoyon <momoyon@momoyon.org>
Thu, 15 May 2025 05:31:07 +0000 (10:31 +0500)
committermomoyon <momoyon@momoyon.org>
Thu, 15 May 2025 05:32:46 +0000 (10:32 +0500)
- [tests] Add new test parse_access.momo
- [main.c] Remove unneccesary TODO

main.c
tests/.parse_access.build.code.expected [new file with mode: 0644]
tests/.parse_access.build.err.expected [new file with mode: 0644]
tests/.parse_access.build.in.expected [new file with mode: 0644]
tests/.parse_access.build.out.expected [new file with mode: 0644]
tests/.parse_access.code.expected [new file with mode: 0644]
tests/.parse_access.err.expected [new file with mode: 0644]
tests/.parse_access.in.expected [new file with mode: 0644]
tests/.parse_access.out.expected [new file with mode: 0644]
tests/parse_access.momo [new file with mode: 0644]

diff --git a/main.c b/main.c
index b880699ba1ce10e678d22dada06f6b7da9aacbbf..62f05b3dac29051c1e80d7d214cf617fe0875de2 100644 (file)
--- 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)] <file>", 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 (file)
index 0000000..c227083
--- /dev/null
@@ -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 (file)
index 0000000..e69de29
diff --git a/tests/.parse_access.build.in.expected b/tests/.parse_access.build.in.expected
new file mode 100644 (file)
index 0000000..c4d955f
--- /dev/null
@@ -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 (file)
index 0000000..1416cc0
--- /dev/null
@@ -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 (file)
index 0000000..d7d17fc
--- /dev/null
@@ -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 (file)
index 0000000..e69de29
diff --git a/tests/.parse_access.in.expected b/tests/.parse_access.in.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_access.out.expected b/tests/.parse_access.out.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/parse_access.momo b/tests/parse_access.momo
new file mode 100644 (file)
index 0000000..468bda1
--- /dev/null
@@ -0,0 +1,2 @@
+foo.bar;
+foo.bar.baz;