Skip to content

Instantly share code, notes, and snippets.

@SimonMeskens
Last active February 5, 2025 01:07
Show Gist options
  • Save SimonMeskens/94abd04d25b5398861715dc8bdf1dbe9 to your computer and use it in GitHub Desktop.
Save SimonMeskens/94abd04d25b5398861715dc8bdf1dbe9 to your computer and use it in GitHub Desktop.
Threaded code in Zig
// Copyright 2024 Simon Meskens
// Licensed under the MIT License
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided this license is
// preserved. This software is offered as-is, without any warranty.
// https://godbolt.org/z/TK5r79esP
pub const VM = struct {
code: []const Inst,
ip: usize,
data: *anyopaque,
pub fn init(code: [:.end]const Inst, data: *anyopaque) VM {
return VM{ .code = code, .ip = 0, .data = data };
}
pub fn run(self: *VM) void {
while (true) switch (self.code[self.ip]) {
.end => return,
inline else => |op| {
const inst = @field(Inst, @tagName(op));
self.ip += 1;
inst(self);
},
};
}
};
pub const Inst = enum {
op_A,
op_B,
op_C,
end,
extern fn op_A(self: *VM) void;
extern fn op_B(self: *VM) void;
extern fn op_C(self: *VM) void;
fn end(_: *VM) void {}
};
export fn vm_run(mem: [*]u32, code: [*:.end]Inst, code_len: usize) void {
var vm = VM.init(code[0..code_len :.end], mem);
vm.run();
}
// Copyright 2024 Simon Meskens
// Licensed under the MIT License
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided this license is
// preserved. This software is offered as-is, without any warranty.
// https://godbolt.org/z/j9s5GvxcG
pub const VM = struct {
code: []const Inst,
ip: usize,
data: *anyopaque,
pub fn init(code: [:.end]const Inst, data: *anyopaque) VM {
return VM{ .code = code, .ip = 0, .data = data };
}
pub fn run(self: *VM) void {
while (true) switch (self.code[self.ip]) {
.end => return,
inline else => |op| {
const code = @field(Inst, @tagName(op));
self.ip += 1;
for (code()) |inst| inst(self);
},
};
}
};
const InstPtr = *const fn(self: *VM) callconv(.C) void;
pub const Inst = enum {
op_A,
op_B,
op_C,
end,
fn op_A() [2]InstPtr { return .{ one, two }; }
fn op_B() [2]InstPtr { return .{ two, one }; }
fn op_C() [1]InstPtr { return .{ two }; }
fn end() [0]InstPtr { return .{}; }
};
extern fn one(self: *VM) void;
extern fn two(self: *VM) void;
export fn vm_run(mem: [*]u32, code: [*:.end]Inst, code_len: usize) void {
var vm = VM.init(code[0..code_len :.end], mem);
vm.run();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment