]> www.git.momoyon.org Git - lang.git/commitdiff
[main.c] WIP: parse_subscript()...
authormomoyon <momoyon@momoyon.org>
Mon, 12 May 2025 19:28:53 +0000 (00:28 +0500)
committermomoyon <momoyon@momoyon.org>
Mon, 12 May 2025 19:28:53 +0000 (00:28 +0500)
- [tests] Add expected output files of previous tests.

49 files changed:
main.c
tests/.parse_comparision.build.code.expected [new file with mode: 0644]
tests/.parse_comparision.build.err.expected [new file with mode: 0644]
tests/.parse_comparision.build.in.expected [new file with mode: 0644]
tests/.parse_comparision.build.out.expected [new file with mode: 0644]
tests/.parse_comparision.code.expected [new file with mode: 0644]
tests/.parse_comparision.err.expected [new file with mode: 0644]
tests/.parse_comparision.in.expected [new file with mode: 0644]
tests/.parse_comparision.out.expected [new file with mode: 0644]
tests/.parse_equality.build.code.expected [new file with mode: 0644]
tests/.parse_equality.build.err.expected [new file with mode: 0644]
tests/.parse_equality.build.in.expected [new file with mode: 0644]
tests/.parse_equality.build.out.expected [new file with mode: 0644]
tests/.parse_equality.code.expected [new file with mode: 0644]
tests/.parse_equality.err.expected [new file with mode: 0644]
tests/.parse_equality.in.expected [new file with mode: 0644]
tests/.parse_equality.out.expected [new file with mode: 0644]
tests/.parse_factor.build.code.expected [new file with mode: 0644]
tests/.parse_factor.build.err.expected [new file with mode: 0644]
tests/.parse_factor.build.in.expected [new file with mode: 0644]
tests/.parse_factor.build.out.expected [new file with mode: 0644]
tests/.parse_factor.code.expected [new file with mode: 0644]
tests/.parse_factor.err.expected [new file with mode: 0644]
tests/.parse_factor.in.expected [new file with mode: 0644]
tests/.parse_factor.out.expected [new file with mode: 0644]
tests/.parse_primary.build.code.expected [new file with mode: 0644]
tests/.parse_primary.build.err.expected [new file with mode: 0644]
tests/.parse_primary.build.in.expected [new file with mode: 0644]
tests/.parse_primary.build.out.expected [new file with mode: 0644]
tests/.parse_primary.code.expected [new file with mode: 0644]
tests/.parse_primary.err.expected [new file with mode: 0644]
tests/.parse_primary.in.expected [new file with mode: 0644]
tests/.parse_primary.out.expected [new file with mode: 0644]
tests/.parse_term.build.code.expected [new file with mode: 0644]
tests/.parse_term.build.err.expected [new file with mode: 0644]
tests/.parse_term.build.in.expected [new file with mode: 0644]
tests/.parse_term.build.out.expected [new file with mode: 0644]
tests/.parse_term.code.expected [new file with mode: 0644]
tests/.parse_term.err.expected [new file with mode: 0644]
tests/.parse_term.in.expected [new file with mode: 0644]
tests/.parse_term.out.expected [new file with mode: 0644]
tests/.parse_unary.build.code.expected [new file with mode: 0644]
tests/.parse_unary.build.err.expected [new file with mode: 0644]
tests/.parse_unary.build.in.expected [new file with mode: 0644]
tests/.parse_unary.build.out.expected [new file with mode: 0644]
tests/.parse_unary.code.expected [new file with mode: 0644]
tests/.parse_unary.err.expected [new file with mode: 0644]
tests/.parse_unary.in.expected [new file with mode: 0644]
tests/.parse_unary.out.expected [new file with mode: 0644]

diff --git a/main.c b/main.c
index 39459dd18c8191456b8ba39ad4ee34db6bb26553..3c8db1b4ac4e04c1df8ad14bc7fd20544e26865b 100644 (file)
--- a/main.c
+++ b/main.c
@@ -33,7 +33,9 @@ static bool DEBUG_PRINT = false;
 // factor          -> unary ( ( "/" | "*" ) unary )* ;
 // unary           -> ( "!" | "-" ) unary
 //                | primary ;
