about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBaitinq <[email protected]>2025-03-08 20:53:46 +0100
committerBaitinq <[email protected]>2025-03-08 20:53:46 +0100
commit5f132c8422cb88e3f0ca266f4de9cc0129d44775 (patch)
treeab4acc5dbed602b19c4eea4e451175f4fa265200
parentCodegen: Fix bug with recursive functions as variables (diff)
downloadinterpreter-5f132c8422cb88e3f0ca266f4de9cc0129d44775.tar.gz
interpreter-5f132c8422cb88e3f0ca266f4de9cc0129d44775.tar.bz2
interpreter-5f132c8422cb88e3f0ca266f4de9cc0129d44775.zip
Feature: Add support for GT and LT operators
-rw-r--r--examples/10.src2
-rw-r--r--grammar.ebnf2
-rw-r--r--src/codegen.zig84
-rw-r--r--src/parser.zig35
-rw-r--r--src/tokenizer.zig4
5 files changed, 47 insertions, 80 deletions
diff --git a/examples/10.src b/examples/10.src
index 0ec38ea..67199b0 100644
--- a/examples/10.src
+++ b/examples/10.src
@@ -1,7 +1,7 @@
 let main = () => i64 {
 	let counter = 0;
 
-	while !(counter == 10) {
+	while counter < 10 {
 		print(counter);
 		counter = counter + 1;
 	};
diff --git a/grammar.ebnf b/grammar.ebnf
index ed87d7f..addd256 100644
--- a/grammar.ebnf
+++ b/grammar.ebnf
@@ -16,7 +16,7 @@ FunctionArguments ::= Expression ("," Expression)*
 
 Expression ::= EqualityExpression | AdditiveExpression
 
-EqualityExpression ::= AdditiveExpression "==" AdditiveExpression
+EqualityExpression ::= AdditiveExpression ("==" | "<" | ">") AdditiveExpression
 
 AdditiveExpression ::= MultiplicativeExpression (("+" | "-") MultiplicativeExpression)*
 
diff --git a/src/codegen.zig b/src/codegen.zig
index 9e06c8a..1e9a33e 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -307,6 +307,7 @@ pub const CodeGen = struct {
                     try self.generate_statement(stmt);
                 }
 
+                // TODO: This should be done with a defer when `builder_pos` is declared, but for some reason it doesn't work
                 core.LLVMPositionBuilderAtEnd(self.builder, builder_pos);
 
                 // Global functions
@@ -358,18 +359,7 @@ pub const CodeGen = struct {
                     }
                     const loaded = core.LLVMBuildLoad2(self.builder, param_type, variable.value, "");
 
-                    if (name != null) {
-                        const ptr = self.environment.get_variable(name.?).?;
-                        _ = core.LLVMBuildStore(self.builder, loaded, ptr.value);
-                        ptr.type = variable.type;
-                        return ptr;
-                    }
-
-                    return try self.create_variable(.{
-                        .value = loaded,
-                        .type = variable.type,
-                        .stack_level = null,
-                    });
+                    return self.generate_literal(loaded, variable.type, name);
                 },
             },
             .ADDITIVE_EXPRESSION => |exp| {
@@ -383,19 +373,7 @@ pub const CodeGen = struct {
                     result = core.LLVMBuildSub(self.builder, lhs_value.value, rhs_value.value, "") orelse return CodeGenError.CompilationError;
                 }
 
-                if (name != null) {
-                    const ptr = self.environment.get_variable(name.?) orelse unreachable;
-                    _ = core.LLVMBuildStore(self.builder, result, ptr.value);
-                    ptr.type = core.LLVMInt64Type();
-
-                    return ptr;
-                } else {
-                    return try self.create_variable(.{
-                        .value = result,
-                        .type = core.LLVMInt64Type(),
-                        .stack_level = null,
-                    });
-                }
+                return self.generate_literal(result, core.LLVMInt64Type(), name);
             },
             .MULTIPLICATIVE_EXPRESSION => |exp| {
                 const lhs_value = try self.generate_expression_value(exp.lhs, null);
@@ -408,19 +386,7 @@ pub const CodeGen = struct {
                     result = core.LLVMBuildSDiv(self.builder, lhs_value.value, rhs_value.value, "") orelse return CodeGenError.CompilationError;
                 }
 
-                if (name != null) {
-                    const ptr = self.environment.get_variable(name.?) orelse unreachable;
-                    _ = core.LLVMBuildStore(self.builder, result, ptr.value);
-                    ptr.type = core.LLVMInt64Type();
-
-                    return ptr;
-                } else {
-                    return try self.create_variable(.{
-                        .value = result,
-                        .type = core.LLVMInt64Type(),
-                        .stack_level = null,
-                    });
-                }
+                return self.generate_literal(result, core.LLVMInt64Type(), name);
             },
             .UNARY_EXPRESSION => |exp| {
                 const k = try self.generate_expression_value(exp.expression, null);
@@ -439,48 +405,26 @@ pub const CodeGen = struct {
                     },
                 }
 
