diff --git a/src/main.zig b/src/main.zig index d29869f..f32a66c 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,5 +1,87 @@ const std = @import("std"); +const Instruction = enum(u32) { + PSH, + ADD, + POP, + SET, + HLT, +}; + +const default_program = [_]u32{ + @enumToInt(Instruction.PSH), 5, + @enumToInt(Instruction.PSH), 6, + @enumToInt(Instruction.ADD), @enumToInt(Instruction.POP), + @enumToInt(Instruction.HLT), +}; + +const Stack = std.ArrayList(u32); + +const VM = struct { + program: []const u32, + stack: Stack, + + instruction_pointer: usize = 0, + stack_pointer: usize = 0, + running: bool = false, + + const Self = @This(); + + pub fn init(allocator: *std.mem.Allocator, program: []const u32) !Self { + return Self{ + .program = program, + .stack = try Stack.initCapacity(allocator, 256), + .instruction_pointer = 0, + }; + } + + pub fn deinit(self: Self) void { + self.stack.deinit(); + } + + pub fn fetch(self: Self) u32 { + return self.program[self.instruction_pointer]; + } + + pub fn runOne(self: *Self, instruction_as_number: u32) !void { + const instruction: Instruction = try std.meta.intToEnum(Instruction, instruction_as_number); + std.log.info("running {}", .{instruction}); + + switch (instruction) { + .PSH => { + self.instruction_pointer += 1; + const value = self.fetch(); + self.stack.appendAssumeCapacity(value); + }, + .POP => { + const value = self.stack.pop(); + std.log.info("stack: popped {}", .{value}); + }, + .ADD => { + const value_a = self.stack.pop(); + const value_b = self.stack.pop(); + self.stack.appendAssumeCapacity(value_b + value_a); + }, + .HLT => self.running = false, + else => unreachable, + } + } +}; + pub fn main() anyerror!void { - std.log.info("All your codebase are belong to us.", .{}); + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer { + _ = gpa.deinit(); + } + + const allocator = &gpa.allocator; + + var vm = try VM.init(allocator, &default_program); + defer vm.deinit(); + + vm.running = true; + while (vm.running) { + try vm.runOne(vm.fetch()); + vm.instruction_pointer += 1; + } }