-// array subscript -> IDENT "[" NUMBER "]"
+// // TODO:                 Ig there could be a funcall here aswell?
+//                                V
+// array subscript -> IDENT "[" ( IDENT | NUMBER ) "]"
 // funcalls        -> IDENT "(" ( ast "," )* ")"
 //                   | IDENT "(" IDENT ")"
 // suffix          -> IDENT ( "++" | "--" )
@@ -281,6 +283,7 @@ typedef struct Literal Literal;
 typedef enum   Literal_kind Literal_kind;
 typedef struct Binary_expr Binary_expr;
 typedef struct Funcall_AST Funcall_AST;
+typedef struct Subscript_AST Subscript_AST;
 typedef struct Unary_expr Unary_expr;
 typedef struct Primary_expr Primary_expr;
 typedef struct AST AST;
@@ -309,6 +312,7 @@ struct Literal {
 };
 
 void print_literal(FILE *f, Literal value);
+
 struct Unary_expr {
     Token operator;
     AST *operand;
@@ -326,6 +330,11 @@ struct Funcall_AST {
     ASTs arguments;
 };
 
+struct Subscript_AST {
+    String_view identifier_key;
+    Primary_expr *index_expr;
+};
+
 struct Binary_expr {
     Token operator;
     AST *lhs;
@@ -352,6 +361,7 @@ typedef enum {
     AST_UNARY,
     AST_PRIMARY,
     AST_FUNCALL,
+    AST_SUBSCRIPT,
     AST_COUNT,
 } AST_kind;
 
@@ -359,10 +369,11 @@ const char *ast_kind_as_str(AST_kind k);
 
 struct AST {
     AST_kind kind;
-    Binary_expr *bin_ast;
+    Binary_expr *bin_expr;
     Primary_expr *prim_expr;
-    Unary_expr *unary_ast;
+    Unary_expr *unary_expr;
     Funcall_AST *funcall;
+    Subscript_AST *subscript;
     Location loc;
 };
 
@@ -470,6 +481,7 @@ const char *expr_kind_as_str(AST_kind k) {
         case AST_UNARY: return "UNARY";
         case AST_PRIMARY: return "PRIMARY";
         case AST_FUNCALL: return "FUNCALL";
+        case AST_SUBSCRIPT: return "SUBSCRIPT";
         case AST_COUNT:
         default: ASSERT(false, "UNREACHABLE!");
     }
@@ -535,6 +547,19 @@ void print_ast_as_value(FILE *f, AST e) {
             }
             fprintf(f, ")");
         } break;
+        case AST_SUBSCRIPT: {
+            fprintf(f, SV_FMT, SV_ARG(e.subscript->identifier_key));
+            fprintf(f, "[");
+            print_primary_expr(f, e.subscript->index_expr);
+            // if (e.subscript->index_expr->kind == PRIMARY_VALUE) {
+            //     print_literal(f, e.subscript->index_expr->value);
+            // } else if (e.subscript->index_expr->kind == PRIMARY_IDENT) {
+            //     print_loc(f, e.subscript->index_expr->value);
+            // } else {
+            //     ASSERT(false, "This shouldnt happen");
+            // }
+            fprintf(f, "]");
+        } break;
         case AST_COUNT:
         default: ASSERT(false, "UNREACHABLE!");
     }
