Refactor Kym #47

Merged
kayomn merged 4 commits from kym-refactor into main 2023-11-12 21:23:06 +01:00
3 changed files with 1059 additions and 531 deletions
Showing only changes of commit b0aa7166f9 - Show all commits

File diff suppressed because it is too large Load Diff

View File

@ -632,7 +632,7 @@ pub fn execute(self: *Self, env: *kym.RuntimeEnv) kym.RuntimeError!?*kym.Runtime
.push_false => _ = try env.new_boolean(false), .push_false => _ = try env.new_boolean(false),
.push_const => |push_const| _ = try env.push(try self.get_constant(env, push_const)), .push_const => |push_const| _ = try env.push(try self.get_constant(env, push_const)),
.push_local => |push_local| _ = try env.local_get(push_local), .push_local => |push_local| _ = try env.local_get(push_local),
.push_top => _ = try env.local_get(env.local_count() - 1), .push_top => _ = try env.local_top(),
.push_table => |push_table| { .push_table => |push_table| {
const table = (try env.new_table()).pop().?; const table = (try env.new_table()).pop().?;
@ -708,7 +708,7 @@ pub fn execute(self: *Self, env: *kym.RuntimeEnv) kym.RuntimeError!?*kym.Runtime
.vec3 => syscall_vec3, .vec3 => syscall_vec3,
}), }),
.set_local => |local_set| _ = env.local_set(local_set, env.pop()), .set_local => |local_set| _ = try env.local_set(local_set, env.pop()),
.get_box => _ = try env.boxed_get(), .get_box => _ = try env.boxed_get(),
.set_box => { .set_box => {
@ -765,10 +765,10 @@ pub fn execute(self: *Self, env: *kym.RuntimeEnv) kym.RuntimeError!?*kym.Runtime
defer env.release(addable); defer env.release(addable);
_ = switch (try env.expect_numeric(addable)) { _ = switch (try env.expect_numeric(addable)) {
.fixed => |fixed| try env.add_fixed(fixed), .fixed => |fixed| try env.fixed_add(fixed),
.float => |float| try env.add_float(float), .float => |float| try env.float_add(float),
.vector2 => |vector2| try env.add_vector2(vector2), .vector2 => |vector2| try env.vector2_add(vector2),
.vector3 => |vector3| try env.add_vector3(vector3), .vector3 => |vector3| try env.vector3_add(vector3),
}; };
}, },
@ -778,10 +778,10 @@ pub fn execute(self: *Self, env: *kym.RuntimeEnv) kym.RuntimeError!?*kym.Runtime
defer env.release(subtractable); defer env.release(subtractable);
_ = switch (try env.expect_numeric(subtractable)) { _ = switch (try env.expect_numeric(subtractable)) {
.fixed => |fixed| try env.sub_fixed(fixed), .fixed => |fixed| try env.fixed_subtract(fixed),
.float => |float| try env.sub_float(float), .float => |float| try env.float_subtract(float),
.vector2 => |vector2| try env.sub_vector2(vector2), .vector2 => |vector2| try env.vector2_subtract(vector2),
.vector3 => |vector3| try env.sub_vector3(vector3), .vector3 => |vector3| try env.vector3_subtract(vector3),
}; };
}, },
@ -791,10 +791,10 @@ pub fn execute(self: *Self, env: *kym.RuntimeEnv) kym.RuntimeError!?*kym.Runtime
defer env.release(multiplicable); defer env.release(multiplicable);
_ = switch (try env.expect_numeric(multiplicable)) { _ = switch (try env.expect_numeric(multiplicable)) {
.fixed => |fixed| try env.mul_fixed(fixed), .fixed => |fixed| try env.fixed_multiply(fixed),
.float => |float| try env.mul_float(float), .float => |float| try env.float_multiply(float),
.vector2 => |vector2| try env.mul_vector2(vector2), .vector2 => |vector2| try env.vector2_multiply(vector2),
.vector3 => |vector3| try env.mul_vector3(vector3), .vector3 => |vector3| try env.vector3_multiply(vector3),
}; };
}, },
@ -804,10 +804,10 @@ pub fn execute(self: *Self, env: *kym.RuntimeEnv) kym.RuntimeError!?*kym.Runtime
defer env.release(divisible); defer env.release(divisible);
_ = switch (try env.expect_numeric(divisible)) { _ = switch (try env.expect_numeric(divisible)) {
.fixed => |fixed| try env.div_fixed(fixed), .fixed => |fixed| try env.fixed_divide(fixed),
.float => |float| try env.div_float(float), .float => |float| try env.float_divide(float),
.vector2 => |vector2| try env.div_vector2(vector2), .vector2 => |vector2| try env.vector2_divide(vector2),
.vector3 => |vector3| try env.div_vector3(vector3), .vector3 => |vector3| try env.vector3_divide(vector3),
}; };
}, },
@ -951,10 +951,13 @@ fn syscall_vec2(env: *kym.RuntimeEnv) kym.RuntimeError!?*kym.RuntimeObj {
if ((try env.arg_get(1)).pop()) |y| { if ((try env.arg_get(1)).pop()) |y| {
defer env.release(y); defer env.release(y);
return (try env.new_vector2(x, @floatCast(try env.expect_float(y)))).pop(); return (try env.new_vector2(.{
.y = @floatCast(try env.expect_float(y)),
.x = x,
})).pop();
} }
return (try env.new_vector2(x, x)).pop(); return (try env.new_vector2(kym.Vector2.from_scalar(x))).pop();
} }
fn syscall_vec3(env: *kym.RuntimeEnv) kym.RuntimeError!?*kym.RuntimeObj { fn syscall_vec3(env: *kym.RuntimeEnv) kym.RuntimeError!?*kym.RuntimeObj {
@ -971,7 +974,8 @@ fn syscall_vec3(env: *kym.RuntimeEnv) kym.RuntimeError!?*kym.RuntimeObj {
if ((try env.arg_get(1)).pop()) |y| { if ((try env.arg_get(1)).pop()) |y| {
defer env.release(y); defer env.release(y);
const z = @as(f32, get_z: { return (try env.new_vector3(.{
.z = @as(f32, get_z: {
const z = (try env.arg_get(0)).pop() orelse { const z = (try env.arg_get(0)).pop() orelse {
return env.raise(error.BadOperation, return env.raise(error.BadOperation,
"a third argument is required to create a vector if a first and second exist", .{}); "a third argument is required to create a vector if a first and second exist", .{});
@ -980,12 +984,14 @@ fn syscall_vec3(env: *kym.RuntimeEnv) kym.RuntimeError!?*kym.RuntimeObj {
defer env.release(z); defer env.release(z);
break: get_z @floatCast(try env.expect_float(z)); break: get_z @floatCast(try env.expect_float(z));
}); }),
return (try env.new_vector3(x, @floatCast(try env.expect_float(y)), z)).pop(); .y = @floatCast(try env.expect_float(y)),
.x = x,
})).pop();
} }
return (try env.new_vector3(x, x, x)).pop(); return (try env.new_vector3(kym.Vector3.from_scalar(x))).pop();
} }
pub const typeinfo = &kym.Typeinfo{ pub const typeinfo = &kym.Typeinfo{
@ -996,16 +1002,16 @@ pub const typeinfo = &kym.Typeinfo{
.to_string = typeinfo_to_string, .to_string = typeinfo_to_string,
}; };
fn typeinfo_call(env: *kym.RuntimeEnv, userdata: []coral.io.Byte) kym.RuntimeError!?*kym.RuntimeObj { fn typeinfo_call(context: kym.Typeinfo.CallContext) kym.RuntimeError!?*kym.RuntimeObj {
return @as(*Self, @ptrCast(@alignCast(userdata))).execute(env); return @as(*Self, @ptrCast(@alignCast(context.userdata))).execute(context.env);
} }
fn typeinfo_destruct(env: *kym.RuntimeEnv, userdata: []coral.io.Byte) void { fn typeinfo_destruct(context: kym.Typeinfo.DestructContext) void {
@as(*Self, @ptrCast(@alignCast(userdata))).deinit(env); @as(*Self, @ptrCast(@alignCast(context.userdata))).deinit(context.env);
} }
fn typeinfo_to_string(env: *kym.RuntimeEnv, userdata: []coral.io.Byte) kym.RuntimeError!*kym.RuntimeObj { fn typeinfo_to_string(context: kym.Typeinfo.ToStringContext) kym.RuntimeError!*kym.RuntimeObj {
return (try (try env.push(@as(*Self, @ptrCast(@alignCast(userdata))).name)).to_string()).pop().?; return (try (try context.env.push(@as(*Self, @ptrCast(@alignCast(context.userdata))).name)).to_string()).pop().?;
} }
pub fn write(self: *Self, line: tokens.Line, opcode: Opcode) coral.io.AllocationError!void { pub fn write(self: *Self, line: tokens.Line, opcode: Opcode) coral.io.AllocationError!void {

View File

@ -8,7 +8,7 @@ contiguous: RefList,
const RefList = coral.list.Stack(?*kym.RuntimeObj); const RefList = coral.list.Stack(?*kym.RuntimeObj);
const RefTable = coral.map.Table(*kym.RuntimeObj, *kym.RuntimeObj, struct { const RefTable = coral.map.Table(*kym.RuntimeObj, *kym.RuntimeObj, struct {
pub const hash = kym.RuntimeObj.get_hash; pub const hash = kym.RuntimeObj.hash;
pub const equals = kym.RuntimeObj.equals; pub const equals = kym.RuntimeObj.equals;
}); });
@ -51,41 +51,41 @@ pub const typeinfo = &kym.Typeinfo{
.set = typeinfo_set, .set = typeinfo_set,
}; };
fn typeinfo_destruct(env: *kym.RuntimeEnv, userdata: []coral.io.Byte) void { fn typeinfo_destruct(context: kym.Typeinfo.DestructContext) void {
@as(*Self, @ptrCast(@alignCast(userdata))).deinit(env); @as(*Self, @ptrCast(@alignCast(context.userdata))).deinit(context.env);
} }
fn typeinfo_get(env: *kym.RuntimeEnv, userdata: []coral.io.Byte, index: *const kym.RuntimeObj) kym.RuntimeError!?*kym.RuntimeObj { fn typeinfo_get(context: kym.Typeinfo.GetContext) kym.RuntimeError!?*kym.RuntimeObj {
const table = @as(*Self, @ptrCast(@alignCast(userdata))); const table = @as(*Self, @ptrCast(@alignCast(context.userdata)));
const acquired_index = index.acquire(); const index = context.get_index();
defer env.release(acquired_index); defer context.env.release(index);
if (acquired_index.is_fixed()) |fixed| { if (index.is_fixed()) |fixed| {
if (fixed < 0) { if (fixed < 0) {
// TODO: Negative indexing. // TODO: Negative indexing.
unreachable; unreachable;
} }
if (fixed < table.contiguous.values.len) { if (fixed < table.contiguous.values.len) {
return (table.contiguous.values[@intCast(fixed)] orelse return null).acquire(); return table.contiguous.values[@intCast(fixed)];
} }
} }
if (table.associative.lookup(acquired_index)) |value| { if (table.associative.lookup(index)) |value| {
return value.acquire(); return value;
} }
return null; return null;
} }
fn typeinfo_set(env: *kym.RuntimeEnv, userdata: []coral.io.Byte, index: *const kym.RuntimeObj, value: ?*const kym.RuntimeObj) kym.RuntimeError!void { fn typeinfo_set(context: kym.Typeinfo.SetContext) kym.RuntimeError!void {
const table = @as(*Self, @ptrCast(@alignCast(userdata))); const table = @as(*Self, @ptrCast(@alignCast(context.userdata)));
const acquired_index = index.acquire(); const index = context.get_index();
errdefer env.release(acquired_index); errdefer context.env.release(index);
if (acquired_index.is_fixed()) |fixed| { if (index.is_fixed()) |fixed| {
if (fixed < 0) { if (fixed < 0) {
// TODO: Negative indexing. // TODO: Negative indexing.
unreachable; unreachable;
@ -95,28 +95,34 @@ fn typeinfo_set(env: *kym.RuntimeEnv, userdata: []coral.io.Byte, index: *const k
const maybe_replacing = &table.contiguous.values[@intCast(fixed)]; const maybe_replacing = &table.contiguous.values[@intCast(fixed)];
if (maybe_replacing.*) |replacing| { if (maybe_replacing.*) |replacing| {
env.release(replacing); context.env.release(replacing);
} }
maybe_replacing.* = if (value) |ref| ref.acquire() else null; if (context.get_value()) |value| {
errdefer context.env.release(value);
return; maybe_replacing.* = value;
} } else {
} maybe_replacing.* = null;
const acquired_value = (value orelse {
if (table.associative.remove(acquired_index)) |removed| {
env.release(removed.key);
env.release(removed.value);
} }
return; return;
}).acquire(); }
}
errdefer env.release(acquired_value);
const value = context.get_value() orelse {
if (try table.associative.replace(acquired_index, acquired_value)) |replaced| { if (table.associative.remove(index)) |removed| {
env.release(replaced.key); context.env.release(removed.key);
env.release(replaced.value); context.env.release(removed.value);
}
return;
};
errdefer context.env.release(value);
if (try table.associative.replace(index, value)) |replaced| {
context.env.release(replaced.key);
context.env.release(replaced.value);
} }
} }