]> www.git.momoyon.org Git - lang.git/commitdiff
[main.c] Can parse_unary_not()...
authormomoyon <momoyon@momoyon.org>
Sat, 17 May 2025 06:13:40 +0000 (11:13 +0500)
committermomoyon <momoyon@momoyon.org>
Sat, 17 May 2025 06:13:40 +0000 (11:13 +0500)
- [tests] Add new test parse_unary_not.momo

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

diff --git a/main.c b/main.c
index c10ab359feff1d378d90c8b21ace6bcaa4dc7951..7c4a693220b9c034147031d1fe327b4f439d8567 100644 (file)
--- a/main.c
+++ b/main.c
@@ -285,6 +285,7 @@ typedef struct Funcall_AST Funcall_AST;
 typedef struct Subscript_AST Subscript_AST;
 typedef struct Access_AST Access_AST;
 typedef struct Unary_term_AST Unary_term_AST;
+typedef struct Unary_not_AST Unary_not_AST;
 typedef struct Suffix_AST Suffix_AST;
 typedef struct Prefix_AST Prefix_AST;
 typedef struct Primary_expr Primary_expr;
@@ -320,6 +321,11 @@ struct Unary_term_AST {
     AST *operand;
 };
 
+struct Unary_not_AST {
+    Token operator;
+    AST *operand;
+};
+
 typedef struct {
     AST **items;
     size_t count;
@@ -390,6 +396,7 @@ typedef enum {
     AST_ACCESS,
     AST_PREFIX,
     AST_UNARY_TERM,
+    AST_UNARY_NOT,
     AST_BINARY,
     AST_COUNT,
 } AST_kind;
@@ -405,6 +412,7 @@ struct AST {
     Access_AST      *access;
     Prefix_AST      *prefix;
     Unary_term_AST  *unary_term;
+    Unary_not_AST   *unary_not;
     Binary_expr     *bin_expr;
     Location loc;
 };
@@ -516,6 +524,7 @@ const char *expr_kind_as_str(AST_kind k) {
         case AST_ACCESS: return "ACCESS";
         case AST_PREFIX: return "PREFIX";
         case AST_UNARY_TERM: return "UNARY_TERM";
+        case AST_UNARY_NOT: return "UNARY_NOT";
         case AST_BINARY: return "BINARY";
         case AST_COUNT:
         default: ASSERT(false, "UNREACHABLE!");
@@ -560,6 +569,10 @@ void print_ast_as_value(FILE *f, AST e) {
              fprintf(f, " %s ", token_type_as_str(e.unary_term->operator.type));
              print_ast_as_value(f, *e.unary_term->operand);
         } break;
+        case AST_UNARY_NOT: {
+             fprintf(f, " %s ", token_type_as_str(e.unary_not->operator.type));
+             print_ast_as_value(f, *e.unary_not->operand);
+        } break;
         case AST_PRIMARY: {
             print_primary_expr(f, e.prim_expr);
         } break;
@@ -806,6 +819,7 @@ AST *parse_subscript(Arena *arena, Parser *p);
 AST *parse_access(Arena *arena, Parser *p);
 AST *parse_prefix(Arena *arena, Parser *p);
 AST *parse_unary_term(Arena *arena, Parser *p);
+AST *parse_unary_not(Arena *arena, Parser *p);
 AST *parse_factor(Arena *arena, Parser *p);
 AST *parse_comparision(Arena *arena, Parser *p);
 AST *parse_term(Arena *arena, Parser *p);
@@ -1068,13 +1082,29 @@ AST *parse_unary_term(Arena *arena, Parser *p) {
     return parse_prefix(arena, p);
 }
 
+AST *parse_unary_not(Arena *arena, Parser *p) {
+    Token t = parser_peek(p);
+
+    if (t.type == TK_NOT || t.type == TK_BITWISE_NOT) {
+        AST *ast = (AST *)arena_alloc(arena, sizeof(AST));
+        ast->loc = t.loc;
+        ast->unary_not = (Unary_not_AST *)arena_alloc(arena, sizeof(Unary_not_AST));
+        ast->kind = AST_UNARY_NOT;
+        ast->unary_not->operator = parser_advance(p);
+        ast->unary_not->operand = parse_unary_not(arena, p);
+        return ast;
+    }
+
+    return parse_unary_term(arena, p);
+}
+
 AST *parse_factor(Arena *arena, Parser *p) {
-    AST *ast = parse_unary_term(arena, p);
+    AST *ast = parse_unary_not(arena, p);
     if (ast == NULL) return NULL;
 
     while (parser_match(p, TK_DIVIDE) || parser_match(p, TK_MULTIPLY)) {
         Token op = parser_previous(p);
-        AST *rhs = parse_unary_term(arena, p);
+        AST *rhs = parse_unary_not(arena, p);
         if (rhs == NULL) return rhs;
 
         AST *new_ast = (AST *)arena_alloc(arena, sizeof(AST));
diff --git a/tests/.parse_unary_not.build.code.expected b/tests/.parse_unary_not.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_not.build.err.expected b/tests/.parse_unary_not.build.err.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_unary_not.build.in.expected b/tests/.parse_unary_not.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_not.build.out.expected b/tests/.parse_unary_not.build.out.expected
new file mode 100644 (file)
index 0000000..de132c6
--- /dev/null
@@ -0,0 +1,4 @@
+parse_unary_not.momo:1:0 [UNARY_NOT] ' ~ 1'
+parse_unary_not.momo:2:0 [UNARY_NOT] ' ~ 2'
+parse_unary_not.momo:3:0 [UNARY_NOT] ' ! true'
+parse_unary_not.momo:4:0 [UNARY_NOT] ' !  ! false'
diff --git a/tests/.parse_unary_not.code.expected b/tests/.parse_unary_not.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_not.err.expected b/tests/.parse_unary_not.err.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_unary_not.in.expected b/tests/.parse_unary_not.in.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/.parse_unary_not.out.expected b/tests/.parse_unary_not.out.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/parse_unary_not.momo b/tests/parse_unary_not.momo
new file mode 100644 (file)
index 0000000..79cd1e3
--- /dev/null
@@ -0,0 +1,4 @@
+~1;
+~2;
+!true;
+!!false;