@@ -735,7 +760,7 @@ bool parser_eof(Parser *p) {
 AST *parse_primary(Arena *arena, Parser *p);
 AST *parse_suffix(Arena *arena, Parser *p);
 AST *parse_funcall(Arena *arena, Parser *p);
-AST *parse_array_subscript(Arena *arena, Parser *p);
+AST *parse_subscript(Arena *arena, Parser *p);
 AST *parse_unary(Arena *arena, Parser *p);
 AST *parse_factor(Arena *arena, Parser *p);
 AST *parse_comparision(Arena *arena, Parser *p);
@@ -905,7 +930,37 @@ AST *parse_funcall(Arena *arena, Parser *p) {
     return parse_suffix(arena, p);
 }
 
-AST *parse_array_subscript(Arena *arena, Parser *p) {
+AST *parse_subscript(Arena *arena, Parser *p) {
+    Token t = parser_peek(p);
+
+    if (t.type == TK_IDENT && parser_peek_by(p, 1).type == TK_LEFT_SQUARE_BRACE) {
+        AST *ast = (AST *)arena_alloc(arena, sizeof(AST));
+        ast->loc = t.loc;
+        ast->subscript = (Subscript_AST *)arena_alloc(arena, sizeof(Subscript_AST));
+        ast->kind = AST_SUBSCRIPT;
+
+        ast->subscript->identifier_key = parser_advance(p).lexeme; // Eat IDENT
+        parser_advance(p); // Skip [
+
+        Token next = parser_peek(p);
+        if (next.type != TK_INT &&
+            next.type != TK_IDENT) {
+            error_pretty(next.loc, (*p->lexer), "Expected a positive integer literal or variable but got `%s`", token_type_as_str(next.type));
+            return NULL;
+        }
+        AST *index_ast = parse_primary(arena, p);
+        if (index_ast == NULL) return NULL;
+        ASSERT(index_ast->prim_expr->value.kind == LIT_INT ||
+               index_ast->prim_expr->kind == PRIMARY_IDENT,
+               "parse_primary() error; should be either integer primary or ident primary!");
+        ast->subscript->index_expr = index_ast->prim_expr;
+
+        if (!parser_match(p, TK_RIGHT_SQUARE_BRACE)) {
+            error_pretty(parser_peek(p).loc, (*p->lexer), "Expected ] but got `%s`", token_type_as_str(parser_peek(p).type));
+        }
+        return ast;
+    }
+
     return parse_funcall(arena, p);
 }
 
@@ -923,7 +978,7 @@ AST *parse_unary(Arena *arena, Parser *p) {
         return ast;
     }
 
-    return parse_array_subscript(arena, p);
+    return parse_subscript(arena, p);
 }
 
 AST *parse_factor(Arena *arena, Parser *p) {
diff --git a/tests/.parse_comparision.build.code.expected b/tests/.parse_comparision.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_comparision.build.err.expected b/tests/.parse_comparision.build.err.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_comparision.build.in.expected b/tests/.parse_comparision.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_comparision.build.out.expected b/tests/.parse_comparision.build.out.expected
new file mode 100644 (file)
index 0000000..a808229
--- /dev/null
@@ -0,0 +1,4 @@
+parse_comparision.momo:1:0 [BINARY] '(123 > 2)'
+parse_comparision.momo:2:0 [BINARY] '(5.000000 <= 'foo': ???)'
+parse_comparision.momo:3:0 [BINARY] '('bar': ??? < 'baz': ???)'
+parse_comparision.momo:4:0 [BINARY] '('two': ??? >= ('a': ??? * 'b': ???))'
diff --git a/tests/.parse_comparision.code.expected b/tests/.parse_comparision.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_comparision.err.expected b/tests/.parse_comparision.err.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_comparision.in.expected b/tests/.parse_comparision.in.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_comparision.out.expected b/tests/.parse_comparision.out.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_equality.build.code.expected b/tests/.parse_equality.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_equality.build.err.expected b/tests/.parse_equality.build.err.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_equality.build.in.expected b/tests/.parse_equality.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_equality.build.out.expected b/tests/.parse_equality.build.out.expected
new file mode 100644 (file)
index 0000000..539700f
--- /dev/null
@@ -0,0 +1,4 @@
+parse_equality.momo:1:0 [BINARY] '(123 == 2)'
+parse_equality.momo:2:0 [BINARY] '(5.000000 != 'foo': ???)'
+parse_equality.momo:3:0 [BINARY] '('bar': ??? == 'baz': ???)'
+parse_equality.momo:4:0 [BINARY] '('two': ??? != ('a': ??? * 'b': ???))'
diff --git a/tests/.parse_equality.code.expected b/tests/.parse_equality.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_equality.err.expected b/tests/.parse_equality.err.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_equality.in.expected b/tests/.parse_equality.in.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_equality.out.expected b/tests/.parse_equality.out.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_factor.build.code.expected b/tests/.parse_factor.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_factor.build.err.expected b/tests/.parse_factor.build.err.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_factor.build.in.expected b/tests/.parse_factor.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_factor.build.out.expected b/tests/.parse_factor.build.out.expected
new file mode 100644 (file)
index 0000000..73e1ab4
--- /dev/null
@@ -0,0 +1,4 @@
+parse_factor.momo:1:0 [BINARY] '(8 * 1024)'
+parse_factor.momo:2:0 [BINARY] '(40.000000 / 1.555500)'
+parse_factor.momo:3:0 [BINARY] '('foo': ??? * 2)'
+parse_factor.momo:4:0 [BINARY] '('bar': ??? / 'baz': ???)'
diff --git a/tests/.parse_factor.code.expected b/tests/.parse_factor.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_factor.err.expected b/tests/.parse_factor.err.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_factor.in.expected b/tests/.parse_factor.in.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_factor.out.expected b/tests/.parse_factor.out.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_primary.build.code.expected b/tests/.parse_primary.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_primary.build.err.expected b/tests/.parse_primary.build.err.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_primary.build.in.expected b/tests/.parse_primary.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_primary.build.out.expected b/tests/.parse_primary.build.out.expected
new file mode 100644 (file)
index 0000000..2354fbe
--- /dev/null
@@ -0,0 +1,7 @@
+parse_primary.momo:1:0 [PRIMARY] '123'
+parse_primary.momo:2:1 [PRIMARY] '"string"'
+parse_primary.momo:3:0 [PRIMARY] ''identifier': ???'
+parse_primary.momo:4:0 [PRIMARY] 'true'
+parse_primary.momo:5:0 [PRIMARY] 'false'
+parse_primary.momo:6:0 [PRIMARY] '0'
+parse_primary.momo:7:1 [PRIMARY] ''expression_inside_parenthesis': ???'
diff --git a/tests/.parse_primary.code.expected b/tests/.parse_primary.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_primary.err.expected b/tests/.parse_primary.err.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_primary.in.expected b/tests/.parse_primary.in.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_primary.out.expected b/tests/.parse_primary.out.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_term.build.code.expected b/tests/.parse_term.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_term.build.err.expected b/tests/.parse_term.build.err.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_term.build.in.expected b/tests/.parse_term.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_term.build.out.expected b/tests/.parse_term.build.out.expected
new file mode 100644 (file)
index 0000000..ea835f4
--- /dev/null
@@ -0,0 +1,4 @@
+parse_term.momo:1:0 [BINARY] '(123 + 2)'
+parse_term.momo:2:0 [BINARY] '(5.000000 + 'foo': ???)'
+parse_term.momo:3:0 [BINARY] '('bar': ??? - 'baz': ???)'
+parse_term.momo:4:0 [BINARY] '('two': ??? - ('a': ??? * 'b': ???))'
diff --git a/tests/.parse_term.code.expected b/tests/.parse_term.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_term.err.expected b/tests/.parse_term.err.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_term.in.expected b/tests/.parse_term.in.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_term.out.expected b/tests/.parse_term.out.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_unary.build.code.expected b/tests/.parse_unary.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_unary.build.err.expected b/tests/.parse_unary.build.err.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_unary.build.in.expected b/tests/.parse_unary.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_unary.build.out.expected b/tests/.parse_unary.build.out.expected
new file mode 100644 (file)
index 0000000..75dff12
--- /dev/null
@@ -0,0 +1,7 @@
+parse_unary.momo:1:0 [UNARY] ' ! (1)'
+parse_unary.momo:2:0 [UNARY] ' ! (true)'
+parse_unary.momo:3:0 [UNARY] ' ! ( ! (true))'
+parse_unary.momo:4:0 [UNARY] ' - (1)'
+parse_unary.momo:5:0 [UNARY] ' - ('number': ???)'
+parse_unary.momo:6:0 [UNARY] ' ! ('bar': ???)'
+parse_unary.momo:7:0 [UNARY] ' - ('baz': ???)'
diff --git a/tests/.parse_unary.code.expected b/tests/.parse_unary.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_unary.err.expected b/tests/.parse_unary.err.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_unary.in.expected b/tests/.parse_unary.in.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_unary.out.expected b/tests/.parse_unary.out.expected
new file mode 100644 (file)
index 0000000..e69de29