|
|
|
@ -11,7 +11,7 @@ const tokens = @import("./kym/tokens.zig");
|
|
|
|
|
const tree = @import("./kym/tree.zig");
|
|
|
|
|
|
|
|
|
|
pub const Frame = struct {
|
|
|
|
|
name_stringable: *RuntimeRef,
|
|
|
|
|
callable: *RuntimeRef,
|
|
|
|
|
arg_count: u8,
|
|
|
|
|
locals_top: usize,
|
|
|
|
|
|
|
|
|
@ -381,14 +381,14 @@ pub const RuntimeEnv = struct {
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn new_boolean(self: *RuntimeEnv, value: bool) RuntimeError!*RuntimeRef {
|
|
|
|
|
pub fn new_boolean(self: *RuntimeEnv, value: bool) coral.io.AllocationError!*RuntimeRef {
|
|
|
|
|
return RuntimeRef.allocate(self.allocator, .{
|
|
|
|
|
.ref_count = 1,
|
|
|
|
|
.payload = if (value) .true else .false,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn new_boxed(self: *RuntimeEnv, value: ?*const RuntimeRef) RuntimeError!*RuntimeRef {
|
|
|
|
|
pub fn new_boxed(self: *RuntimeEnv, value: ?*const RuntimeRef) coral.io.AllocationError!*RuntimeRef {
|
|
|
|
|
return RuntimeRef.allocate(self.allocator, .{
|
|
|
|
|
.ref_count = 1,
|
|
|
|
|
.payload = .{.boxed = if (value) |ref| ref.acquire() else null},
|
|
|
|
@ -399,7 +399,7 @@ pub const RuntimeEnv = struct {
|
|
|
|
|
self: *RuntimeEnv,
|
|
|
|
|
userdata: []const coral.io.Byte,
|
|
|
|
|
typeinfo: *const Typeinfo,
|
|
|
|
|
) RuntimeError!*RuntimeRef {
|
|
|
|
|
) coral.io.AllocationError!*RuntimeRef {
|
|
|
|
|
coral.debug.assert(userdata.len == typeinfo.size);
|
|
|
|
|
|
|
|
|
|
const dynamic = try self.allocator.reallocate(null, @sizeOf(usize) + typeinfo.size);
|
|
|
|
@ -415,21 +415,21 @@ pub const RuntimeEnv = struct {
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn new_fixed(self: *RuntimeEnv, value: Fixed) RuntimeError!*RuntimeRef {
|
|
|
|
|
pub fn new_fixed(self: *RuntimeEnv, value: Fixed) coral.io.AllocationError!*RuntimeRef {
|
|
|
|
|
return RuntimeRef.allocate(self.allocator, .{
|
|
|
|
|
.ref_count = 1,
|
|
|
|
|
.payload = .{.fixed = value},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn new_float(self: *RuntimeEnv, value: Float) RuntimeError!*RuntimeRef {
|
|
|
|
|
pub fn new_float(self: *RuntimeEnv, value: Float) coral.io.AllocationError!*RuntimeRef {
|
|
|
|
|
return RuntimeRef.allocate(self.allocator, .{
|
|
|
|
|
.ref_count = 1,
|
|
|
|
|
.payload = .{.float = value},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn new_string(self: *RuntimeEnv, value: []const coral.io.Byte) RuntimeError!*RuntimeRef {
|
|
|
|
|
pub fn new_string(self: *RuntimeEnv, value: []const coral.io.Byte) coral.io.AllocationError!*RuntimeRef {
|
|
|
|
|
if (value.len > coral.math.max_int(@typeInfo(Fixed).Int)) {
|
|
|
|
|
return error.OutOfMemory;
|
|
|
|
|
}
|
|
|
|
@ -450,7 +450,7 @@ pub const RuntimeEnv = struct {
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn new_symbol(self: *RuntimeEnv, value: []const coral.io.Byte) RuntimeError!*RuntimeRef {
|
|
|
|
|
pub fn new_symbol(self: *RuntimeEnv, value: []const coral.io.Byte) coral.io.AllocationError!*RuntimeRef {
|
|
|
|
|
return RuntimeRef.allocate(self.allocator, .{
|
|
|
|
|
.ref_count = 1,
|
|
|
|
|
|
|
|
|
@ -468,14 +468,14 @@ pub const RuntimeEnv = struct {
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn new_syscall(self: *RuntimeEnv, value: *const Syscall) RuntimeError!*RuntimeRef {
|
|
|
|
|
pub fn new_syscall(self: *RuntimeEnv, value: *const Syscall) coral.io.AllocationError!*RuntimeRef {
|
|
|
|
|
return RuntimeRef.allocate(self.allocator, .{
|
|
|
|
|
.ref_count = 1,
|
|
|
|
|
.payload = .{.syscall = value},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn new_table(self: *RuntimeEnv) RuntimeError!*RuntimeRef {
|
|
|
|
|
pub fn new_table(self: *RuntimeEnv) coral.io.AllocationError!*RuntimeRef {
|
|
|
|
|
var table = Table.make(self);
|
|
|
|
|
|
|
|
|
|
errdefer table.free(self);
|
|
|
|
@ -483,14 +483,14 @@ pub const RuntimeEnv = struct {
|
|
|
|
|
return try self.new_dynamic(coral.io.bytes_of(&table), Table.typeinfo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn new_vector2(self: *RuntimeEnv, x: f32, y: f32) RuntimeError!*RuntimeRef {
|
|
|
|
|
pub fn new_vector2(self: *RuntimeEnv, x: f32, y: f32) coral.io.AllocationError!*RuntimeRef {
|
|
|
|
|
return RuntimeRef.allocate(self.allocator, .{
|
|
|
|
|
.ref_count = 1,
|
|
|
|
|
.payload = .{.vector2 = .{x, y}},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn new_vector3(self: *RuntimeEnv, x: f32, y: f32, z: f32) RuntimeError!*RuntimeRef {
|
|
|
|
|
pub fn new_vector3(self: *RuntimeEnv, x: f32, y: f32, z: f32) coral.io.AllocationError!*RuntimeRef {
|
|
|
|
|
return RuntimeRef.allocate(self.allocator, .{
|
|
|
|
|
.ref_count = 1,
|
|
|
|
|
.payload = .{.vector3 = .{x, y, z}},
|
|
|
|
@ -513,7 +513,7 @@ pub const RuntimeEnv = struct {
|
|
|
|
|
const popped_frame = self.frames.pop();
|
|
|
|
|
|
|
|
|
|
coral.debug.assert(popped_frame != null);
|
|
|
|
|
self.discard(popped_frame.?.name_stringable);
|
|
|
|
|
self.discard(popped_frame.?.callable);
|
|
|
|
|
|
|
|
|
|
var locals_to_pop = self.locals.values.len - popped_frame.?.locals_top;
|
|
|
|
|
|
|
|
|
@ -534,9 +534,9 @@ pub const RuntimeEnv = struct {
|
|
|
|
|
return self.locals.pop() orelse self.raise(error.IllegalState, "stack underflow", .{});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn push_frame(self: *RuntimeEnv, name_stringable: *RuntimeRef, arg_count: u8) RuntimeError!Frame {
|
|
|
|
|
pub fn push_frame(self: *RuntimeEnv, callable: *const RuntimeRef, arg_count: u8) RuntimeError!Frame {
|
|
|
|
|
const frame = Frame{
|
|
|
|
|
.name_stringable = name_stringable.acquire(),
|
|
|
|
|
.callable = callable.acquire(),
|
|
|
|
|
.arg_count = arg_count,
|
|
|
|
|
.locals_top = self.locals.values.len - arg_count,
|
|
|
|
|
};
|
|
|
|
@ -563,7 +563,7 @@ pub const RuntimeEnv = struct {
|
|
|
|
|
while (remaining_frames != 0) {
|
|
|
|
|
remaining_frames -= 1;
|
|
|
|
|
|
|
|
|
|
const callable_string = try self.to_string(self.frames.values[remaining_frames].name_stringable);
|
|
|
|
|
const callable_string = try self.to_string(self.frames.values[remaining_frames].callable);
|
|
|
|
|
|
|
|
|
|
defer self.discard(callable_string);
|
|
|
|
|
|
|
|
|
@ -623,7 +623,7 @@ pub const RuntimeEnv = struct {
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn to_string(self: *RuntimeEnv, value: *const RuntimeRef) RuntimeError!*RuntimeRef {
|
|
|
|
|
pub fn to_string(self: *RuntimeEnv, value: *const RuntimeRef) coral.io.AllocationError!*RuntimeRef {
|
|
|
|
|
const decimal_format = coral.utf8.DecimalFormat.default;
|
|
|
|
|
|
|
|
|
|
return switch (value.object().payload) {
|
|
|
|
@ -683,8 +683,8 @@ pub const RuntimeEnv = struct {
|
|
|
|
|
break: convert self.new_string(string[0 .. length.?]);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
.syscall => self.new_string("<syscall>"),
|
|
|
|
|
.dynamic => self.new_string("<dynamic>"),
|
|
|
|
|
.syscall => self.new_string("syscall"),
|
|
|
|
|
.dynamic => |dynamic| dynamic.typeinfo().to_string(self, dynamic.userdata()),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -957,6 +957,7 @@ pub const Typeinfo = struct {
|
|
|
|
|
name: []const coral.io.Byte,
|
|
|
|
|
size: usize,
|
|
|
|
|
destruct: ?*const fn (env: *RuntimeEnv, userdata: []coral.io.Byte) void = null,
|
|
|
|
|
to_string: *const fn (env: *RuntimeEnv, userdata: []coral.io.Byte) coral.io.AllocationError!*RuntimeRef = default_to_string,
|
|
|
|
|
call: *const fn (env: *RuntimeEnv, userdata: []coral.io.Byte, frame: Frame) RuntimeError!?*RuntimeRef = default_call,
|
|
|
|
|
get: *const fn (env: *RuntimeEnv, userdata: []coral.io.Byte, index: *const RuntimeRef) RuntimeError!?*RuntimeRef = default_get,
|
|
|
|
|
set: *const fn (env: *RuntimeEnv, userdata: []coral.io.Byte, value: *const RuntimeRef, value: ?*const RuntimeRef) RuntimeError!void = default_set,
|
|
|
|
@ -972,6 +973,10 @@ pub const Typeinfo = struct {
|
|
|
|
|
fn default_set(env: *RuntimeEnv, _: []coral.io.Byte, _: *const RuntimeRef, _: ?*const RuntimeRef) RuntimeError!void {
|
|
|
|
|
return env.raise(error.BadOperation, "this dynamic object is not set-indexable", .{});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn default_to_string(env: *RuntimeEnv, _: []coral.io.Byte) coral.io.AllocationError!*RuntimeRef {
|
|
|
|
|
return env.new_string("{}");
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
pub fn assert(env: *RuntimeEnv, condition: bool) RuntimeError!void {
|
|
|
|
|