arithmetic calculator

This commit is contained in:
Patrick MARIE 2024-08-24 19:50:00 +02:00
parent a50663cbf2
commit e619f7016f
4 changed files with 46 additions and 5 deletions

View File

@ -77,6 +77,11 @@ pub const Chunk = struct {
switch (instruction) { switch (instruction) {
@intFromEnum(OpCode.OP_RETURN) => return utils.simple_instruction("OP_RETURN", offset), @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), @intFromEnum(OpCode.OP_CONSTANT) => return utils.constant_instruction("OP_CONSTANT", self, offset),
else => { else => {
debug.print("unknown opcode {d}\n", .{instruction}); debug.print("unknown opcode {d}\n", .{instruction});

View File

@ -18,9 +18,23 @@ pub fn main() !void {
var chunk = Chunk.new(); var chunk = Chunk.new();
try chunk.init(allocator); 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, @intFromEnum(OpCode.OP_CONSTANT), 123);
try chunk.write(allocator, @intCast(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); try chunk.write(allocator, @intFromEnum(OpCode.OP_RETURN), 123);
chunk.dissassemble("test chunk"); chunk.dissassemble("test chunk");

View File

@ -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 };

View File

@ -46,7 +46,7 @@ pub const VM = struct {
while (true) { while (true) {
if (DEBUG_TRACE_EXECUTION) { if (DEBUG_TRACE_EXECUTION) {
if (self.stack.items.len > 0) { if (self.stack.items.len > 0) {
debug.print("S: ", .{}); debug.print("{s:32}", .{""});
for (self.stack.items) |item| { for (self.stack.items) |item| {
debug.print("[ ", .{}); debug.print("[ ", .{});
print_value(item); print_value(item);
@ -59,11 +59,18 @@ pub const VM = struct {
const instruction = self.read_byte(); const instruction = self.read_byte();
switch (instruction) { try switch (instruction) {
@intFromEnum(OpCode.OP_CONSTANT) => { @intFromEnum(OpCode.OP_CONSTANT) => {
const constant = self.read_constant(); const constant = self.read_constant();
try self.push(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) => { @intFromEnum(OpCode.OP_RETURN) => {
print_value(self.pop()); print_value(self.pop());
return InterpretResult.OK; return InterpretResult.OK;
@ -72,7 +79,7 @@ pub const VM = struct {
debug.print("Invalid instruction: {d}\n", .{instruction}); debug.print("Invalid instruction: {d}\n", .{instruction});
return InterpretResult.RUNTIME_ERROR; return InterpretResult.RUNTIME_ERROR;
}, },
} };
} }
return InterpretResult.OK; return InterpretResult.OK;
@ -98,4 +105,19 @@ pub const VM = struct {
pub fn pop(self: *VM) Value { pub fn pop(self: *VM) Value {
return self.stack.pop(); 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);
}
}; };