-                if (name != null) {
-                    const ptr = self.environment.get_variable(name.?) orelse unreachable;
-
-                    _ = core.LLVMBuildStore(self.builder, r, ptr.value);
-                    ptr.type = t;
-
-                    return ptr;
-                } else {
-                    return try self.create_variable(.{
-                        .value = r,
-                        .type = t,
-                        .stack_level = null,
-                    });
-                }
+                return self.generate_literal(r, t, name);
             },
             .EQUALITY_EXPRESSION => |exp| {
                 const lhs_value = try self.generate_expression_value(exp.lhs, null);
                 const rhs_value = try self.generate_expression_value(exp.rhs, null);
 
-                const cmp = core.LLVMBuildICmp(self.builder, types.LLVMIntPredicate.LLVMIntEQ, lhs_value.value, rhs_value.value, "");
-
-                if (name != null) {
-                    const ptr = self.environment.get_variable(name.?) orelse unreachable;
-
-                    _ = core.LLVMBuildStore(self.builder, cmp, ptr.value);
-                    ptr.type = core.LLVMInt1Type();
+                const op = switch (exp.typ) {
+                    .EQ => types.LLVMIntPredicate.LLVMIntEQ,
+                    .LT => types.LLVMIntPredicate.LLVMIntSLT,
+                    .GT => types.LLVMIntPredicate.LLVMIntSGT,
+                };
+                const cmp = core.LLVMBuildICmp(self.builder, op, lhs_value.value, rhs_value.value, "");
 
-                    return ptr;
-                } else {
-                    return try self.create_variable(.{
-                        .value = cmp,
-                        .type = core.LLVMInt1Type(),
-                        .stack_level = null,
-                    });
-                }
+                return self.generate_literal(cmp, core.LLVMInt1Type(), name);
             },
             else => unreachable,
         };
     }
 
     fn generate_literal(self: *CodeGen, literal_val: types.LLVMValueRef, literal_type: types.LLVMTypeRef, name: ?[]const u8) !*Variable {
-        var variable: types.LLVMValueRef = undefined;
         if (name != null) {
             if (self.environment.scope_stack.items.len == 1) {
                 const ptr = try self.create_variable(.{
@@ -495,12 +439,10 @@ pub const CodeGen = struct {
             _ = core.LLVMBuildStore(self.builder, literal_val, ptr.value) orelse return CodeGenError.CompilationError;
             ptr.type = literal_type;
             return ptr;
-        } else {
-            variable = literal_val;
         }
 
         return try self.create_variable(.{
-            .value = variable,
+            .value = literal_val,
             .type = literal_type,
             .stack_level = null,
         });
diff --git a/src/parser.zig b/src/parser.zig
index f7a6806..ad2b8d0 100644
--- a/src/parser.zig
+++ b/src/parser.zig
@@ -30,10 +30,7 @@ pub const Node = union(enum) {
         condition: *Node,
         statements: []*Node,
     },
-    EQUALITY_EXPRESSION: struct {
-        lhs: *Node,
-        rhs: *Node,
-    },
+    EQUALITY_EXPRESSION: struct { lhs: *Node, rhs: *Node, typ: EqualityExpressionType },
     ADDITIVE_EXPRESSION: struct {
         addition: bool,
         lhs: *Node,
@@ -79,6 +76,12 @@ pub const Node = union(enum) {
     },
 };
 
+pub const EqualityExpressionType = enum {
+    EQ,
+    LT,
+    GT,
+};
+
 pub const Parser = struct {
     tokens: []tokenizer.Token,
     offset: u32,
@@ -266,20 +269,38 @@ pub const Parser = struct {
             return ParserError.ParsingError;
     }
 
-    // EqualityExpression ::= AdditiveExpression "==" AdditiveExpression
+    // EqualityExpression ::= AdditiveExpression ("==" | "<" | ">") AdditiveExpression
     fn parse_equality_expression(self: *Parser) ParserError!*Node {
         errdefer if (!self.try_context) std.debug.print("Error parsing equality expression {any}\n", .{self.peek_token()});
 
         const lhs = try self.parse_additive_expression();
 
-        _ = try self.parse_token(tokenizer.TokenType.EQUALS);
-        _ = try self.parse_token(tokenizer.TokenType.EQUALS);
+        var typ: EqualityExpressionType = undefined;
+
+        if (self.accept_parse(struct {
+            fn parse(iself: *Parser) ParserError!*Node {
+                _ = try iself.parse_token(tokenizer.TokenType.EQUALS);
+                _ = try iself.parse_token(tokenizer.TokenType.EQUALS);
+                return try iself.create_node(.{ .PROGRAM = .{
+                    .statements = &[_]*Node{},
+                } });
+            }
+        }.parse) != null) {
+            typ = .EQ;
+        } else if (self.accept_token(tokenizer.TokenType.LESS) != null) {
+            typ = .LT;
+        } else if (self.accept_token(tokenizer.TokenType.GREATER) != null) {
+            typ = .GT;
+        } else {
+            return ParserError.ParsingError;
+        }
 
         const rhs = try self.parse_additive_expression();
 
         return self.create_node(.{ .EQUALITY_EXPRESSION = .{
             .lhs = lhs,
             .rhs = rhs,
+            .typ = typ,
         } });
     }
 
diff --git a/src/tokenizer.zig b/src/tokenizer.zig
index 908c016..99ed10d 100644
--- a/src/tokenizer.zig
+++ b/src/tokenizer.zig
@@ -26,6 +26,8 @@ pub const TokenType = union(enum) {
     MUL: void,
     DIV: void,
     BANG: void,
+    LESS: void,
+    GREATER: void,
 
     // Punctuation
     SEMICOLON: void,
@@ -84,6 +86,8 @@ pub const Tokenizer = struct {
         if (self.accept_string("*")) return self.create_token(.{ .MUL = void{} });
         if (self.accept_string("/")) return self.create_token(.{ .DIV = void{} });
         if (self.accept_string("!")) return self.create_token(.{ .BANG = void{} });
+        if (self.accept_string("<")) return self.create_token(.{ .LESS = void{} });
+        if (self.accept_string(">")) return self.create_token(.{ .GREATER = void{} });
 
         const string = self.consume_string();
         if (string.len == 0) return TokenizerError.TokenizingError;