diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Lexer.zig | 20 | ||||
-rw-r--r-- | src/codegen.zig | 8 | ||||
-rw-r--r-- | src/compile.zig | 8 | ||||
-rw-r--r-- | src/main.zig | 7 | ||||
-rw-r--r-- | src/parse.zig | 35 |
5 files changed, 71 insertions, 7 deletions
diff --git a/src/Lexer.zig b/src/Lexer.zig index c938116..4665379 100644 --- a/src/Lexer.zig +++ b/src/Lexer.zig @@ -16,6 +16,10 @@ pub const Token = struct { invalid, eof, identifier, + left_angle, + right_angle, + left_angle_equal, + right_angle_equal, // Keywords let, @@ -79,6 +83,14 @@ fn getNext(self: *Self) Token { '+' => self.create(.plus), '-' => self.create(.minus), '=' => self.create(.equal), + '<' => if (self.eatIfEqual('=')) + self.create(.left_angle_equal) + else + self.create(.left_angle), + '>' => if (self.eatIfEqual('=')) + self.create(.right_angle_equal) + else + self.create(.right_angle), '#' => { while ((self.eatChar() orelse '\n') != '\n') {} self.start = self.pos; @@ -134,6 +146,14 @@ fn create(self: *Self, ty: Token.Type) Token { return .{ .loc = .{ .start = start, .end = self.pos }, .type = ty }; } +fn eatIfEqual(self: *Self, char: u8) bool { + if (self.peekChar() == char) { + _ = self.eatChar(); + return true; + } + return false; +} + fn eatChar(self: *Self) ?u8 { const token = self.peekChar(); if (token != null) self.pos += 1; diff --git a/src/codegen.zig b/src/codegen.zig index 7ade3fd..701a4e8 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -642,6 +642,14 @@ const Context = struct { switch (bin_op.op) { .add => try self.emit(.add(reg, lhs, rhs)), .sub => try self.emit(.sub(reg, lhs, rhs)), + .less_than => try self.emit(.sltu(reg, lhs, rhs)), + .greater_than => try self.emit(.sltu(reg, rhs, lhs)), + .less_or_equal, .greater_or_equal => { + const l, const r = if (bin_op.op == .less_or_equal) .{ lhs, rhs } else .{ rhs, lhs }; + + try self.emit(.sltu(reg, r, l)); + try self.emit(.xori(reg, reg, 1)); + }, } } diff --git a/src/compile.zig b/src/compile.zig index 93f240b..583be50 100644 --- a/src/compile.zig +++ b/src/compile.zig @@ -63,6 +63,10 @@ pub const Instr = struct { const Op = enum { add, sub, + less_than, + greater_than, + less_or_equal, + greater_or_equal, }; pub fn sources(self: BinOp) Sources { @@ -390,6 +394,10 @@ const CompileContext = struct { .op = switch (binop.op) { .plus => .add, .minus => .sub, + .left_angle => .less_than, + .right_angle => .greater_than, + .left_angle_equal => .less_or_equal, + .right_angle_equal => .greater_or_equal, }, }, }, diff --git a/src/main.zig b/src/main.zig index 5eda854..367edf8 100644 --- a/src/main.zig +++ b/src/main.zig @@ -37,10 +37,11 @@ pub fn main() !void { const source = \\{ \\ let x = 10 - \\ let y = 5 - \\ while y { + \\ let y = 0 + \\ print(x > y) + \\ while y < 3 { \\ x = x + x - \\ y = y - 1 + \\ y = y + 1 \\ } \\ if x { \\ # let x = read_int(0) diff --git a/src/parse.zig b/src/parse.zig index e675fbe..efb5c8e 100644 --- a/src/parse.zig +++ b/src/parse.zig @@ -96,11 +96,19 @@ pub const Expr = struct { const Op = enum { plus, minus, + left_angle, + right_angle, + left_angle_equal, + right_angle_equal, pub fn format(self: Op, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void { - try writer.writeByte(switch (self) { - .plus => '+', - .minus => '-', + try writer.writeAll(switch (self) { + .plus => "+", + .minus => "-", + .left_angle => "<", + .right_angle => ">", + .left_angle_equal => "<=", + .right_angle_equal => ">=", }); } }; @@ -210,7 +218,26 @@ pub fn statement(allocator: Allocator, lexer: *Lexer) ParseError!Stmt { } pub fn expression(allocator: Allocator, lexer: *Lexer) ParseError!*Expr { - return parseTerms(allocator, lexer); + return parseComparisons(allocator, lexer); +} + +pub fn parseComparisons(allocator: Allocator, lexer: *Lexer) ParseError!*Expr { + const lhs = try parseTerms(allocator, lexer); + + const op: Expr.Type.BinOp.Op = switch (lexer.peek().type) { + .left_angle => .left_angle, + .right_angle => .right_angle, + .left_angle_equal => .left_angle_equal, + .right_angle_equal => .right_angle_equal, + else => return lhs, + }; + _ = lexer.next(); + + const rhs = try parseTerms(allocator, lexer); + return try allocate(Expr, allocator, .{ + .loc = lhs.loc.combine(rhs.loc), + .type = .{ .bin_op = .{ .lhs = lhs, .op = op, .rhs = rhs } }, + }); } pub fn parseTerms(allocator: Allocator, lexer: *Lexer) !*Expr { |