From e619f7016feeaa572924b7efd6374abb9f6830f6 Mon Sep 17 00:00:00 2001 From: Patrick MARIE Date: Sat, 24 Aug 2024 19:50:00 +0200 Subject: [PATCH] arithmetic calculator --- src/chunk.zig | 5 +++++ src/main.zig | 16 +++++++++++++++- src/opcode.zig | 2 +- src/vm.zig | 28 +++++++++++++++++++++++++--- 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/chunk.zig b/src/chunk.zig index 2db5177..bb64175 100644 --- a/src/chunk.zig +++ b/src/chunk.zig @@ -77,6 +77,11 @@ pub const Chunk = struct { switch (instruction) { @intFromEnum(OpCode.OP_RETURN) => return utils.simple_instruction("OP_RETURN", offset), + @intFromEnum(OpCode.OP_ADD) => return utils.simple_instruction("OP_ADD", offset), + @intFromEnum(OpCode.OP_SUBSTRACT) => return utils.simple_instruction("OP_SUBSTRACT", offset), + @intFromEnum(OpCode.OP_MULTIPLY) => return utils.simple_instruction("OP_MULTIPLY", offset), + @intFromEnum(OpCode.OP_DIVIDE) => return utils.simple_instruction("OP_DIVIDE", offset), + @intFromEnum(OpCode.OP_NEGATE) => return utils.simple_instruction("OP_NEGATE", offset), @intFromEnum(OpCode.OP_CONSTANT) => return utils.constant_instruction("OP_CONSTANT", self, offset), else => { debug.print("unknown opcode {d}\n", .{instruction}); diff --git a/src/main.zig b/src/main.zig index f716e1f..76924a0 100644 --- a/src/main.zig +++ b/src/main.zig @@ -18,9 +18,23 @@ pub fn main() !void { var chunk = Chunk.new(); try chunk.init(allocator); - const constant = try chunk.add_constant(allocator, 1.2); + var constant = try chunk.add_constant(allocator, 1.2); try chunk.write(allocator, @intFromEnum(OpCode.OP_CONSTANT), 123); try chunk.write(allocator, @intCast(constant), 123); + + constant = try chunk.add_constant(allocator, 3.4); + try chunk.write(allocator, @intFromEnum(OpCode.OP_CONSTANT), 123); + try chunk.write(allocator, @intCast(constant), 123); + + try chunk.write(allocator, @intFromEnum(OpCode.OP_ADD), 123); + + constant = try chunk.add_constant(allocator, 5.6); + try chunk.write(allocator, @intFromEnum(OpCode.OP_CONSTANT), 123); + try chunk.write(allocator, @intCast(constant), 123); + + try chunk.write(allocator, @intFromEnum(OpCode.OP_DIVIDE), 123); + + try chunk.write(allocator, @intFromEnum(OpCode.OP_NEGATE), 123); try chunk.write(allocator, @intFromEnum(OpCode.OP_RETURN), 123); chunk.dissassemble("test chunk"); diff --git a/src/opcode.zig b/src/opcode.zig index c99ab1b..44dac22 100644 --- a/src/opcode.zig +++ b/src/opcode.zig @@ -1 +1 @@ -pub const OpCode = enum(u8) { OP_CONSTANT, OP_RETURN }; +pub const OpCode = enum(u8) { OP_CONSTANT, OP_ADD, OP_SUBSTRACT, OP_MULTIPLY, OP_DIVIDE, OP_NEGATE, OP_RETURN }; diff --git a/src/vm.zig b/src/vm.zig index bfc94ad..3547969 100644 --- a/src/vm.zig +++ b/src/vm.zig @@ -46,7 +46,7 @@ pub const VM = struct { while (true) { if (DEBUG_TRACE_EXECUTION) { if (self.stack.items.len > 0) { - debug.print("S: ", .{}); + debug.print("{s:32}", .{""}); for (self.stack.items) |item| { debug.print("[ ", .{}); print_value(item); @@ -59,11 +59,18 @@ pub const VM = struct { const instruction = self.read_byte(); - switch (instruction) { + try switch (instruction) { @intFromEnum(OpCode.OP_CONSTANT) => { const constant = self.read_constant(); try self.push(constant); }, + @intFromEnum(OpCode.OP_ADD) => self.binary_op(OpCode.OP_ADD), + @intFromEnum(OpCode.OP_SUBSTRACT) => self.binary_op(OpCode.OP_SUBSTRACT), + @intFromEnum(OpCode.OP_MULTIPLY) => self.binary_op(OpCode.OP_SUBSTRACT), + @intFromEnum(OpCode.OP_DIVIDE) => self.binary_op(OpCode.OP_SUBSTRACT), + @intFromEnum(OpCode.OP_NEGATE) => { + try self.push(-self.pop()); + }, @intFromEnum(OpCode.OP_RETURN) => { print_value(self.pop()); return InterpretResult.OK; @@ -72,7 +79,7 @@ pub const VM = struct { debug.print("Invalid instruction: {d}\n", .{instruction}); return InterpretResult.RUNTIME_ERROR; }, - } + }; } return InterpretResult.OK; @@ -98,4 +105,19 @@ pub const VM = struct { pub fn pop(self: *VM) Value { return self.stack.pop(); } + + pub fn binary_op(self: *VM, op: OpCode) !void { + const b = self.pop(); + const a = self.pop(); + + const res: Value = switch (op) { + OpCode.OP_ADD => a + b, + OpCode.OP_SUBSTRACT => a - b, + OpCode.OP_MULTIPLY => a * b, + OpCode.OP_DIVIDE => a / b, + else => unreachable, + }; + + try self.push(res); + } };