Skip to content

Commit

Permalink
Add extern enum support
Browse files Browse the repository at this point in the history
  • Loading branch information
bgk- committed Jul 10, 2024
1 parent 31da66b commit 11a1bd0
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 12 deletions.
11 changes: 6 additions & 5 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,19 @@ pub fn build(b: *std.Build) void {
const build_options = b.addOptions();
build_options.addOption([]const u8, "version", version);

_ = b.addModule("topi", .{
.root_source_file = b.path("src/topi.zig"),
});
_ = b.addModule("topi", .{
.root_source_file = b.path("src/topi.zig"),
});

const topidll = b.addSharedLibrary(.{
const topilib = b.addSharedLibrary(.{
.name = "topi",
.root_source_file = b.path("src/export.zig"),
.target = target,
.optimize = optimize,
});

b.installArtifact(topidll);
const art = b.addInstallArtifact(topilib, .{ .dest_dir = .{ .override = .lib } });
b.getInstallStep().dependOn(&art.step);

const exe = b.addExecutable(.{
.name = "topi",
Expand Down
2 changes: 1 addition & 1 deletion build.zig.zon
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.{
.name = "topiary",
.version = "0.13.2",
.version = "0.13.3",
.paths = .{""},
.dependencies = .{},
}
1 change: 1 addition & 0 deletions src/compiler.zig
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,7 @@ pub const Compiler = struct {
}

obj.* = .{
.id = UUID.fromString(e.name),
.data = .{
.@"enum" = .{
.is_seq = e.is_seq,
Expand Down
9 changes: 9 additions & 0 deletions src/export-value.zig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const Tag = enum(u8) {
list,
set,
map,
enum_value,
};

pub const ExportValue = extern struct {
Expand All @@ -23,6 +24,10 @@ pub const ExportValue = extern struct {
items: [*c]ExportValue,
count: u16,
},
enum_value: extern struct {
enum_name: [*c]const u8,
value_name: [*c]const u8,
},
},

pub const Nil: ExportValue = .{ .tag = Tag.nil, .data = .{ .nil = {} } };
Expand All @@ -33,6 +38,10 @@ pub const ExportValue = extern struct {
return switch (value) {
.bool => |b| if (b) True else False,
.number => |n| .{ .tag = Tag.number, .data = .{ .number = n } },
.enum_value => |e| .{ .tag = Tag.enum_value, .data = .{ .enum_value = .{
.enum_name = e.base.data.@"enum".name.ptr,
.value_name = e.base.data.@"enum".values[e.index].ptr,
} } },
.obj => |o| switch (o.data) {
// We're mixing memory management here, which is a very bad idea,
// Tried passing in a "ExportAllocator" and copying the values to the memory
Expand Down
27 changes: 25 additions & 2 deletions src/export.zig
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,10 @@ export fn start(vm_ptr: usize, path_ptr: [*]const u8, path_len: usize) void {
}

export fn run(vm_ptr: usize) void {
log("Running VM", .{}, .info);
log("Running Vm", .{}, .debug);
var vm: *Vm = @ptrFromInt(vm_ptr);
vm.run() catch {
vm.run() catch |err| {
log("Vm Error: {s}", .{ @errorName(err) }, .err);
if (vm.err.msg) |msg| {
log("Error at line {}: {s}", .{ vm.err.line, msg }, .err);
}
Expand Down Expand Up @@ -246,6 +247,28 @@ export fn setExternNumber(vm_ptr: usize, name_ptr: [*c]const u8, name_length: us
};
}

export fn setExternEnum(vm_ptr: usize, name_ptr: [*c]const u8, name_length: usize, enum_name_ptr: [*c]const u8, enum_name_length: usize, enum_value_ptr: [*c]const u8, enum_value_length: usize) void {
var vm: *Vm = @ptrFromInt(vm_ptr);
const name = name_ptr[0..name_length];
const enum_name = enum_name_ptr[0..enum_name_length];
const enum_value = enum_value_ptr[0..enum_value_length];
for (vm.bytecode.constants) |c| {
if (c != .obj or c.obj.data != .@"enum") continue;
const e = c.obj.data.@"enum";
if (!std.mem.eql(u8, e.name, enum_name)) continue;
for (e.values, 0..) |v, i| {
if (!std.mem.eql(u8, v, enum_value)) continue;
vm.setExtern(name, .{ .enum_value = .{ .base = c.obj, .index = @intCast(i) }}) catch |err| {
log("Could not set Export value \"{s}\": {s}", .{ name, @errorName(err) }, .err);
return;
};
log("Set extern enum \"{s}\" to {s}.{s} ({})", .{ name, enum_name, enum_value, i}, .debug);
return;
}
}
log("Could not set extern enum \"{s}\" {s}.{s}", .{ name, enum_name, enum_value }, .err);
}

export fn setExternBool(vm_ptr: usize, name_ptr: [*c]const u8, name_length: usize, value: bool) void {
var vm: *Vm = @ptrFromInt(vm_ptr);
const name = name_ptr[0..name_length];
Expand Down
12 changes: 8 additions & 4 deletions src/state.zig
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ pub const State = struct {
if (seen.contains(value.obj.id)) continue;
try seen.put(value.obj.id, {});
try stream.objectField(&value.obj.id);
try serializeObj(value, &stream, &references);
try serializeObj(vm.allocator, value, &stream, &references);
}
try stream.endObject();
}

fn serializeObj(value: Value, stream: anytype, references: *std.ArrayList(Value)) !void {
fn serializeObj(allocator: std.mem.Allocator, value: Value, stream: anytype, references: *std.ArrayList(Value)) !void {
try stream.beginObject();
try stream.objectField(@tagName(value.obj.data));
switch (value.obj.data) {
Expand Down Expand Up @@ -101,7 +101,9 @@ pub const State = struct {
try stream.objectField("arity");
try stream.write(f.arity);
try stream.objectField("inst");
try stream.write(&f.instructions);
const buf = try allocator.alloc(u8, std.base64.standard.Encoder.calcSize(f.instructions.len));
defer allocator.free(buf);
try stream.write(std.base64.standard.Encoder.encode(buf, f.instructions));
try stream.objectField("lines");
try stream.beginArray();
for (f.lines) |l| try stream.write(l);
Expand Down Expand Up @@ -292,9 +294,11 @@ pub const State = struct {
for (lines_items, 0..) |t, i| lines[i] = @intCast(t.integer);
const locals = v.object.get("locals_count").?.integer;
const is_method = v.object.get("is_method").?.bool;
const inst_alloc = try vm.allocator.alloc(u8, try std.base64.standard.Decoder.calcSizeForSlice(inst));
try std.base64.standard.Decoder.decode(inst_alloc, inst);
var result = try vm.gc.create(vm, .{ .function = .{
.arity = @intCast(arity),
.instructions = try vm.allocator.dupe(u8, inst),
.instructions = inst_alloc,
.lines = try vm.allocator.dupe(u32, lines),
.locals_count = @intCast(locals),
.is_method = is_method,
Expand Down

0 comments on commit 11a1bd0

Please sign in to comment.