diff --git a/.gitignore b/.gitignore index 47eaeb1c..19829e49 100644 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,7 @@ dist/ *.so *.o -tests/utils/*foreign.* +tests/utils/libforeign.* buzz_history node_modules diff --git a/src/Ast.zig b/src/Ast.zig index 8253a9f2..86217b89 100644 --- a/src/Ast.zig +++ b/src/Ast.zig @@ -484,10 +484,10 @@ pub const Slice = struct { const left = try self.toValue(components.left, gc); const left_integer = if (left.isInteger()) left.integer() else null; - const left_float = if (left.isFloat()) left.double() else null; + const left_float = if (left.isDouble()) left.double() else null; const right = try self.toValue(components.right, gc); const right_integer = if (right.isInteger()) right.integer() else null; - const right_float = if (right.isFloat()) right.double() else null; + const right_float = if (right.isDouble()) right.double() else null; switch (components.operator) { .Ampersand => return Value.fromInteger(left_integer.? & right_integer.?), @@ -544,11 +544,11 @@ pub const Slice = struct { if (right_float) |rf| { return Value.fromBoolean(lf > rf); } else { - return Value.fromBoolean(lf > @as(f64, @floatFromInt(right_integer.?))); + return Value.fromBoolean(lf > @as(v.Double, @floatFromInt(right_integer.?))); } } else { if (right_float) |rf| { - return Value.fromBoolean(@as(f64, @floatFromInt(left_integer.?)) > rf); + return Value.fromBoolean(@as(v.Double, @floatFromInt(left_integer.?)) > rf); } else { return Value.fromBoolean(left_integer.? > right_integer.?); } @@ -561,11 +561,11 @@ pub const Slice = struct { if (right_float) |rf| { return Value.fromBoolean(lf < rf); } else { - return Value.fromBoolean(lf < @as(f64, @floatFromInt(right_integer.?))); + return Value.fromBoolean(lf < @as(v.Double, @floatFromInt(right_integer.?))); } } else { if (right_float) |rf| { - return Value.fromBoolean(@as(f64, @floatFromInt(left_integer.?)) < rf); + return Value.fromBoolean(@as(v.Double, @floatFromInt(left_integer.?)) < rf); } else { return Value.fromBoolean(left_integer.? < right_integer.?); } @@ -578,11 +578,11 @@ pub const Slice = struct { if (right_float) |rf| { return Value.fromBoolean(lf >= rf); } else { - return Value.fromBoolean(lf >= @as(f64, @floatFromInt(right_integer.?))); + return Value.fromBoolean(lf >= @as(v.Double, @floatFromInt(right_integer.?))); } } else { if (right_float) |rf| { - return Value.fromBoolean(@as(f64, @floatFromInt(left_integer.?)) >= rf); + return Value.fromBoolean(@as(v.Double, @floatFromInt(left_integer.?)) >= rf); } else { return Value.fromBoolean(left_integer.? >= right_integer.?); } @@ -595,11 +595,11 @@ pub const Slice = struct { if (right_float) |rf| { return Value.fromBoolean(lf <= rf); } else { - return Value.fromBoolean(lf <= @as(f64, @floatFromInt(right_integer.?))); + return Value.fromBoolean(lf <= @as(v.Double, @floatFromInt(right_integer.?))); } } else { if (right_float) |rf| { - return Value.fromBoolean(@as(f64, @floatFromInt(left_integer.?)) <= rf); + return Value.fromBoolean(@as(v.Double, @floatFromInt(left_integer.?)) <= rf); } else { return Value.fromBoolean(left_integer.? <= right_integer.?); } @@ -626,7 +626,7 @@ pub const Slice = struct { return (try gc.copyString(try new_string.toOwnedSlice())).toValue(); } else if (right_float) |rf| { - return Value.fromFloat(rf + left_float.?); + return Value.fromDouble(rf + left_float.?); } else if (right_integer) |ri| { return Value.fromInteger(ri +% left_integer.?); } else if (right_list) |rl| { @@ -665,28 +665,28 @@ pub const Slice = struct { }, .Minus => { if (right_float) |rf| { - return Value.fromFloat(rf - left_float.?); + return Value.fromDouble(rf - left_float.?); } return Value.fromInteger(right_integer.? -% left_integer.?); }, .Star => { if (right_float) |rf| { - return Value.fromFloat(rf * left_float.?); + return Value.fromDouble(rf * left_float.?); } return Value.fromInteger(right_integer.? *% left_integer.?); }, .Slash => { if (right_float) |rf| { - return Value.fromFloat(left_float.? / rf); + return Value.fromDouble(left_float.? / rf); } return Value.fromInteger(@divTrunc(left_integer.?, right_integer.?)); }, .Percent => { if (right_float) |rf| { - return Value.fromFloat(@mod(left_float.?, rf)); + return Value.fromDouble(@mod(left_float.?, rf)); } return Value.fromInteger(@mod(left_integer.?, right_integer.?)); @@ -721,7 +721,7 @@ pub const Slice = struct { .Pattern => self.nodes.items(.components)[node].Pattern.toValue(), .Void => Value.Void, .Null => Value.Null, - .Double => Value.fromFloat(self.nodes.items(.components)[node].Double), + .Double => Value.fromDouble(self.nodes.items(.components)[node].Double), .Integer => Value.fromInteger(self.nodes.items(.components)[node].Integer), .Boolean => Value.fromBoolean(self.nodes.items(.components)[node].Boolean), .As => try self.toValue(self.nodes.items(.components)[node].As.left, gc), @@ -885,7 +885,7 @@ pub const Slice = struct { .Minus => if (val.isInteger()) Value.fromInteger(-%val.integer()) else - Value.fromFloat(-val.double()), + Value.fromDouble(-val.double()), else => unreachable, }; }, diff --git a/src/Jit.zig b/src/Jit.zig index 8aef4703..e8b7e1f6 100644 --- a/src/Jit.zig +++ b/src/Jit.zig @@ -1,7 +1,8 @@ const std = @import("std"); const Ast = @import("Ast.zig"); const o = @import("obj.zig"); -const Value = @import("value.zig").Value; +const v = @import("value.zig"); +const Value = v.Value; const m = @import("mir.zig"); const builtin = @import("builtin"); const BuildOptions = @import("build_options"); @@ -1131,19 +1132,68 @@ fn buildValueFromBoolean(self: *Self, value: m.MIR_op_t, dest: m.MIR_op_t) void self.append(out_label); } -fn buildValueToInteger(self: *Self, value: m.MIR_op_t, dest: m.MIR_op_t) void { - self.ANDS( - dest, +fn buildValueToInteger(self: *Self, value: m.MIR_op_t, dest: m.MIR_op_t) !void { + const inter = m.MIR_new_reg_op( + self.ctx, + try self.REG( + "inter", + m.MIR_T_I64, + ), + ); + + // Extract i48 + self.AND( + inter, value, - m.MIR_new_uint_op(self.ctx, 0xffffffff), + m.MIR_new_uint_op(self.ctx, 0xffffffffffff), + ); + + const is_neg = m.MIR_new_reg_op( + self.ctx, + try self.REG( + "is_neg", + m.MIR_T_I64, + ), + ); + + const out_label = m.MIR_new_label(self.ctx); + self.AND( + is_neg, + inter, + m.MIR_new_uint_op(self.ctx, 1 << 47), + ); + + // If 48th bit is 1, means the i48 is negative + self.BEQ( + m.MIR_new_label_op(self.ctx, out_label), + is_neg, + m.MIR_new_uint_op(self.ctx, 0), ); + + // Extend sign by filling upper bits with 1s + self.OR( + inter, + inter, + m.MIR_new_uint_op(self.ctx, @bitCast(~@as(i64, 0xFFFFFFFFFFFF))), + ); + + self.append(out_label); + + self.MOV(dest, inter); } fn buildValueFromInteger(self: *Self, value: m.MIR_op_t, dest: m.MIR_op_t) void { + // Get rid of upper bits + self.AND( + dest, + value, + m.MIR_new_uint_op(self.ctx, @bitCast(@as(i64, 0xFFFFFFFFFFFF))), + ); + self.OR( dest, m.MIR_new_uint_op(self.ctx, Value.IntegerMask), - value, + dest, ); } @@ -1762,14 +1812,14 @@ fn generateNamedVariable(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { null; const is_constant_fn = function_type != null and function_type.? != .Extern and function_type.? != .Anonymous; - const value = if (components.value) |v| - try self.generateNode(v) + const value = if (components.value) |val| + try self.generateNode(val) else null; switch (components.slot_type) { .Global => { - if (value) |v| { + if (value) |val| { std.debug.assert(!is_constant_fn); if (tags[components.assign_token.?] != .Equal) { @@ -1779,11 +1829,11 @@ fn generateNamedVariable(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { tags[components.assign_token.?], type_def.?.def_type, global, - v, + val, global, ); } else { - try self.buildSetGlobal(components.slot, v); + try self.buildSetGlobal(components.slot, val); } return null; @@ -1810,7 +1860,7 @@ fn generateNamedVariable(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { } }, .Local => { - if (value) |v| { + if (value) |val| { if (tags[components.assign_token.?] != .Equal) { const local = try self.buildGetLocal(components.slot); @@ -1818,13 +1868,13 @@ fn generateNamedVariable(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { tags[components.assign_token.?], type_def.?.def_type, local, - v, + val, local, ); try self.buildSetLocal(components.slot, local); } else { - try self.buildSetLocal(components.slot, v); + try self.buildSetLocal(components.slot, val); } return null; @@ -1833,7 +1883,7 @@ fn generateNamedVariable(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { return try self.buildGetLocal(components.slot); }, .UpValue => { - if (value) |v| { + if (value) |val| { if (tags[components.assign_token.?] != .Equal) { const upvalue = m.MIR_new_reg_op( self.ctx, @@ -1853,7 +1903,7 @@ fn generateNamedVariable(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { tags[components.assign_token.?], type_def.?.def_type, upvalue, - v, + val, upvalue, ); } else { @@ -1863,7 +1913,7 @@ fn generateNamedVariable(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { &[_]m.MIR_op_t{ m.MIR_new_reg_op(self.ctx, self.state.?.ctx_reg.?), m.MIR_new_uint_op(self.ctx, components.slot), - v, + val, }, ); } @@ -2618,7 +2668,7 @@ fn buildBinary( .Plus, .PlusEqual => { switch (def_type) { .Integer => { - self.ADDS(dest, left, right); + self.ADD(dest, left, right); try self.wrap(.Integer, dest, dest); }, .Double => { @@ -2664,7 +2714,7 @@ fn buildBinary( .Minus, .MinusEqual => { switch (def_type) { .Integer => { - self.SUBS(dest, left, right); + self.SUB(dest, left, right); try self.wrap(.Integer, dest, dest); }, .Double => { @@ -2677,7 +2727,7 @@ fn buildBinary( .Star, .StarEqual => { switch (def_type) { .Integer => { - self.MULS(dest, left, right); + self.MUL(dest, left, right); try self.wrap(.Integer, dest, dest); }, .Double => { @@ -2690,7 +2740,7 @@ fn buildBinary( .Slash, .SlashEqual => { switch (def_type) { .Integer => { - self.DIVS(dest, left, right); + self.DIV(dest, left, right); try self.wrap(.Integer, dest, dest); }, .Double => { @@ -2703,7 +2753,7 @@ fn buildBinary( .Percent, .PercentEqual => { switch (def_type) { .Integer => { - self.MODS(dest, left, right); + self.MOD(dest, left, right); try self.wrap(.Integer, dest, dest); }, .Double => { @@ -2914,10 +2964,10 @@ fn generateComparison(self: *Self, components: Ast.Binary) Error!?m.MIR_op_t { try self.wrap(.Bool, res, res); } else { switch (components.operator) { - .Greater => self.GTS(res, left, right), - .Less => self.LTS(res, left, right), - .GreaterEqual => self.GES(res, left, right), - .LessEqual => self.LES(res, left, right), + .Greater => self.GT(res, left, right), + .Less => self.LT(res, left, right), + .GreaterEqual => self.GE(res, left, right), + .LessEqual => self.LE(res, left, right), else => unreachable, } @@ -4438,7 +4488,7 @@ fn generateUnary(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { switch (components.operator) { .Bnot => { try self.unwrap(.Integer, left, result); - self.NOTS(result, result); + self.NOT(result, result); try self.wrap(.Integer, result, result); }, .Bang => { @@ -4473,7 +4523,7 @@ fn generateUnary(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { try self.unwrap(.Integer, left, result); if (left_type_def.?.def_type == .Integer) { - self.NEGS(result, result); + self.NEG(result, result); } else { self.DNEG(result, result); } @@ -5328,7 +5378,7 @@ fn buildBuzzValueToZigValue(self: *Self, buzz_type: *o.ObjTypeDef, zig_type: Zig // Convert it back to an int self.D2I(dest, tmp_float); } else { - self.buildValueToInteger(buzz_value, dest); + try self.buildValueToInteger(buzz_value, dest); } }, // TODO: double can't be truncated like ints, we need a D2F instruction @@ -6546,6 +6596,36 @@ inline fn BEQ(self: *Self, label: m.MIR_op_t, left: m.MIR_op_t, right: m.MIR_op_ ); } +inline fn BLT(self: *Self, label: m.MIR_op_t, left: m.MIR_op_t, right: m.MIR_op_t) void { + self.append( + m.MIR_new_insn_arr( + self.ctx, + @intFromEnum(m.MIR_Instruction.BLT), + 3, + &[_]m.MIR_op_t{ + label, + left, + right, + }, + ), + ); +} + +inline fn BGT(self: *Self, label: m.MIR_op_t, left: m.MIR_op_t, right: m.MIR_op_t) void { + self.append( + m.MIR_new_insn_arr( + self.ctx, + @intFromEnum(m.MIR_Instruction.BGT), + 3, + &[_]m.MIR_op_t{ + label, + left, + right, + }, + ), + ); +} + inline fn BNE(self: *Self, label: m.MIR_insn_t, left: m.MIR_op_t, right: m.MIR_op_t) void { self.append( m.MIR_new_insn_arr( @@ -6961,11 +7041,11 @@ inline fn D2I(self: *Self, dest: m.MIR_op_t, value: m.MIR_op_t) void { ); } -inline fn NEGS(self: *Self, dest: m.MIR_op_t, value: m.MIR_op_t) void { +inline fn NEG(self: *Self, dest: m.MIR_op_t, value: m.MIR_op_t) void { self.append( m.MIR_new_insn_arr( self.ctx, - @intFromEnum(m.MIR_Instruction.NEGS), + @intFromEnum(m.MIR_Instruction.NEG), 2, &[_]m.MIR_op_t{ dest, @@ -7093,6 +7173,10 @@ fn outputModule(self: *Self, name: []const u8, module: m.MIR_module_t) void { ); } -pub fn fmod(lhs: f64, rhs: f64) Value { - return Value.fromFloat(@mod(lhs, rhs)); +pub fn fmod(lhs: v.Double, rhs: v.Double) Value { + return Value.fromDouble(@mod(lhs, rhs)); +} + +pub fn dumpInt(value: u64) void { + io.print("\nvalue: {} {b}\n", .{ value, value }); } diff --git a/src/Parser.zig b/src/Parser.zig index 8eb926d2..9c9e45df 100644 --- a/src/Parser.zig +++ b/src/Parser.zig @@ -5,7 +5,9 @@ const BuildOptions = @import("build_options"); const obj = @import("obj.zig"); const Token = @import("Token.zig"); const Chunk = @import("Chunk.zig"); -const Value = @import("value.zig").Value; +const v = @import("value.zig"); +const Value = v.Value; +const Integer = v.Integer; const FFI = @import("FFI.zig"); const Ast = @import("Ast.zig"); const GarbageCollector = @import("memory.zig").GarbageCollector; @@ -7912,7 +7914,7 @@ fn enumDeclaration(self: *Self) Error!Ast.Node.Index { var cases = std.ArrayList(Ast.Enum.Case).init(self.gc.allocator); var def_cases = std.ArrayList([]const u8).init(self.gc.allocator); var picked = std.ArrayList(bool).init(self.gc.allocator); - var case_index: i32 = 0; + var case_index: v.Integer = 0; while (!self.check(.RightBrace) and !self.check(.Eof)) : (case_index += 1) { if (case_index > std.math.maxInt(u24)) { const location = self.ast.tokens.get(self.current_token.? - 1); diff --git a/src/Scanner.zig b/src/Scanner.zig index 6e39d5cb..eef100ed 100644 --- a/src/Scanner.zig +++ b/src/Scanner.zig @@ -2,6 +2,7 @@ const std = @import("std"); const mem = std.mem; const Allocator = mem.Allocator; const Token = @import("Token.zig"); +const v = @import("value.zig"); pub const SourceLocation = struct { start: usize, @@ -342,7 +343,7 @@ fn number(self: *Self) Token { } const double = if (is_float) - std.fmt.parseFloat(f64, self.source[self.current.start..self.current.offset]) catch { + std.fmt.parseFloat(v.Double, self.source[self.current.start..self.current.offset]) catch { return self.makeToken( .Error, "double overflow", @@ -354,7 +355,7 @@ fn number(self: *Self) Token { null; const int = if (!is_float) - std.fmt.parseInt(i32, self.source[self.current.start..self.current.offset], 10) catch { + std.fmt.parseInt(v.Integer, self.source[self.current.start..self.current.offset], 10) catch { return self.makeToken( .Error, "int overflow", @@ -429,7 +430,7 @@ fn binary(self: *Self) Token { .IntegerValue, null, null, - std.fmt.parseInt(i32, self.source[self.current.start + 2 .. self.current.offset], 2) catch { + std.fmt.parseInt(v.Integer, self.source[self.current.start + 2 .. self.current.offset], 2) catch { return self.makeToken( .Error, "int overflow", @@ -461,7 +462,7 @@ fn hexa(self: *Self) Token { .IntegerValue, null, null, - std.fmt.parseInt(i32, self.source[self.current.start + 2 .. self.current.offset], 16) catch { + std.fmt.parseInt(v.Integer, self.source[self.current.start + 2 .. self.current.offset], 16) catch { return self.makeToken( .Error, "int overflow", @@ -611,7 +612,7 @@ fn match(self: *Self, expected: u8) bool { return true; } -fn makeToken(self: *Self, tag: Token.Type, literal_string: ?[]const u8, literal_float: ?f64, literal_integer: ?i32) Token { +fn makeToken(self: *Self, tag: Token.Type, literal_string: ?[]const u8, literal_float: ?v.Double, literal_integer: ?v.Integer) Token { self.token_index += 1; return Token{ .tag = tag, diff --git a/src/Token.zig b/src/Token.zig index 9ec94738..1325e4c2 100644 --- a/src/Token.zig +++ b/src/Token.zig @@ -1,5 +1,6 @@ const std = @import("std"); const mem = std.mem; +const v = @import("value.zig"); const Self = @This(); @@ -10,8 +11,8 @@ tag: Type, lexeme: []const u8, // Literal is either a string or a number literal_string: ?[]const u8 = null, -literal_float: ?f64 = null, -literal_integer: ?i32 = null, +literal_float: ?v.Double = null, +literal_integer: ?v.Integer = null, line: usize, column: usize, offset: usize = 0, diff --git a/src/builtin/fiber.zig b/src/builtin/fiber.zig index 42005823..7a14b97a 100644 --- a/src/builtin/fiber.zig +++ b/src/builtin/fiber.zig @@ -1,21 +1,18 @@ const std = @import("std"); -const _obj = @import("../obj.zig"); -const ObjFiber = _obj.ObjFiber; -const NativeCtx = _obj.NativeCtx; +const o = @import("../obj.zig"); const VM = @import("../vm.zig").VM; -const _value = @import("../value.zig"); -const Value = _value.Value; +const v = @import("../value.zig"); -pub fn over(ctx: *NativeCtx) callconv(.c) c_int { - const self = ObjFiber.cast(ctx.vm.peek(0).obj()).?; +pub fn over(ctx: *o.NativeCtx) callconv(.c) c_int { + const self = o.ObjFiber.cast(ctx.vm.peek(0).obj()).?; - ctx.vm.push(Value.fromBoolean(self.fiber.status == .Over)); + ctx.vm.push(v.Value.fromBoolean(self.fiber.status == .Over)); return 1; } -pub fn cancel(ctx: *NativeCtx) callconv(.c) c_int { - const self = ObjFiber.cast(ctx.vm.peek(0).obj()).?; +pub fn cancel(ctx: *o.NativeCtx) callconv(.c) c_int { + const self = o.ObjFiber.cast(ctx.vm.peek(0).obj()).?; // Main fiber can't be cancelled if (self.fiber.parent_fiber == null) { @@ -27,10 +24,10 @@ pub fn cancel(ctx: *NativeCtx) callconv(.c) c_int { return 0; } -pub fn isMain(ctx: *NativeCtx) callconv(.c) c_int { - const self = ObjFiber.cast(ctx.vm.peek(0).obj()).?; +pub fn isMain(ctx: *o.NativeCtx) callconv(.c) c_int { + const self = o.ObjFiber.cast(ctx.vm.peek(0).obj()).?; - ctx.vm.push(Value.fromBoolean(self.fiber.parent_fiber == null)); + ctx.vm.push(v.Value.fromBoolean(self.fiber.parent_fiber == null)); return 1; } diff --git a/src/builtin/list.zig b/src/builtin/list.zig index b082c68f..32b0a1e8 100644 --- a/src/builtin/list.zig +++ b/src/builtin/list.zig @@ -1,19 +1,14 @@ const builtin = @import("builtin"); const std = @import("std"); -const _obj = @import("../obj.zig"); -const ObjString = _obj.ObjString; -const ObjList = _obj.ObjList; -const ObjTypeDef = _obj.ObjTypeDef; -const ObjClosure = _obj.ObjClosure; -const NativeCtx = _obj.NativeCtx; +const o = @import("../obj.zig"); const VM = @import("../vm.zig").VM; -const Value = @import("../value.zig").Value; +const v = @import("../value.zig"); const buzz_api = @import("../buzz_api.zig"); -pub fn append(ctx: *NativeCtx) callconv(.c) c_int { - const list_value: Value = ctx.vm.peek(1); - const list: *ObjList = ObjList.cast(list_value.obj()).?; - const value: Value = ctx.vm.peek(0); +pub fn append(ctx: *o.NativeCtx) callconv(.c) c_int { + const list_value: v.Value = ctx.vm.peek(1); + const list: *o.ObjList = o.ObjList.cast(list_value.obj()).?; + const value: v.Value = ctx.vm.peek(0); list.rawAppend( ctx.vm.gc, @@ -26,16 +21,16 @@ pub fn append(ctx: *NativeCtx) callconv(.c) c_int { return 0; } -pub fn insert(ctx: *NativeCtx) callconv(.c) c_int { - const list_value: Value = ctx.vm.peek(2); - const list: *ObjList = ObjList.cast(list_value.obj()).?; +pub fn insert(ctx: *o.NativeCtx) callconv(.c) c_int { + const list_value: v.Value = ctx.vm.peek(2); + const list: *o.ObjList = o.ObjList.cast(list_value.obj()).?; var index = ctx.vm.peek(1).integer(); - const value: Value = ctx.vm.peek(0); + const value: v.Value = ctx.vm.peek(0); if (index < 0 or list.items.items.len == 0) { index = 0; } else if (index >= list.items.items.len) { - index = @as(i32, @intCast(list.items.items.len)) - 1; + index = @as(v.Integer, @intCast(list.items.items.len)) - 1; } list.rawInsert( @@ -52,20 +47,20 @@ pub fn insert(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn len(ctx: *NativeCtx) callconv(.c) c_int { - const list: *ObjList = ObjList.cast(ctx.vm.peek(0).obj()).?; +pub fn len(ctx: *o.NativeCtx) callconv(.c) c_int { + const list: *o.ObjList = o.ObjList.cast(ctx.vm.peek(0).obj()).?; - ctx.vm.push(Value.fromInteger(@as(i32, @intCast(list.items.items.len)))); + ctx.vm.push(v.Value.fromInteger(@as(v.Integer, @intCast(list.items.items.len)))); return 1; } -pub fn reverse(ctx: *NativeCtx) callconv(.c) c_int { - const list: *ObjList = ObjList.cast(ctx.vm.peek(0).obj()).?; +pub fn reverse(ctx: *o.NativeCtx) callconv(.c) c_int { + const list: *o.ObjList = o.ObjList.cast(ctx.vm.peek(0).obj()).?; var new_list = ctx.vm.gc.allocateObject( - ObjList, - ObjList.init(ctx.vm.gc.allocator, list.type_def) catch { + o.ObjList, + o.ObjList.init(ctx.vm.gc.allocator, list.type_def) catch { ctx.vm.panic("Out of memory"); unreachable; }, @@ -78,31 +73,31 @@ pub fn reverse(ctx: *NativeCtx) callconv(.c) c_int { ctx.vm.panic("Out of memory"); unreachable; }; - std.mem.reverse(Value, new_list.items.items); + std.mem.reverse(v.Value, new_list.items.items); ctx.vm.push(new_list.toValue()); return 1; } -pub fn pop(ctx: *NativeCtx) callconv(.c) c_int { - const list: *ObjList = ObjList.cast(ctx.vm.peek(0).obj()).?; +pub fn pop(ctx: *o.NativeCtx) callconv(.c) c_int { + const list: *o.ObjList = o.ObjList.cast(ctx.vm.peek(0).obj()).?; if (list.items.items.len > 0) { ctx.vm.push(list.items.pop().?); } else { - ctx.vm.push(Value.Null); + ctx.vm.push(v.Value.Null); } return 1; } -pub fn remove(ctx: *NativeCtx) callconv(.c) c_int { - const list: *ObjList = ObjList.cast(ctx.vm.peek(1).obj()).?; +pub fn remove(ctx: *o.NativeCtx) callconv(.c) c_int { + const list: *o.ObjList = o.ObjList.cast(ctx.vm.peek(1).obj()).?; const list_index = ctx.vm.peek(0).integer(); if (list_index < 0 or list_index >= list.items.items.len) { - ctx.vm.push(Value.Null); + ctx.vm.push(v.Value.Null); return 1; } @@ -117,12 +112,12 @@ pub fn remove(ctx: *NativeCtx) callconv(.c) c_int { } const SortContext = struct { - sort_closure: Value, - ctx: *NativeCtx, + sort_closure: v.Value, + ctx: *o.NativeCtx, }; -fn lessThan(context: SortContext, lhs: Value, rhs: Value) bool { - var args = [_]*const Value{ &lhs, &rhs }; +fn lessThan(context: SortContext, lhs: v.Value, rhs: v.Value) bool { + var args = [_]*const v.Value{ &lhs, &rhs }; buzz_api.bz_call( context.ctx.vm, @@ -135,13 +130,13 @@ fn lessThan(context: SortContext, lhs: Value, rhs: Value) bool { return context.ctx.vm.pop().boolean(); } -pub fn sort(ctx: *NativeCtx) callconv(.c) c_int { - var self = ObjList.cast(ctx.vm.peek(1).obj()).?; +pub fn sort(ctx: *o.NativeCtx) callconv(.c) c_int { + var self = o.ObjList.cast(ctx.vm.peek(1).obj()).?; // fun compare(T lhs, T rhs) > bool const sort_closure = ctx.vm.peek(0); std.sort.insertion( - Value, + v.Value, self.items.items, SortContext{ .sort_closure = sort_closure, @@ -156,9 +151,9 @@ pub fn sort(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn indexOf(ctx: *NativeCtx) callconv(.c) c_int { - const self: *ObjList = ObjList.cast(ctx.vm.peek(1).obj()).?; - const needle: Value = ctx.vm.peek(0); +pub fn indexOf(ctx: *o.NativeCtx) callconv(.c) c_int { + const self: *o.ObjList = o.ObjList.cast(ctx.vm.peek(1).obj()).?; + const needle: v.Value = ctx.vm.peek(0); var index: ?usize = null; var i: usize = 0; @@ -172,19 +167,19 @@ pub fn indexOf(ctx: *NativeCtx) callconv(.c) c_int { } ctx.vm.push(if (index) |uindex| - Value.fromInteger(@as(i32, @intCast(uindex))) + v.Value.fromInteger(@as(v.Integer, @intCast(uindex))) else - Value.Null); + v.Value.Null); return 1; } -fn cloneRaw(ctx: *NativeCtx, mutable: bool) void { - const self: *ObjList = ObjList.cast(ctx.vm.peek(0).obj()).?; +fn cloneRaw(ctx: *o.NativeCtx, mutable: bool) void { + const self: *o.ObjList = o.ObjList.cast(ctx.vm.peek(0).obj()).?; var new_list = ctx.vm.gc.allocateObject( - ObjList, - ObjList.init( + o.ObjList, + o.ObjList.init( ctx.vm.gc.allocator, self.type_def.cloneMutable(&ctx.vm.gc.type_registry, mutable) catch { ctx.vm.panic("Out of memory"); @@ -207,21 +202,21 @@ fn cloneRaw(ctx: *NativeCtx, mutable: bool) void { ctx.vm.push(new_list.toValue()); } -pub fn cloneImmutable(ctx: *NativeCtx) callconv(.c) c_int { +pub fn cloneImmutable(ctx: *o.NativeCtx) callconv(.c) c_int { cloneRaw(ctx, false); return 1; } -pub fn cloneMutable(ctx: *NativeCtx) callconv(.c) c_int { +pub fn cloneMutable(ctx: *o.NativeCtx) callconv(.c) c_int { cloneRaw(ctx, true); return 1; } -pub fn join(ctx: *NativeCtx) callconv(.c) c_int { - const self = ObjList.cast(ctx.vm.peek(1).obj()).?; - const separator = ObjString.cast(ctx.vm.peek(0).obj()).?; +pub fn join(ctx: *o.NativeCtx) callconv(.c) c_int { + const self = o.ObjList.cast(ctx.vm.peek(1).obj()).?; + const separator = o.ObjString.cast(ctx.vm.peek(0).obj()).?; var result = std.ArrayList(u8).init(ctx.vm.gc.allocator); var writer = result.writer(); @@ -250,8 +245,8 @@ pub fn join(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn sub(ctx: *NativeCtx) callconv(.c) c_int { - const self: *ObjList = ObjList.cast(ctx.vm.peek(2).obj()).?; +pub fn sub(ctx: *o.NativeCtx) callconv(.c) c_int { + const self: *o.ObjList = o.ObjList.cast(ctx.vm.peek(2).obj()).?; const start = @min( @max( 0, @@ -270,7 +265,7 @@ pub fn sub(ctx: *NativeCtx) callconv(.c) c_int { self.items.items.len; const substr = self.items.items[@intCast(start)..limit]; - var methods = std.ArrayList(?*_obj.ObjNative) + var methods = std.ArrayList(?*o.ObjNative) .fromOwnedSlice(ctx.vm.gc.allocator, self.methods) .clone() catch { ctx.vm.panic("Out of memory"); @@ -278,14 +273,14 @@ pub fn sub(ctx: *NativeCtx) callconv(.c) c_int { }; var list = ctx.vm.gc.allocateObject( - ObjList, + o.ObjList, .{ .type_def = self.type_def, .methods = methods.toOwnedSlice() catch { ctx.vm.panic("Out of memory"); unreachable; }, - .items = std.ArrayListUnmanaged(Value){}, + .items = std.ArrayListUnmanaged(v.Value){}, }, ) catch { ctx.vm.panic("Out of memory"); @@ -302,12 +297,12 @@ pub fn sub(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn next(ctx: *NativeCtx) callconv(.c) c_int { - const list_value: Value = ctx.vm.peek(1); - const list: *ObjList = ObjList.cast(list_value.obj()).?; - const list_index: Value = ctx.vm.peek(0); +pub fn next(ctx: *o.NativeCtx) callconv(.c) c_int { + const list_value: v.Value = ctx.vm.peek(1); + const list: *o.ObjList = o.ObjList.cast(list_value.obj()).?; + const list_index: v.Value = ctx.vm.peek(0); - const next_index: ?i32 = list.rawNext( + const next_index: ?v.Integer = list.rawNext( ctx.vm, list_index.integerOrNull(), ) catch { @@ -317,22 +312,22 @@ pub fn next(ctx: *NativeCtx) callconv(.c) c_int { ctx.vm.push( if (next_index) |unext_index| - Value.fromInteger(unext_index) + v.Value.fromInteger(unext_index) else - Value.Null, + v.Value.Null, ); return 1; } -pub fn forEach(ctx: *NativeCtx) callconv(.c) c_int { - const list = ObjList.cast(ctx.vm.peek(1).obj()).?; +pub fn forEach(ctx: *o.NativeCtx) callconv(.c) c_int { + const list = o.ObjList.cast(ctx.vm.peek(1).obj()).?; const closure = ctx.vm.peek(0); for (list.items.items, 0..) |item, index| { - const index_value = Value.fromInteger(@as(i32, @intCast(index))); + const index_value = v.Value.fromInteger(@as(v.Integer, @intCast(index))); - var args = [_]*const Value{ &index_value, &item }; + var args = [_]*const v.Value{ &index_value, &item }; buzz_api.bz_call( ctx.vm, @@ -346,15 +341,15 @@ pub fn forEach(ctx: *NativeCtx) callconv(.c) c_int { return 0; } -pub fn reduce(ctx: *NativeCtx) callconv(.c) c_int { - const list = ObjList.cast(ctx.vm.peek(2).obj()).?; +pub fn reduce(ctx: *o.NativeCtx) callconv(.c) c_int { + const list = o.ObjList.cast(ctx.vm.peek(2).obj()).?; const closure = ctx.vm.peek(1); var accumulator = ctx.vm.peek(0); for (list.items.items, 0..) |item, index| { - const index_value = Value.fromInteger(@as(i32, @intCast(index))); + const index_value = v.Value.fromInteger(@as(v.Integer, @intCast(index))); - var args = [_]*const Value{ + var args = [_]*const v.Value{ &index_value, &item, &accumulator, @@ -376,13 +371,13 @@ pub fn reduce(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn filter(ctx: *NativeCtx) callconv(.c) c_int { - const list = ObjList.cast(ctx.vm.peek(1).obj()).?; +pub fn filter(ctx: *o.NativeCtx) callconv(.c) c_int { + const list = o.ObjList.cast(ctx.vm.peek(1).obj()).?; const closure = ctx.vm.peek(0); - var new_list: *ObjList = ctx.vm.gc.allocateObject( - ObjList, - ObjList.init( + var new_list: *o.ObjList = ctx.vm.gc.allocateObject( + o.ObjList, + o.ObjList.init( ctx.vm.gc.allocator, list.type_def, ) catch { @@ -395,8 +390,8 @@ pub fn filter(ctx: *NativeCtx) callconv(.c) c_int { }; for (list.items.items, 0..) |item, index| { - const index_value = Value.fromInteger(@as(i32, @intCast(index))); - var args = [_]*const Value{ &index_value, &item }; + const index_value = v.Value.fromInteger(@as(v.Integer, @intCast(index))); + var args = [_]*const v.Value{ &index_value, &item }; buzz_api.bz_call( ctx.vm, @@ -419,24 +414,24 @@ pub fn filter(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn map(ctx: *NativeCtx) callconv(.c) c_int { - const list = ObjList.cast(ctx.vm.peek(1).obj()).?; +pub fn map(ctx: *o.NativeCtx) callconv(.c) c_int { + const list = o.ObjList.cast(ctx.vm.peek(1).obj()).?; const closure = ctx.vm.peek(0); - const mapped_type = ObjClosure.cast(closure.obj()).? + const mapped_type = o.ObjClosure.cast(closure.obj()).? .function .type_def.resolved_type.?.Function .return_type; - var new_list: *ObjList = ctx.vm.gc.allocateObject( - ObjList, - ObjList.init( + var new_list: *o.ObjList = ctx.vm.gc.allocateObject( + o.ObjList, + o.ObjList.init( ctx.vm.gc.allocator, ctx.vm.gc.type_registry.getTypeDef( .{ .def_type = .List, .resolved_type = .{ - .List = ObjList.ListDef.init( + .List = o.ObjList.ListDef.init( mapped_type, false, ), @@ -456,8 +451,8 @@ pub fn map(ctx: *NativeCtx) callconv(.c) c_int { }; for (list.items.items, 0..) |item, index| { - const index_value = Value.fromInteger(@as(i32, @intCast(index))); - var args = [_]*const Value{ &index_value, &item }; + const index_value = v.Value.fromInteger(@as(v.Integer, @intCast(index))); + var args = [_]*const v.Value{ &index_value, &item }; buzz_api.bz_call( ctx.vm, @@ -478,8 +473,8 @@ pub fn map(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn fill(ctx: *NativeCtx) callconv(.c) c_int { - const self: *ObjList = ObjList.cast(ctx.vm.peek(3).obj()).?; +pub fn fill(ctx: *o.NativeCtx) callconv(.c) c_int { + const self: *o.ObjList = o.ObjList.cast(ctx.vm.peek(3).obj()).?; const value = ctx.vm.peek(2); const start: usize = @intCast( @min( diff --git a/src/builtin/map.zig b/src/builtin/map.zig index bb535fde..baec71a4 100644 --- a/src/builtin/map.zig +++ b/src/builtin/map.zig @@ -1,26 +1,15 @@ const std = @import("std"); -const _obj = @import("../obj.zig"); -const ObjString = _obj.ObjString; -const ObjMap = _obj.ObjMap; -const ObjList = _obj.ObjList; -const ObjTypeDef = _obj.ObjTypeDef; -const ObjClosure = _obj.ObjClosure; -const ObjObjectInstance = _obj.ObjObjectInstance; -const NativeCtx = _obj.NativeCtx; +const o = @import("../obj.zig"); const VM = @import("../vm.zig").VM; -const _value = @import("../value.zig"); +const v = @import("../value.zig"); const buzz_api = @import("../buzz_api.zig"); -const Value = _value.Value; -const floatToInteger = _value.floatToInteger; -const eql = _value.eql; -const toString = _value.toString; -fn cloneRaw(ctx: *NativeCtx, mutable: bool) void { - const self = ObjMap.cast(ctx.vm.peek(0).obj()).?; +fn cloneRaw(ctx: *o.NativeCtx, mutable: bool) void { + const self = o.ObjMap.cast(ctx.vm.peek(0).obj()).?; var new_map = ctx.vm.gc.allocateObject( - ObjMap, - ObjMap.init( + o.ObjMap, + o.ObjMap.init( ctx.vm.gc.allocator, self.type_def.cloneMutable(&ctx.vm.gc.type_registry, mutable) catch { ctx.vm.panic("Out of memory"); @@ -43,26 +32,26 @@ fn cloneRaw(ctx: *NativeCtx, mutable: bool) void { ctx.vm.push(new_map.toValue()); } -pub fn cloneMutable(ctx: *NativeCtx) callconv(.c) c_int { +pub fn cloneMutable(ctx: *o.NativeCtx) callconv(.c) c_int { cloneRaw(ctx, true); return 1; } -pub fn cloneImmutable(ctx: *NativeCtx) callconv(.c) c_int { +pub fn cloneImmutable(ctx: *o.NativeCtx) callconv(.c) c_int { cloneRaw(ctx, false); return 1; } -pub fn reduce(ctx: *NativeCtx) callconv(.c) c_int { - const self = ObjMap.cast(ctx.vm.peek(2).obj()).?; +pub fn reduce(ctx: *o.NativeCtx) callconv(.c) c_int { + const self = o.ObjMap.cast(ctx.vm.peek(2).obj()).?; const closure = ctx.vm.peek(1); var accumulator = ctx.vm.peek(0); var it = self.map.iterator(); while (it.next()) |kv| { - var args = [_]*const Value{ kv.key_ptr, kv.value_ptr, &accumulator }; + var args = [_]*const v.Value{ kv.key_ptr, kv.value_ptr, &accumulator }; buzz_api.bz_call( ctx.vm, @@ -80,13 +69,13 @@ pub fn reduce(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn filter(ctx: *NativeCtx) callconv(.c) c_int { - const self = ObjMap.cast(ctx.vm.peek(1).obj()).?; +pub fn filter(ctx: *o.NativeCtx) callconv(.c) c_int { + const self = o.ObjMap.cast(ctx.vm.peek(1).obj()).?; const closure = ctx.vm.peek(0); - var new_map: *ObjMap = ctx.vm.gc.allocateObject( - ObjMap, - ObjMap.init( + var new_map: *o.ObjMap = ctx.vm.gc.allocateObject( + o.ObjMap, + o.ObjMap.init( ctx.vm.gc.allocator, self.type_def, ) catch { @@ -100,7 +89,7 @@ pub fn filter(ctx: *NativeCtx) callconv(.c) c_int { var it = self.map.iterator(); while (it.next()) |kv| { - var args = [_]*const Value{ kv.key_ptr, kv.value_ptr }; + var args = [_]*const v.Value{ kv.key_ptr, kv.value_ptr }; buzz_api.bz_call( ctx.vm, @@ -123,13 +112,13 @@ pub fn filter(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn forEach(ctx: *NativeCtx) callconv(.c) c_int { - const self = ObjMap.cast(ctx.vm.peek(1).obj()).?; +pub fn forEach(ctx: *o.NativeCtx) callconv(.c) c_int { + const self = o.ObjMap.cast(ctx.vm.peek(1).obj()).?; const closure = ctx.vm.peek(0); var it = self.map.iterator(); while (it.next()) |kv| { - var args = [_]*const Value{ kv.key_ptr, kv.value_ptr }; + var args = [_]*const v.Value{ kv.key_ptr, kv.value_ptr }; buzz_api.bz_call( ctx.vm, @@ -143,24 +132,24 @@ pub fn forEach(ctx: *NativeCtx) callconv(.c) c_int { return 0; } -pub fn map(ctx: *NativeCtx) callconv(.c) c_int { - const self = ObjMap.cast(ctx.vm.peek(1).obj()).?; +pub fn map(ctx: *o.NativeCtx) callconv(.c) c_int { + const self = o.ObjMap.cast(ctx.vm.peek(1).obj()).?; const closure = ctx.vm.peek(0); - const mapped_type = ObjClosure.cast(closure.obj()).?.function.type_def.resolved_type.?.Function + const mapped_type = o.ObjClosure.cast(closure.obj()).?.function.type_def.resolved_type.?.Function .return_type.resolved_type.?.ObjectInstance.of .resolved_type.?.Object; - var new_map: *ObjMap = ctx.vm.gc.allocateObject( - ObjMap, - ObjMap.init( + var new_map: *o.ObjMap = ctx.vm.gc.allocateObject( + o.ObjMap, + o.ObjMap.init( ctx.vm.gc.allocator, ctx.vm.gc.type_registry.getTypeDef( .{ .optional = false, .def_type = .Map, .resolved_type = .{ - .Map = ObjMap.MapDef.init( + .Map = o.ObjMap.MapDef.init( mapped_type.fields.get("key").?.type_def, mapped_type.fields.get("value").?.type_def, self.type_def.resolved_type.?.Map.mutable, @@ -182,7 +171,7 @@ pub fn map(ctx: *NativeCtx) callconv(.c) c_int { var it = self.map.iterator(); while (it.next()) |kv| { - var args = [_]*const Value{ kv.key_ptr, kv.value_ptr }; + var args = [_]*const v.Value{ kv.key_ptr, kv.value_ptr }; buzz_api.bz_call( ctx.vm, @@ -192,7 +181,7 @@ pub fn map(ctx: *NativeCtx) callconv(.c) c_int { null, ); - const instance = ObjObjectInstance.cast(ctx.vm.pop().obj()).?; + const instance = o.ObjObjectInstance.cast(ctx.vm.pop().obj()).?; const object_def = instance.type_def.resolved_type.?.ObjectInstance.of .resolved_type.?.Object; @@ -212,16 +201,16 @@ pub fn map(ctx: *NativeCtx) callconv(.c) c_int { } const SortContext = struct { - sort_closure: Value, - ctx: *NativeCtx, - map: *ObjMap, + sort_closure: v.Value, + ctx: *o.NativeCtx, + map: *o.ObjMap, pub fn lessThan(context: SortContext, lhs_index: usize, rhs_index: usize) bool { const map_keys = context.map.map.keys(); const lhs = map_keys[lhs_index]; const rhs = map_keys[rhs_index]; - var args = [_]*const Value{ &lhs, &rhs }; + var args = [_]*const v.Value{ &lhs, &rhs }; buzz_api.bz_call( context.ctx.vm, @@ -235,8 +224,8 @@ const SortContext = struct { } }; -pub fn sort(ctx: *NativeCtx) callconv(.c) c_int { - const self: *ObjMap = ObjMap.cast(ctx.vm.peek(1).obj()).?; +pub fn sort(ctx: *o.NativeCtx) callconv(.c) c_int { + const self: *o.ObjMap = o.ObjMap.cast(ctx.vm.peek(1).obj()).?; const sort_closure = ctx.vm.peek(0); self.map.sort( @@ -253,13 +242,13 @@ pub fn sort(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn diff(ctx: *NativeCtx) callconv(.c) c_int { - const lhs: *ObjMap = ObjMap.cast(ctx.vm.peek(1).obj()).?; - const rhs: *ObjMap = ObjMap.cast(ctx.vm.peek(0).obj()).?; +pub fn diff(ctx: *o.NativeCtx) callconv(.c) c_int { + const lhs: *o.ObjMap = o.ObjMap.cast(ctx.vm.peek(1).obj()).?; + const rhs: *o.ObjMap = o.ObjMap.cast(ctx.vm.peek(0).obj()).?; - var new_map: *ObjMap = ctx.vm.gc.allocateObject( - ObjMap, - ObjMap.init( + var new_map: *o.ObjMap = ctx.vm.gc.allocateObject( + o.ObjMap, + o.ObjMap.init( ctx.vm.gc.allocator, lhs.type_def, ) catch { @@ -291,13 +280,13 @@ pub fn diff(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn intersect(ctx: *NativeCtx) callconv(.c) c_int { - const lhs: *ObjMap = ObjMap.cast(ctx.vm.peek(1).obj()).?; - const rhs: *ObjMap = ObjMap.cast(ctx.vm.peek(0).obj()).?; +pub fn intersect(ctx: *o.NativeCtx) callconv(.c) c_int { + const lhs: *o.ObjMap = o.ObjMap.cast(ctx.vm.peek(1).obj()).?; + const rhs: *o.ObjMap = o.ObjMap.cast(ctx.vm.peek(0).obj()).?; - var new_map: *ObjMap = ctx.vm.gc.allocateObject( - ObjMap, - ObjMap.init( + var new_map: *o.ObjMap = ctx.vm.gc.allocateObject( + o.ObjMap, + o.ObjMap.init( ctx.vm.gc.allocator, lhs.type_def, ) catch { @@ -329,32 +318,32 @@ pub fn intersect(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn size(ctx: *NativeCtx) callconv(.c) c_int { - const self: *ObjMap = ObjMap.cast(ctx.vm.peek(0).obj()).?; +pub fn size(ctx: *o.NativeCtx) callconv(.c) c_int { + const self: *o.ObjMap = o.ObjMap.cast(ctx.vm.peek(0).obj()).?; - ctx.vm.push(Value.fromInteger(@intCast(self.map.count()))); + ctx.vm.push(v.Value.fromInteger(@intCast(self.map.count()))); return 1; } -pub fn remove(ctx: *NativeCtx) callconv(.c) c_int { - const self: *ObjMap = ObjMap.cast(ctx.vm.peek(1).obj()).?; +pub fn remove(ctx: *o.NativeCtx) callconv(.c) c_int { + const self: *o.ObjMap = o.ObjMap.cast(ctx.vm.peek(1).obj()).?; const map_key = ctx.vm.peek(0); if (self.map.fetchOrderedRemove(map_key)) |removed| { ctx.vm.push(removed.value); } else { - ctx.vm.push(Value.Null); + ctx.vm.push(v.Value.Null); } return 1; } -pub fn keys(ctx: *NativeCtx) callconv(.c) c_int { - const self: *ObjMap = ObjMap.cast(ctx.vm.peek(0).obj()).?; +pub fn keys(ctx: *o.NativeCtx) callconv(.c) c_int { + const self: *o.ObjMap = o.ObjMap.cast(ctx.vm.peek(0).obj()).?; const map_keys = self.map.keys(); - var result = std.ArrayListUnmanaged(Value){}; + var result = std.ArrayListUnmanaged(v.Value){}; for (map_keys) |key| { result.append(ctx.vm.gc.allocator, key) catch { ctx.vm.panic("Out of memory"); @@ -362,12 +351,12 @@ pub fn keys(ctx: *NativeCtx) callconv(.c) c_int { }; } - var list_def_type: *ObjTypeDef = ctx.vm.gc.type_registry.getTypeDef( + var list_def_type: *o.ObjTypeDef = ctx.vm.gc.type_registry.getTypeDef( .{ .def_type = .List, .optional = false, .resolved_type = .{ - .List = ObjList.ListDef.init( + .List = o.ObjList.ListDef.init( self.type_def.resolved_type.?.Map.key_type, false, ), @@ -382,8 +371,8 @@ pub fn keys(ctx: *NativeCtx) callconv(.c) c_int { ctx.vm.push(list_def_type.toValue()); var list = ctx.vm.gc.allocateObject( - ObjList, - ObjList.init(ctx.vm.gc.allocator, list_def_type) catch { + o.ObjList, + o.ObjList.init(ctx.vm.gc.allocator, list_def_type) catch { ctx.vm.panic("Out of memory"); unreachable; }, @@ -401,22 +390,22 @@ pub fn keys(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn values(ctx: *NativeCtx) callconv(.c) c_int { - const self: *ObjMap = ObjMap.cast(ctx.vm.peek(0).obj()).?; +pub fn values(ctx: *o.NativeCtx) callconv(.c) c_int { + const self: *o.ObjMap = o.ObjMap.cast(ctx.vm.peek(0).obj()).?; - const map_values: []Value = self.map.values(); - var result = std.ArrayListUnmanaged(Value){}; + const map_values: []v.Value = self.map.values(); + var result = std.ArrayListUnmanaged(v.Value){}; result.appendSlice(ctx.vm.gc.allocator, map_values) catch { ctx.vm.panic("Out of memory"); unreachable; }; const list_def_type = ctx.vm.gc.type_registry.getTypeDef( - ObjTypeDef{ + o.ObjTypeDef{ .def_type = .List, .optional = false, .resolved_type = .{ - .List = ObjList.ListDef.init( + .List = o.ObjList.ListDef.init( self.type_def.resolved_type.?.Map.value_type, false, ), @@ -428,8 +417,8 @@ pub fn values(ctx: *NativeCtx) callconv(.c) c_int { }; var list = ctx.vm.gc.allocateObject( - ObjList, - ObjList.init(ctx.vm.gc.allocator, list_def_type) catch { + o.ObjList, + o.ObjList.init(ctx.vm.gc.allocator, list_def_type) catch { ctx.vm.panic("Out of memory"); unreachable; }, diff --git a/src/builtin/pattern.zig b/src/builtin/pattern.zig index db179f0a..9e705043 100644 --- a/src/builtin/pattern.zig +++ b/src/builtin/pattern.zig @@ -1,13 +1,7 @@ const std = @import("std"); -const _obj = @import("../obj.zig"); -const ObjPattern = _obj.ObjPattern; -const ObjString = _obj.ObjString; -const ObjList = _obj.ObjList; -const ObjTypeDef = _obj.ObjTypeDef; -const NativeCtx = _obj.NativeCtx; +const o = @import("../obj.zig"); const VM = @import("../vm.zig").VM; -const _value = @import("../value.zig"); -const Value = _value.Value; +const v = @import("../value.zig"); const builtin = @import("builtin"); const is_wasm = builtin.cpu.arch.isWasm(); const Token = @import("../Token.zig"); @@ -66,12 +60,12 @@ const fake_token: Token = .{ }; // Return match anonymous object type: obj{ start: int, end: int, capture: str } -fn matchType(vm: *VM) !*ObjTypeDef { +fn matchType(vm: *VM) !*o.ObjTypeDef { if (vm.gc.type_registry.registry.get(".{ capture: str, start: int, end: int }")) |type_def| { return type_def; } - var object_def = _obj.ObjObject.ObjectDef.init( + var object_def = o.ObjObject.ObjectDef.init( fake_token, try vm.gc.copyString("match"), try vm.gc.copyString("builtin.match"), @@ -139,12 +133,12 @@ fn matchType(vm: *VM) !*ObjTypeDef { ); } -fn rawMatch(self: *ObjPattern, vm: *VM, subject: *ObjString, offset: *usize) !?*ObjList { +fn rawMatch(self: *o.ObjPattern, vm: *VM, subject: *o.ObjString, offset: *usize) !?*o.ObjList { if (subject.string.len == 0) { return null; } - var results: ?*ObjList = null; + var results: ?*o.ObjList = null; var match_data = self.pattern.createMatchData(null) orelse { vm.panic("Out of memory"); unreachable; @@ -173,15 +167,15 @@ fn rawMatch(self: *ObjPattern, vm: *VM, subject: *ObjString, offset: *usize) !?* offset.* = @intCast(output_vector[1]); results = try vm.gc.allocateObject( - ObjList, - try ObjList.init( + o.ObjList, + try o.ObjList.init( vm.gc.allocator, try vm.gc.type_registry.getTypeDef( .{ .def_type = .List, .optional = false, .resolved_type = .{ - .List = ObjList.ListDef.init( + .List = o.ObjList.ListDef.init( vm.gc.type_registry.str_type, false, ), @@ -199,8 +193,8 @@ fn rawMatch(self: *ObjPattern, vm: *VM, subject: *ObjString, offset: *usize) !?* var i: usize = 0; while (i < rc) : (i += 1) { const match_instance = try vm.gc.allocateObject( - _obj.ObjObjectInstance, - try _obj.ObjObjectInstance.init( + o.ObjObjectInstance, + try o.ObjObjectInstance.init( vm, null, match_type, @@ -209,9 +203,9 @@ fn rawMatch(self: *ObjPattern, vm: *VM, subject: *ObjString, offset: *usize) !?* ); // start - match_instance.fields[2] = Value.fromInteger(@intCast(output_vector[2 * i])); + match_instance.fields[2] = v.Value.fromInteger(@intCast(output_vector[2 * i])); // end - match_instance.fields[1] = Value.fromInteger(@intCast(output_vector[2 * i + 1])); + match_instance.fields[1] = v.Value.fromInteger(@intCast(output_vector[2 * i + 1])); // capture match_instance.fields[0] = (try vm.gc.copyString( subject.string[@intCast(output_vector[2 * i])..@intCast(output_vector[2 * i + 1])], @@ -230,26 +224,26 @@ fn rawMatch(self: *ObjPattern, vm: *VM, subject: *ObjString, offset: *usize) !?* return results; } -fn rawMatchAll(self: *ObjPattern, vm: *VM, subject: *ObjString) !?*ObjList { +fn rawMatchAll(self: *o.ObjPattern, vm: *VM, subject: *o.ObjString) !?*o.ObjList { if (subject.string.len == 0) { return null; } - var results: ?*ObjList = null; + var results: ?*o.ObjList = null; var offset: usize = 0; while (true) { if (try rawMatch(self, vm, subject, &offset)) |matches| { const was_null = results == null; results = results orelse try vm.gc.allocateObject( - ObjList, - try ObjList.init( + o.ObjList, + try o.ObjList.init( vm.gc.allocator, try vm.gc.type_registry.getTypeDef( .{ .def_type = .List, .optional = false, .resolved_type = .{ - .List = ObjList.ListDef.init( + .List = o.ObjList.ListDef.init( matches.type_def, false, ), @@ -280,7 +274,7 @@ fn rawMatchAll(self: *ObjPattern, vm: *VM, subject: *ObjString) !?*ObjList { return results; } -fn rawReplace(self: *ObjPattern, vm: *VM, subject: *ObjString, replacement: *ObjString, offset: *usize) !*ObjString { +fn rawReplace(self: *o.ObjPattern, vm: *VM, subject: *o.ObjString, replacement: *o.ObjString, offset: *usize) !*o.ObjString { if (subject.string.len == 0) { return subject; } @@ -324,7 +318,7 @@ fn rawReplace(self: *ObjPattern, vm: *VM, subject: *ObjString, replacement: *Obj return try vm.gc.copyString(result.items); } -fn rawReplaceAll(self: *ObjPattern, vm: *VM, subject: *ObjString, replacement: *ObjString) !*ObjString { +fn rawReplaceAll(self: *o.ObjPattern, vm: *VM, subject: *o.ObjString, replacement: *o.ObjString) !*o.ObjString { if (subject.string.len == 0) { return subject; } @@ -350,9 +344,9 @@ fn rawReplaceAll(self: *ObjPattern, vm: *VM, subject: *ObjString, replacement: * return current; } -pub fn match(ctx: *NativeCtx) callconv(.c) c_int { - const self = ObjPattern.cast(ctx.vm.peek(1).obj()).?; - const subject = ObjString.cast(ctx.vm.peek(0).obj()).?; +pub fn match(ctx: *o.NativeCtx) callconv(.c) c_int { + const self = o.ObjPattern.cast(ctx.vm.peek(1).obj()).?; + const subject = o.ObjString.cast(ctx.vm.peek(0).obj()).?; var offset: usize = 0; if (rawMatch( @@ -366,16 +360,16 @@ pub fn match(ctx: *NativeCtx) callconv(.c) c_int { }) |results| { ctx.vm.push(results.toValue()); } else { - ctx.vm.push(Value.Null); + ctx.vm.push(v.Value.Null); } return 1; } -pub fn replace(ctx: *NativeCtx) callconv(.c) c_int { - const self = ObjPattern.cast(ctx.vm.peek(2).obj()).?; - const subject = ObjString.cast(ctx.vm.peek(1).obj()).?; - const replacement = ObjString.cast(ctx.vm.peek(0).obj()).?; +pub fn replace(ctx: *o.NativeCtx) callconv(.c) c_int { + const self = o.ObjPattern.cast(ctx.vm.peek(2).obj()).?; + const subject = o.ObjString.cast(ctx.vm.peek(1).obj()).?; + const replacement = o.ObjString.cast(ctx.vm.peek(0).obj()).?; if (!is_wasm) { var offset: usize = 0; @@ -432,9 +426,9 @@ pub fn replace(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn matchAll(ctx: *NativeCtx) callconv(.c) c_int { - const self = ObjPattern.cast(ctx.vm.peek(1).obj()).?; - const subject = ObjString.cast(ctx.vm.peek(0).obj()).?; +pub fn matchAll(ctx: *o.NativeCtx) callconv(.c) c_int { + const self = o.ObjPattern.cast(ctx.vm.peek(1).obj()).?; + const subject = o.ObjString.cast(ctx.vm.peek(0).obj()).?; if (rawMatchAll( self, @@ -446,16 +440,16 @@ pub fn matchAll(ctx: *NativeCtx) callconv(.c) c_int { }) |results| { ctx.vm.push(results.toValue()); } else { - ctx.vm.push(Value.Null); + ctx.vm.push(v.Value.Null); } return 1; } -pub fn replaceAll(ctx: *NativeCtx) callconv(.c) c_int { - const self = ObjPattern.cast(ctx.vm.peek(2).obj()).?; - const subject = ObjString.cast(ctx.vm.peek(1).obj()).?; - const replacement = ObjString.cast(ctx.vm.peek(0).obj()).?; +pub fn replaceAll(ctx: *o.NativeCtx) callconv(.c) c_int { + const self = o.ObjPattern.cast(ctx.vm.peek(2).obj()).?; + const subject = o.ObjString.cast(ctx.vm.peek(1).obj()).?; + const replacement = o.ObjString.cast(ctx.vm.peek(0).obj()).?; if (!is_wasm) { const result = rawReplaceAll( diff --git a/src/builtin/range.zig b/src/builtin/range.zig index 85170815..80443974 100644 --- a/src/builtin/range.zig +++ b/src/builtin/range.zig @@ -1,5 +1,5 @@ const obj = @import("../obj.zig"); -const Value = @import("../value.zig").Value; +const v = @import("../value.zig"); pub fn toList(ctx: *obj.NativeCtx) callconv(.c) c_int { const range = ctx.vm.peek(0).obj().access(obj.ObjRange, .Range, ctx.vm.gc).?; @@ -31,20 +31,20 @@ pub fn toList(ctx: *obj.NativeCtx) callconv(.c) c_int { unreachable; }; - ctx.vm.push(Value.fromObj(list.toObj())); + ctx.vm.push(v.Value.fromObj(list.toObj())); if (range.low < range.high) { - var i: i32 = range.low; + var i: v.Integer = range.low; while (i < range.high) : (i += 1) { - list.rawAppend(ctx.vm.gc, Value.fromInteger(i)) catch { + list.rawAppend(ctx.vm.gc, v.Value.fromInteger(i)) catch { ctx.vm.panic("Out of memory"); unreachable; }; } } else { - var i: i32 = range.low; + var i: v.Integer = range.low; while (i > range.high) : (i -= 1) { - list.rawAppend(ctx.vm.gc, Value.fromInteger(i)) catch { + list.rawAppend(ctx.vm.gc, v.Value.fromInteger(i)) catch { ctx.vm.panic("Out of memory"); unreachable; }; @@ -58,7 +58,7 @@ pub fn len(ctx: *obj.NativeCtx) callconv(.c) c_int { const range = ctx.vm.peek(0).obj().access(obj.ObjRange, .Range, ctx.vm.gc).?; ctx.vm.push( - Value.fromInteger( + v.Value.fromInteger( if (range.low < range.high) range.high - range.low else @@ -73,7 +73,7 @@ pub fn invert(ctx: *obj.NativeCtx) callconv(.c) c_int { const range = ctx.vm.peek(0).obj().access(obj.ObjRange, .Range, ctx.vm.gc).?; ctx.vm.push( - Value.fromObj((ctx.vm.gc.allocateObject( + v.Value.fromObj((ctx.vm.gc.allocateObject( obj.ObjRange, .{ .high = range.low, @@ -93,7 +93,7 @@ pub fn subsetOf(ctx: *obj.NativeCtx) callconv(.c) c_int { const rangeB = ctx.vm.peek(0).obj().access(obj.ObjRange, .Range, ctx.vm.gc).?; ctx.vm.push( - Value.fromBoolean( + v.Value.fromBoolean( @min(rangeA.low, rangeA.high) >= @min(rangeB.low, rangeB.high) and @max(rangeA.low, rangeA.high) <= @max(rangeB.low, rangeB.high), ), @@ -107,7 +107,7 @@ pub fn intersect(ctx: *obj.NativeCtx) callconv(.c) c_int { const rangeB = ctx.vm.peek(0).obj().access(obj.ObjRange, .Range, ctx.vm.gc).?; ctx.vm.push( - Value.fromObj((ctx.vm.gc.allocateObject( + v.Value.fromObj((ctx.vm.gc.allocateObject( obj.ObjRange, .{ .high = @max( @@ -133,7 +133,7 @@ pub fn @"union"(ctx: *obj.NativeCtx) callconv(.c) c_int { const rangeB = ctx.vm.peek(0).obj().access(obj.ObjRange, .Range, ctx.vm.gc).?; ctx.vm.push( - Value.fromObj((ctx.vm.gc.allocateObject( + v.Value.fromObj((ctx.vm.gc.allocateObject( obj.ObjRange, .{ .high = @min( @@ -156,7 +156,7 @@ pub fn @"union"(ctx: *obj.NativeCtx) callconv(.c) c_int { pub fn high(ctx: *obj.NativeCtx) callconv(.c) c_int { ctx.vm.push( - Value.fromInteger( + v.Value.fromInteger( ctx.vm.peek(0).obj().access(obj.ObjRange, .Range, ctx.vm.gc).?.high, ), ); @@ -166,7 +166,7 @@ pub fn high(ctx: *obj.NativeCtx) callconv(.c) c_int { pub fn low(ctx: *obj.NativeCtx) callconv(.c) c_int { ctx.vm.push( - Value.fromInteger( + v.Value.fromInteger( ctx.vm.peek(0).obj().access(obj.ObjRange, .Range, ctx.vm.gc).?.low, ), ); @@ -179,7 +179,7 @@ pub fn contains(ctx: *obj.NativeCtx) callconv(.c) c_int { const value = ctx.vm.peek(0).integer(); ctx.vm.push( - Value.fromBoolean( + v.Value.fromBoolean( (range.high >= range.low and value >= range.low and value < range.high) or (range.low >= range.high and value >= range.high and value < range.low), ), diff --git a/src/builtin/str.zig b/src/builtin/str.zig index 72eb7226..5ba58dd0 100644 --- a/src/builtin/str.zig +++ b/src/builtin/str.zig @@ -1,15 +1,10 @@ const std = @import("std"); -const _obj = @import("../obj.zig"); -const ObjString = _obj.ObjString; -const ObjList = _obj.ObjList; -const ObjTypeDef = _obj.ObjTypeDef; -const NativeCtx = _obj.NativeCtx; +const o = @import("../obj.zig"); const VM = @import("../vm.zig").VM; -const _value = @import("../value.zig"); -const Value = _value.Value; +const v = @import("../value.zig"); -pub fn trim(ctx: *NativeCtx) callconv(.c) c_int { - const str = ObjString.cast(ctx.vm.peek(0).obj()).?; +pub fn trim(ctx: *o.NativeCtx) callconv(.c) c_int { + const str = o.ObjString.cast(ctx.vm.peek(0).obj()).?; const trimmed = std.mem.trim(u8, str.string, " \t\r\n"); @@ -21,11 +16,11 @@ pub fn trim(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn len(ctx: *NativeCtx) callconv(.c) c_int { - const str = ObjString.cast(ctx.vm.peek(0).obj()).?; +pub fn len(ctx: *o.NativeCtx) callconv(.c) c_int { + const str = o.ObjString.cast(ctx.vm.peek(0).obj()).?; ctx.vm.push( - Value.fromInteger( + v.Value.fromInteger( @intCast(str.string.len), ), ); @@ -33,11 +28,11 @@ pub fn len(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn utf8Len(ctx: *NativeCtx) callconv(.c) c_int { - const str = ObjString.cast(ctx.vm.peek(0).obj()).?; +pub fn utf8Len(ctx: *o.NativeCtx) callconv(.c) c_int { + const str = o.ObjString.cast(ctx.vm.peek(0).obj()).?; ctx.vm.push( - Value.fromInteger( + v.Value.fromInteger( @intCast(std.unicode.utf8CountCodepoints(str.string) catch 0), ), ); @@ -45,11 +40,11 @@ pub fn utf8Len(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn utf8Valid(ctx: *NativeCtx) callconv(.c) c_int { - const str = ObjString.cast(ctx.vm.peek(0).obj()).?; +pub fn utf8Valid(ctx: *o.NativeCtx) callconv(.c) c_int { + const str = o.ObjString.cast(ctx.vm.peek(0).obj()).?; ctx.vm.push( - Value.fromBoolean( + v.Value.fromBoolean( std.unicode.utf8ValidateSlice(str.string), ), ); @@ -57,15 +52,15 @@ pub fn utf8Valid(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn utf8Codepoints(ctx: *NativeCtx) callconv(.c) c_int { - const str = ObjString.cast(ctx.vm.peek(0).obj()).?; +pub fn utf8Codepoints(ctx: *o.NativeCtx) callconv(.c) c_int { + const str = o.ObjString.cast(ctx.vm.peek(0).obj()).?; const list_def_type = ctx.vm.gc.type_registry.getTypeDef( - ObjTypeDef{ + o.ObjTypeDef{ .def_type = .List, .optional = false, .resolved_type = .{ - .List = ObjList.ListDef.init( + .List = o.ObjList.ListDef.init( ctx.vm.gc.type_registry.str_type, false, ), @@ -77,8 +72,8 @@ pub fn utf8Codepoints(ctx: *NativeCtx) callconv(.c) c_int { }; var list = (ctx.vm.gc.allocateObject( - ObjList, - ObjList.init(ctx.vm.gc.allocator, list_def_type) catch { + o.ObjList, + o.ObjList.init(ctx.vm.gc.allocator, list_def_type) catch { ctx.vm.panic("Out of memory"); unreachable; }, @@ -108,8 +103,8 @@ pub fn utf8Codepoints(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn repeat(ctx: *NativeCtx) callconv(.c) c_int { - const str = ObjString.cast(ctx.vm.peek(1).obj()).?; +pub fn repeat(ctx: *o.NativeCtx) callconv(.c) c_int { + const str = o.ObjString.cast(ctx.vm.peek(1).obj()).?; const n = ctx.vm.peek(0).integer(); var new_string: std.ArrayList(u8) = std.ArrayList(u8).init(ctx.vm.gc.allocator); @@ -131,8 +126,8 @@ pub fn repeat(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn byte(ctx: *NativeCtx) callconv(.c) c_int { - const self = ObjString.cast(ctx.vm.peek(1).obj()).?; +pub fn byte(ctx: *o.NativeCtx) callconv(.c) c_int { + const self = o.ObjString.cast(ctx.vm.peek(1).obj()).?; const index = @min( @max( 0, @@ -142,7 +137,7 @@ pub fn byte(ctx: *NativeCtx) callconv(.c) c_int { ); ctx.vm.push( - Value.fromInteger( + v.Value.fromInteger( @intCast(self.string[@intCast(index)]), ), ); @@ -150,28 +145,28 @@ pub fn byte(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn indexOf(ctx: *NativeCtx) callconv(.c) c_int { - const self = ObjString.cast(ctx.vm.peek(1).obj()).?; - const needle = ObjString.cast(ctx.vm.peek(0).obj()).?; +pub fn indexOf(ctx: *o.NativeCtx) callconv(.c) c_int { + const self = o.ObjString.cast(ctx.vm.peek(1).obj()).?; + const needle = o.ObjString.cast(ctx.vm.peek(0).obj()).?; const index = std.mem.indexOf(u8, self.string, needle.string); ctx.vm.push( if (index) |uindex| - Value.fromInteger(@intCast(uindex)) + v.Value.fromInteger(@intCast(uindex)) else - Value.Null, + v.Value.Null, ); return 1; } -pub fn startsWith(ctx: *NativeCtx) callconv(.c) c_int { - const self = ObjString.cast(ctx.vm.peek(1).obj()).?; - const needle = ObjString.cast(ctx.vm.peek(0).obj()).?; +pub fn startsWith(ctx: *o.NativeCtx) callconv(.c) c_int { + const self = o.ObjString.cast(ctx.vm.peek(1).obj()).?; + const needle = o.ObjString.cast(ctx.vm.peek(0).obj()).?; ctx.vm.push( - Value.fromBoolean( + v.Value.fromBoolean( std.mem.startsWith(u8, self.string, needle.string), ), ); @@ -179,12 +174,12 @@ pub fn startsWith(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn endsWith(ctx: *NativeCtx) callconv(.c) c_int { - const self = ObjString.cast(ctx.vm.peek(1).obj()).?; - const needle = ObjString.cast(ctx.vm.peek(0).obj()).?; +pub fn endsWith(ctx: *o.NativeCtx) callconv(.c) c_int { + const self = o.ObjString.cast(ctx.vm.peek(1).obj()).?; + const needle = o.ObjString.cast(ctx.vm.peek(0).obj()).?; ctx.vm.push( - Value.fromBoolean( + v.Value.fromBoolean( std.mem.endsWith(u8, self.string, needle.string), ), ); @@ -192,10 +187,10 @@ pub fn endsWith(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn replace(ctx: *NativeCtx) callconv(.c) c_int { - const self = ObjString.cast(ctx.vm.peek(2).obj()).?; - const needle = ObjString.cast(ctx.vm.peek(1).obj()).?; - const replacement = ObjString.cast(ctx.vm.peek(0).obj()).?; +pub fn replace(ctx: *o.NativeCtx) callconv(.c) c_int { + const self = o.ObjString.cast(ctx.vm.peek(2).obj()).?; + const needle = o.ObjString.cast(ctx.vm.peek(1).obj()).?; + const replacement = o.ObjString.cast(ctx.vm.peek(0).obj()).?; const new_string = std.mem.replaceOwned( u8, @@ -218,8 +213,8 @@ pub fn replace(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn sub(ctx: *NativeCtx) callconv(.c) c_int { - const self = ObjString.cast(ctx.vm.peek(2).obj()).?; +pub fn sub(ctx: *o.NativeCtx) callconv(.c) c_int { + const self = o.ObjString.cast(ctx.vm.peek(2).obj()).?; const start = @max( 0, ctx.vm.peek(1).integer(), @@ -249,16 +244,16 @@ pub fn sub(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn split(ctx: *NativeCtx) callconv(.c) c_int { - const self = ObjString.cast(ctx.vm.peek(1).obj()).?; - const separator = ObjString.cast(ctx.vm.peek(0).obj()).?; +pub fn split(ctx: *o.NativeCtx) callconv(.c) c_int { + const self = o.ObjString.cast(ctx.vm.peek(1).obj()).?; + const separator = o.ObjString.cast(ctx.vm.peek(0).obj()).?; const list_def_type = ctx.vm.gc.type_registry.getTypeDef( .{ .def_type = .List, .optional = false, .resolved_type = .{ - .List = ObjList.ListDef.init( + .List = o.ObjList.ListDef.init( ctx.vm.gc.type_registry.str_type, false, ), @@ -270,8 +265,8 @@ pub fn split(ctx: *NativeCtx) callconv(.c) c_int { }; var list = ctx.vm.gc.allocateObject( - ObjList, - ObjList.init(ctx.vm.gc.allocator, list_def_type) catch { + o.ObjList, + o.ObjList.init(ctx.vm.gc.allocator, list_def_type) catch { ctx.vm.panic("Out of memory"); unreachable; }, @@ -313,8 +308,8 @@ pub fn split(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn encodeBase64(ctx: *NativeCtx) callconv(.c) c_int { - const str = ObjString.cast(ctx.vm.peek(0).obj()).?; +pub fn encodeBase64(ctx: *o.NativeCtx) callconv(.c) c_int { + const str = o.ObjString.cast(ctx.vm.peek(0).obj()).?; const encoded = ctx.vm.gc.allocator.alloc( u8, @@ -338,8 +333,8 @@ pub fn encodeBase64(ctx: *NativeCtx) callconv(.c) c_int { } // FIXME: signature should be fun decodeBase64(str self) > str !> DecodeError -pub fn decodeBase64(ctx: *NativeCtx) callconv(.c) c_int { - const str = ObjString.cast(ctx.vm.peek(0).obj()).?; +pub fn decodeBase64(ctx: *o.NativeCtx) callconv(.c) c_int { + const str = o.ObjString.cast(ctx.vm.peek(0).obj()).?; const size = std.base64.standard.Decoder.calcSizeForSlice(str.string) catch { ctx.vm.push((ctx.vm.gc.copyString("Could not decode string") catch { @@ -374,8 +369,8 @@ pub fn decodeBase64(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn upper(ctx: *NativeCtx) callconv(.c) c_int { - const str = ObjString.cast(ctx.vm.peek(0).obj()).?; +pub fn upper(ctx: *o.NativeCtx) callconv(.c) c_int { + const str = o.ObjString.cast(ctx.vm.peek(0).obj()).?; if (str.string.len == 0) { ctx.vm.push(str.toValue()); @@ -406,8 +401,8 @@ pub fn upper(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn lower(ctx: *NativeCtx) callconv(.c) c_int { - const str = ObjString.cast(ctx.vm.peek(0).obj()).?; +pub fn lower(ctx: *o.NativeCtx) callconv(.c) c_int { + const str = o.ObjString.cast(ctx.vm.peek(0).obj()).?; if (str.string.len == 0) { ctx.vm.push(str.toValue()); @@ -438,8 +433,8 @@ pub fn lower(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn hex(ctx: *NativeCtx) callconv(.c) c_int { - const str = ObjString.cast(ctx.vm.peek(0).obj()).?; +pub fn hex(ctx: *o.NativeCtx) callconv(.c) c_int { + const str = o.ObjString.cast(ctx.vm.peek(0).obj()).?; if (str.string.len == 0) { ctx.vm.push(str.toValue()); @@ -468,8 +463,8 @@ pub fn hex(ctx: *NativeCtx) callconv(.c) c_int { return 1; } -pub fn bin(ctx: *NativeCtx) callconv(.c) c_int { - const str = ObjString.cast(ctx.vm.peek(0).obj()).?; +pub fn bin(ctx: *o.NativeCtx) callconv(.c) c_int { + const str = o.ObjString.cast(ctx.vm.peek(0).obj()).?; if (str.string.len == 0) { ctx.vm.push(str.toValue()); diff --git a/src/buzz_api.zig b/src/buzz_api.zig index 192c95b6..75b6ea5d 100644 --- a/src/buzz_api.zig +++ b/src/buzz_api.zig @@ -1,14 +1,12 @@ const std = @import("std"); const builtin = @import("builtin"); const buzz_builtin = @import("builtin.zig"); -const _vm = @import("vm.zig"); -const VM = _vm.VM; -const TryCtx = _vm.TryCtx; -const _obj = @import("obj.zig"); -const _value = @import("value.zig"); -const Integer = _value.Integer; -const Double = _value.Double; -const Value = _value.Value; +const vmachine = @import("vm.zig"); +const VM = vmachine.VM; +const TryCtx = vmachine.TryCtx; +const ImportRegistry = vmachine.ImportRegistry; +const o = @import("obj.zig"); +const v = @import("value.zig"); const memory = @import("memory.zig"); const Parser = @import("Parser.zig"); const CodeGen = @import("Codegen.zig"); @@ -26,31 +24,6 @@ pub const os = if (is_wasm) else std.os; -const eql = Value.eql; -const Obj = _obj.Obj; -const ObjString = _obj.ObjString; -const ObjPattern = _obj.ObjPattern; -const ObjMap = _obj.ObjMap; -const ObjUpValue = _obj.ObjUpValue; -const ObjEnum = _obj.ObjEnum; -const ObjEnumInstance = _obj.ObjEnumInstance; -const ObjObject = _obj.ObjObject; -const ObjObjectInstance = _obj.ObjObjectInstance; -const ObjTypeDef = _obj.ObjTypeDef; -const ObjFunction = _obj.ObjFunction; -const ObjList = _obj.ObjList; -const ObjUserData = _obj.ObjUserData; -const ObjClosure = _obj.ObjClosure; -const ObjNative = _obj.ObjNative; -const ObjBoundMethod = _obj.ObjBoundMethod; -const ObjFiber = _obj.ObjFiber; -const ObjForeignContainer = _obj.ObjForeignContainer; -const ObjRange = _obj.ObjRange; -const NativeFn = _obj.NativeFn; -const NativeCtx = _obj.NativeCtx; -const TypeRegistry = memory.TypeRegistry; -const GarbageCollector = memory.GarbageCollector; - var gpa = std.heap.GeneralPurposeAllocator(.{ .safety = builtin.mode == .Debug, }){}; @@ -65,51 +38,51 @@ else if (!is_wasm) // Stack manipulation /// Push a Value to the stack -export fn bz_push(vm: *VM, value: Value) callconv(.c) void { +export fn bz_push(vm: *VM, value: v.Value) callconv(.c) void { vm.push(value); } /// Pop a Value from the stack and returns it -export fn bz_pop(vm: *VM) callconv(.c) Value { +export fn bz_pop(vm: *VM) callconv(.c) v.Value { return vm.pop(); } /// Peeks at the stack at [distance] from the stack top -export fn bz_peek(vm: *VM, dist: u32) callconv(.c) Value { +export fn bz_peek(vm: *VM, dist: u32) callconv(.c) v.Value { return vm.peek(dist); } /// Absolute access to the stack. -export fn bz_at(vm: *VM, at: u32) callconv(.c) Value { +export fn bz_at(vm: *VM, at: u32) callconv(.c) v.Value { if (at < vm.current_fiber.stack.len) { return vm.current_fiber.stack[at]; } - return Value.Null; + return v.Value.Null; } /// Converts a value to a string -export fn bz_valueToString(value: Value, len: *usize) callconv(.c) ?[*]const u8 { +export fn bz_valueToString(value: v.Value, len: *usize) callconv(.c) ?[*]const u8 { if (!value.isObj() or value.obj().obj_type != .String) { return null; } - const string = ObjString.cast(value.obj()).?.string; + const string = o.ObjString.cast(value.obj()).?.string; len.* = string.len; return if (string.len > 0) @as([*]const u8, @ptrCast(string)) else null; } -export fn bz_valueToCString(value: Value) callconv(.c) ?[*:0]const u8 { +export fn bz_valueToCString(value: v.Value) callconv(.c) ?[*:0]const u8 { if (!value.isObj() or value.obj().obj_type != .String) { return null; } - return @ptrCast(ObjString.cast(value.obj()).?.string.ptr); + return @ptrCast(o.ObjString.cast(value.obj()).?.string.ptr); } -fn valueDump(value: Value, vm: *VM, seen: *std.AutoHashMap(*_obj.Obj, void), depth: usize) void { +fn valueDump(value: v.Value, vm: *VM, seen: *std.AutoHashMap(*o.Obj, void), depth: usize) void { if (depth > 50) { io.print("...", .{}); return; @@ -142,25 +115,25 @@ fn valueDump(value: Value, vm: *VM, seen: *std.AutoHashMap(*_obj.Obj, void), dep }, .UpValue => { - const upvalue = ObjUpValue.cast(value.obj()).?; + const upvalue = o.ObjUpValue.cast(value.obj()).?; valueDump(if (upvalue.closed != null) upvalue.closed.? else upvalue.location.*, vm, seen, depth); }, .String => { - const string = ObjString.cast(value.obj()).?; + const string = o.ObjString.cast(value.obj()).?; io.print("\"{s}\"", .{string.string}); }, .Pattern => { - const pattern = ObjPattern.cast(value.obj()).?; + const pattern = o.ObjPattern.cast(value.obj()).?; io.print("$\"{s}\"", .{pattern.source}); }, .List => { - const list = ObjList.cast(value.obj()).?; + const list = o.ObjList.cast(value.obj()).?; io.print( "{s}[ ", @@ -179,13 +152,13 @@ fn valueDump(value: Value, vm: *VM, seen: *std.AutoHashMap(*_obj.Obj, void), dep }, .Range => { - const range = ObjRange.cast(value.obj()).?; + const range = o.ObjRange.cast(value.obj()).?; io.print("{}..{}", .{ range.low, range.high }); }, .Map => { - const map = ObjMap.cast(value.obj()).?; + const map = o.ObjMap.cast(value.obj()).?; io.print( "{s}{{ ", @@ -209,7 +182,7 @@ fn valueDump(value: Value, vm: *VM, seen: *std.AutoHashMap(*_obj.Obj, void), dep }, .Enum => { - const enumeration = ObjEnum.cast(value.obj()).?; + const enumeration = o.ObjEnum.cast(value.obj()).?; const enum_type_def = enumeration.type_def.resolved_type.?.Enum; io.print( @@ -228,7 +201,7 @@ fn valueDump(value: Value, vm: *VM, seen: *std.AutoHashMap(*_obj.Obj, void), dep }, .Object => { - const object = ObjObject.cast(value.obj()).?; + const object = o.ObjObject.cast(value.obj()).?; const object_def = object.type_def.resolved_type.?.Object; io.print("object", .{}); @@ -268,10 +241,10 @@ fn valueDump(value: Value, vm: *VM, seen: *std.AutoHashMap(*_obj.Obj, void), dep else if (field.has_default) object.defaults[field.index] else - null) |v| + null) |val| { io.print(" = ", .{}); - valueDump(v, vm, seen, depth + 1); + valueDump(val, vm, seen, depth + 1); } io.print(", ", .{}); @@ -291,7 +264,7 @@ fn valueDump(value: Value, vm: *VM, seen: *std.AutoHashMap(*_obj.Obj, void), dep }, .ObjectInstance => { - const object_instance = ObjObjectInstance.cast(value.obj()).?; + const object_instance = o.ObjObjectInstance.cast(value.obj()).?; const object_def = object_instance.type_def.resolved_type.?.ObjectInstance.of .resolved_type.?.Object; @@ -325,7 +298,7 @@ fn valueDump(value: Value, vm: *VM, seen: *std.AutoHashMap(*_obj.Obj, void), dep }, .ForeignContainer => { - const foreign = ObjForeignContainer.cast(value.obj()).?; + const foreign = o.ObjForeignContainer.cast(value.obj()).?; const foreign_def = foreign.type_def.resolved_type.?.ForeignContainer; io.print( @@ -356,19 +329,19 @@ fn valueDump(value: Value, vm: *VM, seen: *std.AutoHashMap(*_obj.Obj, void), dep } /// Dump value -pub export fn bz_valueDump(value: Value, vm: *VM) callconv(.c) void { - var seen = std.AutoHashMap(*_obj.Obj, void).init(vm.gc.allocator); +pub export fn bz_valueDump(value: v.Value, vm: *VM) callconv(.c) void { + var seen = std.AutoHashMap(*o.Obj, void).init(vm.gc.allocator); defer seen.deinit(); valueDump(value, vm, &seen, 0); } -export fn bz_valueToForeignContainerPtr(value: Value) callconv(.c) [*]u8 { - return ObjForeignContainer.cast(value.obj()).?.data.ptr; +export fn bz_valueToForeignContainerPtr(value: v.Value) callconv(.c) [*]u8 { + return o.ObjForeignContainer.cast(value.obj()).?.data.ptr; } -/// Converts a c string to a *ObjString -export fn bz_stringToValue(vm: *VM, string: ?[*]const u8, len: usize) callconv(.c) Value { +/// Converts a c string to a *o.ObjString +export fn bz_stringToValue(vm: *VM, string: ?[*]const u8, len: usize) callconv(.c) v.Value { return ((if (string != null and len > 0) vm.gc.copyString(string.?[0..len]) else @@ -378,7 +351,7 @@ export fn bz_stringToValue(vm: *VM, string: ?[*]const u8, len: usize) callconv(. }).toValue(); } -export fn bz_stringToValueZ(vm: *VM, string: [*:0]const u8) callconv(.c) Value { +export fn bz_stringToValueZ(vm: *VM, string: [*:0]const u8) callconv(.c) v.Value { // Keeping the sentinel return (vm.gc.copyString(string[0..(std.mem.len(string) + 1)]) catch { vm.panic("Out of memory"); @@ -386,20 +359,20 @@ export fn bz_stringToValueZ(vm: *VM, string: [*:0]const u8) callconv(.c) Value { }).toValue(); } -export fn bz_stringConcat(obj_string: Value, other: Value, vm: *VM) callconv(.c) Value { - return (ObjString.cast(obj_string.obj()).?.concat( +export fn bz_stringConcat(obj_string: v.Value, other: v.Value, vm: *VM) callconv(.c) v.Value { + return (o.ObjString.cast(obj_string.obj()).?.concat( vm, - ObjString.cast(other.obj()).?, + o.ObjString.cast(other.obj()).?, ) catch @panic("Could not concat strings")).toValue(); } -export fn bz_stringSubscript(obj_string: Value, index_value: Value, checked: bool, vm: *VM) callconv(.c) Value { - const str = ObjString.cast(obj_string.obj()).?; +export fn bz_stringSubscript(obj_string: v.Value, index_value: v.Value, checked: bool, vm: *VM) callconv(.c) v.Value { + const str = o.ObjString.cast(obj_string.obj()).?; const index = index_value.integer(); if (index < 0) { if (checked) { - return Value.Null; + return v.Value.Null; } bz_throw( @@ -407,7 +380,7 @@ export fn bz_stringSubscript(obj_string: Value, index_value: Value, checked: boo (vm.gc.copyString("Out of bound string access.") catch unreachable).toValue(), ); - return Value.Error; + return v.Value.Error; } const str_index: usize = @intCast(index); @@ -416,7 +389,7 @@ export fn bz_stringSubscript(obj_string: Value, index_value: Value, checked: boo return (vm.gc.copyString(&([_]u8{str.string[str_index]})) catch unreachable).toValue(); } else { if (checked) { - return Value.Null; + return v.Value.Null; } bz_throw( @@ -424,11 +397,11 @@ export fn bz_stringSubscript(obj_string: Value, index_value: Value, checked: boo (vm.gc.copyString("Out of bound str access.") catch unreachable).toValue(), ); - return Value.Error; + return v.Value.Error; } } -export fn bz_valueCastToString(value: Value, vm: *VM) callconv(.c) Value { +export fn bz_valueCastToString(value: v.Value, vm: *VM) callconv(.c) v.Value { const str = value.toStringAlloc(vm.gc.allocator) catch @panic("Out of memory"); defer vm.gc.allocator.free(str); @@ -441,22 +414,22 @@ export fn bz_valueCastToString(value: Value, vm: *VM) callconv(.c) Value { // Type helpers /// Returns the [str] type -export fn bz_stringType(vm: *VM) callconv(.c) Value { +export fn bz_stringType(vm: *VM) callconv(.c) v.Value { return vm.gc.type_registry.str_type.toValue(); } -export fn bz_intType(vm: *VM) callconv(.c) Value { +export fn bz_intType(vm: *VM) callconv(.c) v.Value { return vm.gc.type_registry.int_type.toValue(); } -export fn bz_listType(vm: *VM, item_type: Value, mutable: bool) callconv(.c) Value { +export fn bz_listType(vm: *VM, item_type: v.Value, mutable: bool) callconv(.c) v.Value { return (vm.gc.type_registry.getTypeDef( .{ .def_type = .List, .optional = false, .resolved_type = .{ - .List = ObjList.ListDef.init( - ObjTypeDef.cast(item_type.obj()).?, + .List = o.ObjList.ListDef.init( + o.ObjTypeDef.cast(item_type.obj()).?, mutable, ), }, @@ -467,15 +440,15 @@ export fn bz_listType(vm: *VM, item_type: Value, mutable: bool) callconv(.c) Val }).toValue(); } -export fn bz_mapType(vm: *VM, key_type: Value, value_type: Value, mutable: bool) callconv(.c) Value { +export fn bz_mapType(vm: *VM, key_type: v.Value, value_type: v.Value, mutable: bool) callconv(.c) v.Value { return (vm.gc.type_registry.getTypeDef( .{ .def_type = .Map, .optional = false, .resolved_type = .{ - .Map = ObjMap.MapDef.init( - ObjTypeDef.cast(key_type.obj()).?, - ObjTypeDef.cast(value_type.obj()).?, + .Map = o.ObjMap.MapDef.init( + o.ObjTypeDef.cast(key_type.obj()).?, + o.ObjTypeDef.cast(value_type.obj()).?, mutable, ), }, @@ -486,15 +459,15 @@ export fn bz_mapType(vm: *VM, key_type: Value, value_type: Value, mutable: bool) }).toValue(); } -export fn bz_containerTypeSize(type_def: Value) callconv(.c) usize { - return ObjTypeDef.cast(type_def.obj()).? +export fn bz_containerTypeSize(type_def: v.Value) callconv(.c) usize { + return o.ObjTypeDef.cast(type_def.obj()).? .resolved_type.? .ForeignContainer .zig_type.size(); } -export fn bz_containerTypeAlign(type_def: Value) callconv(.c) usize { - return ObjTypeDef.cast(type_def.obj()).? +export fn bz_containerTypeAlign(type_def: v.Value) callconv(.c) usize { + return o.ObjTypeDef.cast(type_def.obj()).? .resolved_type.? .ForeignContainer .zig_type.alignment(); @@ -508,36 +481,36 @@ export fn bz_collect(self: *VM) callconv(.c) void { self.gc.collectGarbage() catch @panic("Could not collect"); } -export fn bz_newRange(vm: *VM, low: Integer, high: Integer) callconv(.c) Value { - return Value.fromObj((vm.gc.allocateObject( - ObjRange, - ObjRange{ - .low = low, - .high = high, +export fn bz_newRange(vm: *VM, low: i64, high: i64) callconv(.c) v.Value { + return v.Value.fromObj((vm.gc.allocateObject( + o.ObjRange, + o.ObjRange{ + .low = @truncate(low), + .high = @truncate(high), }, ) catch @panic("Could not create range")).toObj()); } -export fn bz_newList(vm: *VM, list_type: Value) callconv(.c) Value { +export fn bz_newList(vm: *VM, list_type: v.Value) callconv(.c) v.Value { return (vm.gc.allocateObject( - ObjList, - ObjList.init( + o.ObjList, + o.ObjList.init( vm.gc.allocator, - ObjTypeDef.cast(list_type.obj()).?, + o.ObjTypeDef.cast(list_type.obj()).?, ) catch @panic("Out of memory"), ) catch @panic("Could not create list")).toValue(); } -export fn bz_listAppend(list: Value, value: Value, vm: *VM) callconv(.c) void { - ObjList.cast(list.obj()).?.rawAppend(vm.gc, value) catch @panic("Could not add element to list"); +export fn bz_listAppend(list: v.Value, value: v.Value, vm: *VM) callconv(.c) void { + o.ObjList.cast(list.obj()).?.rawAppend(vm.gc, value) catch @panic("Could not add element to list"); } -export fn bz_listGet(self: Value, index: i32, checked: bool) callconv(.c) Value { - const list = ObjList.cast(self.obj()).?; +export fn bz_listGet(self: v.Value, index: i64, checked: bool) callconv(.c) v.Value { + const list = o.ObjList.cast(self.obj()).?; if (index < 0 or index >= list.items.items.len) { if (checked) { - return Value.Null; + return v.Value.Null; } else { @panic("Out of bound list access."); } @@ -546,29 +519,29 @@ export fn bz_listGet(self: Value, index: i32, checked: bool) callconv(.c) Value return list.items.items[@intCast(index)]; } -export fn bz_listSet(self: Value, index: usize, value: Value, vm: *VM) callconv(.c) void { - ObjList.cast(self.obj()).?.set( +export fn bz_listSet(self: v.Value, index: usize, value: v.Value, vm: *VM) callconv(.c) void { + o.ObjList.cast(self.obj()).?.set( vm.gc, index, value, ) catch @panic("Could not set element in list"); } -export fn bz_listLen(self: Value) callconv(.c) usize { - return ObjList.cast(self.obj()).?.items.items.len; +export fn bz_listLen(self: v.Value) callconv(.c) usize { + return o.ObjList.cast(self.obj()).?.items.items.len; } -export fn bz_listConcat(list: Value, other_list: Value, vm: *VM) callconv(.c) Value { - const left: *ObjList = ObjList.cast(list.obj()).?; - const right: *ObjList = ObjList.cast(other_list.obj()).?; +export fn bz_listConcat(list: v.Value, other_list: v.Value, vm: *VM) callconv(.c) v.Value { + const left: *o.ObjList = o.ObjList.cast(list.obj()).?; + const right: *o.ObjList = o.ObjList.cast(other_list.obj()).?; - var new_list = std.ArrayListUnmanaged(Value){}; + var new_list = std.ArrayListUnmanaged(v.Value){}; new_list.appendSlice(vm.gc.allocator, left.items.items) catch @panic("Could not concatenate lists"); new_list.appendSlice(vm.gc.allocator, right.items.items) catch @panic("Could not concatenate lists"); return (vm.gc.allocateObject( - ObjList, - ObjList{ + o.ObjList, + o.ObjList{ .type_def = left.type_def, .methods = left.methods, .items = new_list, @@ -576,9 +549,9 @@ export fn bz_listConcat(list: Value, other_list: Value, vm: *VM) callconv(.c) Va ) catch @panic("Could not concatenate lists")).toValue(); } -export fn bz_mapConcat(map: Value, other_map: Value, vm: *VM) callconv(.c) Value { - const left = ObjMap.cast(map.obj()).?; - const right = ObjMap.cast(other_map.obj()).?; +export fn bz_mapConcat(map: v.Value, other_map: v.Value, vm: *VM) callconv(.c) v.Value { + const left = o.ObjMap.cast(map.obj()).?; + const right = o.ObjMap.cast(other_map.obj()).?; var new_map = left.map.clone(vm.gc.allocator) catch @panic("Could not concatenate maps"); var it = right.map.iterator(); @@ -590,35 +563,35 @@ export fn bz_mapConcat(map: Value, other_map: Value, vm: *VM) callconv(.c) Value ) catch @panic("Could not concatenate maps"); } - return (vm.gc.allocateObject(ObjMap, ObjMap{ + return (vm.gc.allocateObject(o.ObjMap, o.ObjMap{ .type_def = left.type_def, .methods = left.methods, .map = new_map, }) catch @panic("Could not concatenate maps")).toValue(); } -export fn bz_newUserData(vm: *VM, userdata: u64) callconv(.c) Value { +export fn bz_newUserData(vm: *VM, userdata: u64) callconv(.c) v.Value { return (vm.gc.allocateObject( - ObjUserData, - ObjUserData{ .userdata = userdata }, + o.ObjUserData, + o.ObjUserData{ .userdata = userdata }, ) catch { vm.panic("Out of memory"); unreachable; }).toValue(); } -export fn bz_getUserDataPtr(userdata: Value) callconv(.c) u64 { - return ObjUserData.cast(userdata.obj()).?.userdata; +export fn bz_getUserDataPtr(userdata: v.Value) callconv(.c) u64 { + return o.ObjUserData.cast(userdata.obj()).?.userdata; } export fn bz_newVM() *VM { const vm = allocator.create(VM) catch @panic("Out of memory"); - var gc = allocator.create(GarbageCollector) catch @panic("Out of memory"); + var gc = allocator.create(memory.GarbageCollector) catch @panic("Out of memory"); // FIXME: should share strings between gc - gc.* = GarbageCollector.init(allocator) catch @panic("Out of memory"); - gc.type_registry = TypeRegistry.init(gc) catch @panic("Out of memory"); - const import_registry = allocator.create(_vm.ImportRegistry) catch @panic("Out of memory"); - import_registry.* = _vm.ImportRegistry.init(allocator); + gc.* = memory.GarbageCollector.init(allocator) catch @panic("Out of memory"); + gc.type_registry = memory.TypeRegistry.init(gc) catch @panic("Out of memory"); + const import_registry = allocator.create(ImportRegistry) catch @panic("Out of memory"); + import_registry.* = ImportRegistry.init(allocator); // FIXME: give reference to JIT? vm.* = VM.init( @@ -652,7 +625,7 @@ export fn bz_run( } var imports = std.StringHashMapUnmanaged(Parser.ScriptImport){}; - var strings = std.StringHashMap(*ObjString).init(self.gc.allocator); + var strings = std.StringHashMap(*o.ObjString).init(self.gc.allocator); var parser = Parser.init( self.gc, &imports, @@ -686,11 +659,11 @@ export fn bz_run( return false; } -fn calleeIsCompiled(value: Value) bool { - const obj: *Obj = value.obj(); +fn calleeIsCompiled(value: v.Value) bool { + const obj: *o.Obj = value.obj(); return switch (obj.obj_type) { .Bound => bound: { - const bound = ObjBoundMethod.cast(obj).?; + const bound = o.ObjBoundMethod.cast(obj).?; if (bound.native != null) { break :bound true; @@ -702,7 +675,7 @@ fn calleeIsCompiled(value: Value) bool { break :bound false; }, - .Closure => ObjClosure.cast(obj).?.function.native != null, + .Closure => o.ObjClosure.cast(obj).?.function.native != null, .Native => true, else => false, }; @@ -710,11 +683,11 @@ fn calleeIsCompiled(value: Value) bool { pub export fn bz_invoke( self: *VM, - instance: Value, + instance: v.Value, method_idx: usize, - arguments: ?[*]const *const Value, + arguments: ?[*]const *const v.Value, len: u8, - catch_value: ?*Value, + catch_value: ?*v.Value, ) callconv(.c) void { self.push(instance); var i: usize = 0; @@ -730,7 +703,7 @@ pub export fn bz_invoke( false, method_idx, len, - if (catch_value) |v| v.* else null, + if (catch_value) |val| val.* else null, false, ) catch unreachable; @@ -744,10 +717,10 @@ pub export fn bz_invoke( pub export fn bz_call( self: *VM, - closure_value: Value, - arguments: ?[*]const *const Value, + closure_value: v.Value, + arguments: ?[*]const *const v.Value, len: u8, - catch_value: ?*Value, + catch_value: ?*v.Value, ) callconv(.c) void { std.debug.assert(closure_value.obj().obj_type == .Closure); @@ -761,12 +734,12 @@ pub export fn bz_call( self.callValue( closure_value, len, - if (catch_value) |v| v.* else null, + if (catch_value) |val| val.* else null, ) catch unreachable; // If not compiled, run it with the VM loop if (closure_value.obj().access( - ObjClosure, + o.ObjClosure, .Closure, self.gc, ).?.function.native == null) { @@ -774,12 +747,12 @@ pub export fn bz_call( } } -export fn bz_newQualifiedObjectInstance(self: *VM, qualified_name: [*]const u8, len: usize, mutable: bool) callconv(.c) Value { - const object = ObjObject.cast(bz_getQualified(self, qualified_name, len).obj()).?; +export fn bz_newQualifiedObjectInstance(self: *VM, qualified_name: [*]const u8, len: usize, mutable: bool) callconv(.c) v.Value { + const object = o.ObjObject.cast(bz_getQualified(self, qualified_name, len).obj()).?; - const instance: *ObjObjectInstance = self.gc.allocateObject( - ObjObjectInstance, - ObjObjectInstance.init( + const instance: *o.ObjObjectInstance = self.gc.allocateObject( + o.ObjObjectInstance, + o.ObjObjectInstance.init( self, object, object.type_def.toInstance( @@ -815,7 +788,7 @@ fn instanciateError( len: usize, message: ?[*]const u8, mlen: usize, -) Value { +) v.Value { const instance = bz_newQualifiedObjectInstance( vm, qualified_name, @@ -824,7 +797,7 @@ fn instanciateError( ); if (message) |msg| { - const obj_instance = ObjObjectInstance.cast(instance.obj()).?; + const obj_instance = o.ObjObjectInstance.cast(instance.obj()).?; const object_def = obj_instance.type_def.resolved_type.?.ObjectInstance.of .resolved_type.?.Object .fields; @@ -871,19 +844,19 @@ export fn bz_pushErrorEnum(self: *VM, qualified_name: [*]const u8, name_len: usi ); } -export fn bz_getQualified(self: *VM, qualified_name: [*]const u8, len: usize) callconv(.c) Value { +export fn bz_getQualified(self: *VM, qualified_name: [*]const u8, len: usize) callconv(.c) v.Value { for (self.globals.items) |global| { if (global.isObj()) { switch (global.obj().obj_type) { .Enum => { - const obj_enum = ObjEnum.cast(global.obj()).?; + const obj_enum = o.ObjEnum.cast(global.obj()).?; if (std.mem.eql(u8, qualified_name[0..len], obj_enum.type_def.resolved_type.?.Enum.qualified_name.string)) { return global; } }, .Object => { - const obj_enum = ObjObject.cast(global.obj()).?; + const obj_enum = o.ObjObject.cast(global.obj()).?; if (std.mem.eql(u8, qualified_name[0..len], obj_enum.type_def.resolved_type.?.Object.qualified_name.string)) { return global; @@ -897,13 +870,13 @@ export fn bz_getQualified(self: *VM, qualified_name: [*]const u8, len: usize) ca std.debug.panic("bz_getQualified no name: {s}", .{qualified_name[0..len]}); } -export fn bz_newObjectInstance(vm: *VM, object_value: Value, typedef_value: Value) callconv(.c) Value { - const object = if (object_value.isObj()) ObjObject.cast(object_value.obj()).? else null; - const typedef = ObjTypeDef.cast(typedef_value.obj()).?; +export fn bz_newObjectInstance(vm: *VM, object_value: v.Value, typedef_value: v.Value) callconv(.c) v.Value { + const object = if (object_value.isObj()) o.ObjObject.cast(object_value.obj()).? else null; + const typedef = o.ObjTypeDef.cast(typedef_value.obj()).?; const instance = vm.gc.allocateObject( - ObjObjectInstance, - ObjObjectInstance.init( + o.ObjObjectInstance, + o.ObjObjectInstance.init( vm, object, typedef, @@ -927,33 +900,33 @@ export fn bz_newObjectInstance(vm: *VM, object_value: Value, typedef_value: Valu return instance.toValue(); } -export fn bz_getObjectField(object_value: Value, field_idx: usize) callconv(.c) Value { - return ObjObject.cast(object_value.obj()).?.fields[field_idx]; +export fn bz_getObjectField(object_value: v.Value, field_idx: usize) callconv(.c) v.Value { + return o.ObjObject.cast(object_value.obj()).?.fields[field_idx]; } -export fn bz_setObjectField(object_value: Value, field_idx: usize, value: Value, vm: *VM) callconv(.c) void { - ObjObject.cast(object_value.obj()).?.setField( +export fn bz_setObjectField(object_value: v.Value, field_idx: usize, value: v.Value, vm: *VM) callconv(.c) void { + o.ObjObject.cast(object_value.obj()).?.setField( vm.gc, field_idx, value, ) catch @panic("Could not set static field"); } -export fn bz_setObjectInstanceProperty(instance_value: Value, field_idx: usize, value: Value, vm: *VM) callconv(.c) void { - ObjObjectInstance.cast(instance_value.obj()).?.setField( +export fn bz_setObjectInstanceProperty(instance_value: v.Value, field_idx: usize, value: v.Value, vm: *VM) callconv(.c) void { + o.ObjObjectInstance.cast(instance_value.obj()).?.setField( vm.gc, field_idx, value, ) catch @panic("Could not set instance field"); } -export fn bz_getObjectInstanceProperty(instance_value: Value, property_idx: usize) callconv(.c) Value { - return ObjObjectInstance.cast(instance_value.obj()).? +export fn bz_getObjectInstanceProperty(instance_value: v.Value, property_idx: usize) callconv(.c) v.Value { + return o.ObjObjectInstance.cast(instance_value.obj()).? .fields[property_idx]; } -export fn bz_getObjectInstanceMethod(instance_value: Value, method_idx: usize, bind: bool, vm: *VM) callconv(.c) Value { - const method = ObjObjectInstance.cast(instance_value.obj()).? +export fn bz_getObjectInstanceMethod(instance_value: v.Value, method_idx: usize, bind: bool, vm: *VM) callconv(.c) v.Value { + const method = o.ObjObjectInstance.cast(instance_value.obj()).? .object.? .fields[method_idx]; @@ -962,21 +935,21 @@ export fn bz_getObjectInstanceMethod(instance_value: Value, method_idx: usize, b vm, method, method, - Value.Null, + v.Value.Null, ) else method; } -export fn bz_getProtocolMethod(instance_value: Value, method_name: Value, vm: *VM) callconv(.c) Value { +export fn bz_getProtocolMethod(instance_value: v.Value, method_name: v.Value, vm: *VM) callconv(.c) v.Value { const instance = instance_value.obj().access( - ObjObjectInstance, + o.ObjObjectInstance, .ObjectInstance, vm.gc, ).?; const name = method_name.obj() - .access(ObjString, .String, vm.gc).? + .access(o.ObjString, .String, vm.gc).? .string; const method_idx = instance.type_def.resolved_type.?.ObjectInstance.of @@ -987,24 +960,24 @@ export fn bz_getProtocolMethod(instance_value: Value, method_name: Value, vm: *V vm, instance_value, instance.object.?.fields[method_idx], - Value.Null, + v.Value.Null, ); } -export fn bz_bindMethod(vm: *VM, receiver: Value, method_value: Value, native_value: Value) callconv(.c) Value { +export fn bz_bindMethod(vm: *VM, receiver: v.Value, method_value: v.Value, native_value: v.Value) callconv(.c) v.Value { return (vm.gc.allocateObject( - ObjBoundMethod, + o.ObjBoundMethod, .{ .receiver = receiver, - .closure = if (method_value.isObj()) ObjClosure.cast(method_value.obj()).? else null, - .native = if (native_value.isObj()) ObjNative.cast(native_value.obj()).? else null, + .closure = if (method_value.isObj()) o.ObjClosure.cast(method_value.obj()).? else null, + .native = if (native_value.isObj()) o.ObjNative.cast(native_value.obj()).? else null, }, ) catch @panic("Could not bind method")).toValue(); } -export fn bz_getEnumCase(enum_value: Value, case_name_value: Value, vm: *VM) callconv(.c) Value { - const self = ObjEnum.cast(enum_value.obj()).?; - const case = ObjString.cast(case_name_value.obj()).?.string; +export fn bz_getEnumCase(enum_value: v.Value, case_name_value: v.Value, vm: *VM) callconv(.c) v.Value { + const self = o.ObjEnum.cast(enum_value.obj()).?; + const case = o.ObjString.cast(case_name_value.obj()).?.string; var case_index: usize = 0; for (self.type_def.resolved_type.?.Enum.cases, 0..) |enum_case, index| { @@ -1015,74 +988,74 @@ export fn bz_getEnumCase(enum_value: Value, case_name_value: Value, vm: *VM) cal } return (vm.gc.allocateObject( - ObjEnumInstance, - ObjEnumInstance{ + o.ObjEnumInstance, + o.ObjEnumInstance{ .enum_ref = self, .case = @intCast(case_index), }, ) catch @panic("Could not create enum case")).toValue(); } -export fn bz_getEnumInstanceValue(enum_instance_value: Value) callconv(.c) Value { - const instance = ObjEnumInstance.cast(enum_instance_value.obj()).?; +export fn bz_getEnumInstanceValue(enum_instance_value: v.Value) callconv(.c) v.Value { + const instance = o.ObjEnumInstance.cast(enum_instance_value.obj()).?; return instance.enum_ref.cases[instance.case]; } -export fn bz_getEnumCaseFromValue(enum_value: Value, case_value: Value, vm: *VM) callconv(.c) Value { - const enum_ = ObjEnum.cast(enum_value.obj()).?; +export fn bz_getEnumCaseFromValue(enum_value: v.Value, case_value: v.Value, vm: *VM) callconv(.c) v.Value { + const enum_ = o.ObjEnum.cast(enum_value.obj()).?; for (enum_.cases, 0..) |case, index| { - if (eql(case, case_value)) { - var enum_case: *ObjEnumInstance = vm.gc.allocateObject(ObjEnumInstance, ObjEnumInstance{ + if (v.Value.eql(case, case_value)) { + var enum_case: *o.ObjEnumInstance = vm.gc.allocateObject(o.ObjEnumInstance, o.ObjEnumInstance{ .enum_ref = enum_, .case = @intCast(index), }) catch @panic("Could not create enum instance"); - return Value.fromObj(enum_case.toObj()); + return v.Value.fromObj(enum_case.toObj()); } } - return Value.Null; + return v.Value.Null; } -export fn bz_valueEqual(self: Value, other: Value) callconv(.c) Value { - return Value.fromBoolean(self.eql(other)); +export fn bz_valueEqual(self: v.Value, other: v.Value) callconv(.c) v.Value { + return v.Value.fromBoolean(self.eql(other)); } -export fn bz_valueTypeOf(self: Value, vm: *VM) callconv(.c) Value { +export fn bz_valueTypeOf(self: v.Value, vm: *VM) callconv(.c) v.Value { return (self.typeOf(vm.gc) catch { vm.panic("Out of memory"); unreachable; }).toValue(); } -export fn bz_newMap(vm: *VM, map_type: Value) callconv(.c) Value { - var map: *ObjMap = vm.gc.allocateObject( - ObjMap, - ObjMap.init( +export fn bz_newMap(vm: *VM, map_type: v.Value) callconv(.c) v.Value { + var map: *o.ObjMap = vm.gc.allocateObject( + o.ObjMap, + o.ObjMap.init( vm.gc.allocator, - ObjTypeDef.cast(map_type.obj()).?, + o.ObjTypeDef.cast(map_type.obj()).?, ) catch @panic("Could not create map"), ) catch @panic("Could not create map"); - return Value.fromObj(map.toObj()); + return v.Value.fromObj(map.toObj()); } -export fn bz_mapSet(map: Value, key: Value, value: Value, vm: *VM) callconv(.c) void { - ObjMap.cast(map.obj()).?.set( +export fn bz_mapSet(map: v.Value, key: v.Value, value: v.Value, vm: *VM) callconv(.c) void { + o.ObjMap.cast(map.obj()).?.set( vm.gc, key, value, ) catch @panic("Could not set map element"); } -export fn bz_mapGet(map: Value, key: Value) callconv(.c) Value { - return ObjMap.cast(map.obj()).?.map.get(key) orelse Value.Null; +export fn bz_mapGet(map: v.Value, key: v.Value) callconv(.c) v.Value { + return o.ObjMap.cast(map.obj()).?.map.get(key) orelse v.Value.Null; } -export fn bz_valueIs(self: Value, type_def: Value) callconv(.c) Value { - return Value.fromBoolean(type_def.is(self)); +export fn bz_valueIs(self: v.Value, type_def: v.Value) callconv(.c) v.Value { + return v.Value.fromBoolean(type_def.is(self)); } export fn bz_setTryCtx(self: *VM) callconv(.c) *TryCtx { @@ -1137,44 +1110,44 @@ export fn bz_rethrow(vm: *VM) callconv(.c) void { } } -export fn bz_throw(vm: *VM, value: Value) callconv(.c) void { +export fn bz_throw(vm: *VM, value: v.Value) callconv(.c) void { vm.push(value); bz_rethrow(vm); } -export fn bz_closeUpValues(vm: *VM, last: *Value) callconv(.c) void { +export fn bz_closeUpValues(vm: *VM, last: *v.Value) callconv(.c) void { vm.closeUpValues(last); _ = vm.pop(); } -export fn bz_getUpValue(ctx: *NativeCtx, slot: usize) callconv(.c) Value { +export fn bz_getUpValue(ctx: *o.NativeCtx, slot: usize) callconv(.c) v.Value { return ctx.upvalues[slot].location.*; } -export fn bz_setUpValue(ctx: *NativeCtx, slot: usize, value: Value) callconv(.c) void { +export fn bz_setUpValue(ctx: *o.NativeCtx, slot: usize, value: v.Value) callconv(.c) void { ctx.upvalues[slot].location.* = value; } -export fn bz_context(ctx: *NativeCtx, closure_value: Value, new_ctx: *NativeCtx, arg_count: usize) callconv(.c) *anyopaque { +export fn bz_context(ctx: *o.NativeCtx, closure_value: v.Value, new_ctx: *o.NativeCtx, arg_count: usize) callconv(.c) *anyopaque { if (is_wasm) { unreachable; } const bound = if (closure_value.obj().obj_type == .Bound) - ObjBoundMethod.cast(closure_value.obj()).? + o.ObjBoundMethod.cast(closure_value.obj()).? else null; const closure = if (bound) |bd| bd.closure else - ObjClosure.cast(closure_value.obj()); + o.ObjClosure.cast(closure_value.obj()); const native = if (closure == null and bound != null) bound.?.native else if (closure == null and bound == null) - ObjNative.cast(closure_value.obj()).? + o.ObjNative.cast(closure_value.obj()).? else null; @@ -1200,7 +1173,7 @@ export fn bz_context(ctx: *NativeCtx, closure_value: Value, new_ctx: *NativeCtx, (ctx.vm.current_fiber.stack_top - arg_count - 1)[0] = bound.?.receiver; } - new_ctx.* = NativeCtx{ + new_ctx.* = o.NativeCtx{ .vm = ctx.vm, .globals = if (closure) |cls| cls.globals.items.ptr else ctx.globals, .upvalues = if (closure) |cls| cls.upvalues.ptr else ctx.upvalues, @@ -1222,11 +1195,11 @@ export fn bz_context(ctx: *NativeCtx, closure_value: Value, new_ctx: *NativeCtx, } export fn bz_closure( - ctx: *NativeCtx, + ctx: *o.NativeCtx, function_node: Ast.Node.Index, native: *anyopaque, native_raw: *anyopaque, -) callconv(.c) Value { +) callconv(.c) v.Value { if (is_wasm) { unreachable; } @@ -1236,9 +1209,9 @@ export fn bz_closure( obj_function.native = native; obj_function.native_raw = native_raw; - const closure: *ObjClosure = ctx.vm.gc.allocateObject( - ObjClosure, - ObjClosure.init( + const closure: *o.ObjClosure = ctx.vm.gc.allocateObject( + o.ObjClosure, + o.ObjClosure.init( ctx.vm.gc.allocator, ctx.vm, obj_function, @@ -1266,180 +1239,180 @@ export fn bz_closure( return ctx.vm.pop(); } -export fn bz_dumpStack(ctx: *NativeCtx, off: usize) callconv(.c) void { +export fn bz_dumpStack(ctx: *o.NativeCtx, off: usize) callconv(.c) void { io.print("base is {}, top is {}\n", .{ @intFromPtr(ctx.base), @intFromPtr(ctx.vm.current_fiber.stack_top) }); io.print("#{}:\n", .{off}); dumpStack(ctx.vm); } -export fn bz_getStringProperty(vm: *VM, string_value: Value, property_idx: usize, bind: bool) callconv(.c) Value { - const method = ObjString.member(vm, property_idx) catch @panic("Out of memory").?; +export fn bz_getStringProperty(vm: *VM, string_value: v.Value, property_idx: usize, bind: bool) callconv(.c) v.Value { + const method = o.ObjString.member(vm, property_idx) catch @panic("Out of memory").?; return if (bind) bz_bindMethod( vm, string_value, - Value.Null, + v.Value.Null, method, ) else method; } -export fn bz_getPatternProperty(vm: *VM, pattern_value: Value, property_idx: usize, bind: bool) callconv(.c) Value { - const method = ObjPattern.member(vm, property_idx) catch @panic("Could not get pattern method"); +export fn bz_getPatternProperty(vm: *VM, pattern_value: v.Value, property_idx: usize, bind: bool) callconv(.c) v.Value { + const method = o.ObjPattern.member(vm, property_idx) catch @panic("Could not get pattern method"); return if (bind) bz_bindMethod( vm, pattern_value, - Value.Null, + v.Value.Null, method, ) else method; } -export fn bz_getFiberProperty(vm: *VM, fiber_value: Value, property_idx: usize, bind: bool) callconv(.c) Value { - const method = ObjFiber.member(vm, property_idx) catch @panic("Could not get fiber method"); +export fn bz_getFiberProperty(vm: *VM, fiber_value: v.Value, property_idx: usize, bind: bool) callconv(.c) v.Value { + const method = o.ObjFiber.member(vm, property_idx) catch @panic("Could not get fiber method"); return if (bind) bz_bindMethod( vm, fiber_value, - Value.Null, + v.Value.Null, method, ) else method; } -export fn bz_getListProperty(vm: *VM, list_value: Value, property_idx: usize, bind: bool) callconv(.c) Value { - const method = ObjList.cast(list_value.obj()).? +export fn bz_getListProperty(vm: *VM, list_value: v.Value, property_idx: usize, bind: bool) callconv(.c) v.Value { + const method = o.ObjList.cast(list_value.obj()).? .member(vm, property_idx) catch @panic("Could not get list method"); return if (bind) bz_bindMethod( vm, list_value, - Value.Null, + v.Value.Null, method, ) else method; } -export fn bz_getRangeProperty(vm: *VM, range_value: Value, property_idx: usize, bind: bool) callconv(.c) Value { - const method = ObjRange.member(vm, property_idx) catch @panic("Out of memory"); +export fn bz_getRangeProperty(vm: *VM, range_value: v.Value, property_idx: usize, bind: bool) callconv(.c) v.Value { + const method = o.ObjRange.member(vm, property_idx) catch @panic("Out of memory"); return if (bind) bz_bindMethod( vm, range_value, - Value.Null, + v.Value.Null, method, ) else method; } -export fn bz_getMapProperty(vm: *VM, map_value: Value, property_idx: usize, bind: bool) callconv(.c) Value { - const method = ObjMap.cast(map_value.obj()).? +export fn bz_getMapProperty(vm: *VM, map_value: v.Value, property_idx: usize, bind: bool) callconv(.c) v.Value { + const method = o.ObjMap.cast(map_value.obj()).? .member(vm, property_idx) catch @panic("Could not get map method"); return if (bind) bz_bindMethod( vm, map_value, - Value.Null, + v.Value.Null, method, ) else method; } -export fn bz_stringNext(string_value: Value, index: *Value, vm: *VM) callconv(.c) Value { - const string = ObjString.cast(string_value.obj()).?; +export fn bz_stringNext(string_value: v.Value, index: *v.Value, vm: *VM) callconv(.c) v.Value { + const string = o.ObjString.cast(string_value.obj()).?; if (string.next( vm, if (index.isNull()) null else index.integer(), ) catch @panic("Could not get next string index")) |new_index| { - index.* = Value.fromInteger(new_index); + index.* = v.Value.fromInteger(new_index); return (vm.gc.copyString(&[_]u8{string.string[@as(usize, @intCast(new_index))]}) catch @panic("Could not iterate on string")).toValue(); } - index.* = Value.Null; - return Value.Null; + index.* = v.Value.Null; + return v.Value.Null; } -export fn bz_listNext(list_value: Value, index: *Value, vm: *VM) callconv(.c) Value { - const list = ObjList.cast(list_value.obj()).?; +export fn bz_listNext(list_value: v.Value, index: *v.Value, vm: *VM) callconv(.c) v.Value { + const list = o.ObjList.cast(list_value.obj()).?; if (list.rawNext( vm, if (index.isNull()) null else index.integer(), ) catch @panic("Could not get next list index")) |new_index| { - index.* = Value.fromInteger(new_index); + index.* = v.Value.fromInteger(new_index); return list.items.items[@as(usize, @intCast(new_index))]; } - index.* = Value.Null; - return Value.Null; + index.* = v.Value.Null; + return v.Value.Null; } -export fn bz_rangeNext(range_value: Value, index_slot: Value) callconv(.c) Value { - const range = ObjRange.cast(range_value.obj()).?; +export fn bz_rangeNext(range_value: v.Value, index_slot: v.Value) callconv(.c) v.Value { + const range = o.ObjRange.cast(range_value.obj()).?; if (index_slot.integerOrNull()) |index| { if (range.low < range.high) { return if (index + 1 >= range.high) - Value.Null + v.Value.Null else - Value.fromInteger(index + 1); + v.Value.fromInteger(index + 1); } else { return if (index - 1 <= range.high) - Value.Null + v.Value.Null else - Value.fromInteger(index - 1); + v.Value.fromInteger(index - 1); } } - return Value.fromInteger(range.low); + return v.Value.fromInteger(range.low); } -export fn bz_mapNext(map_value: Value, key: *Value) callconv(.c) Value { - const map = ObjMap.cast(map_value.obj()).?; +export fn bz_mapNext(map_value: v.Value, key: *v.Value) callconv(.c) v.Value { + const map = o.ObjMap.cast(map_value.obj()).?; if (map.rawNext(if (key.isNull()) null else key.*)) |new_key| { key.* = new_key; - return map.map.get(new_key) orelse Value.Null; + return map.map.get(new_key) orelse v.Value.Null; } - key.* = Value.Null; - return Value.Null; + key.* = v.Value.Null; + return v.Value.Null; } -export fn bz_enumNext(enum_value: Value, case: Value, vm: *VM) callconv(.c) Value { - const enum_ = ObjEnum.cast(enum_value.obj()).?; +export fn bz_enumNext(enum_value: v.Value, case: v.Value, vm: *VM) callconv(.c) v.Value { + const enum_ = o.ObjEnum.cast(enum_value.obj()).?; if (enum_.rawNext( vm, - if (case.isNull()) null else ObjEnumInstance.cast(case.obj()), + if (case.isNull()) null else o.ObjEnumInstance.cast(case.obj()), ) catch @panic("Could not iterate over enum")) |new_case| { return new_case.toValue(); } - return Value.Null; + return v.Value.Null; } -export fn bz_clone(vm: *VM, value: Value) callconv(.c) Value { +export fn bz_clone(vm: *VM, value: v.Value) callconv(.c) v.Value { return vm.cloneValue(value) catch @panic("Could not clone value"); } -export fn bz_zigType(vm: *VM, ztype: [*]const u8, len: usize, expected_type: *Value) callconv(.c) ?*const ZigType { +export fn bz_zigType(vm: *VM, ztype: [*]const u8, len: usize, expected_type: *v.Value) callconv(.c) ?*const ZigType { if (is_wasm) { return null; } @@ -1455,8 +1428,8 @@ export fn bz_zigType(vm: *VM, ztype: [*]const u8, len: usize, expected_type: *Va return null; } -export fn bz_foreignContainerGet(value: Value, field_idx: usize, vm: *VM) callconv(.c) Value { - const container = ObjForeignContainer.cast(value.obj()).?; +export fn bz_foreignContainerGet(value: v.Value, field_idx: usize, vm: *VM) callconv(.c) v.Value { + const container = o.ObjForeignContainer.cast(value.obj()).?; return container.type_def.resolved_type.? .ForeignContainer @@ -1467,8 +1440,8 @@ export fn bz_foreignContainerGet(value: Value, field_idx: usize, vm: *VM) callco ); } -export fn bz_foreignContainerSet(value: Value, field_idx: usize, new_value: Value, vm: *VM) callconv(.c) void { - const container = ObjForeignContainer.cast(value.obj()).?; +export fn bz_foreignContainerSet(value: v.Value, field_idx: usize, new_value: v.Value, vm: *VM) callconv(.c) void { + const container = o.ObjForeignContainer.cast(value.obj()).?; // Oh right that's beautiful enough... return container.type_def.resolved_type.?.ForeignContainer .fields.values()[field_idx] @@ -1479,12 +1452,12 @@ export fn bz_foreignContainerSet(value: Value, field_idx: usize, new_value: Valu ); } -export fn bz_newForeignContainerInstance(vm: *VM, typedef_value: Value) callconv(.c) Value { +export fn bz_newForeignContainerInstance(vm: *VM, typedef_value: v.Value) callconv(.c) v.Value { return (vm.gc.allocateObject( - ObjForeignContainer, - ObjForeignContainer.init( + o.ObjForeignContainer, + o.ObjForeignContainer.init( vm, - ObjTypeDef.cast(typedef_value.obj()).?, + o.ObjTypeDef.cast(typedef_value.obj()).?, ) catch { vm.panic("Out of memory"); unreachable; @@ -1495,23 +1468,23 @@ export fn bz_newForeignContainerInstance(vm: *VM, typedef_value: Value) callconv }).toValue(); } -export fn bz_foreignContainerSlice(container_value: Value, len: *usize) callconv(.c) [*]u8 { - const container = ObjForeignContainer.cast(container_value.obj()).?; +export fn bz_foreignContainerSlice(container_value: v.Value, len: *usize) callconv(.c) [*]u8 { + const container = o.ObjForeignContainer.cast(container_value.obj()).?; len.* = container.data.len; return container.data.ptr; } -export fn bz_valueIsForeignContainer(value: Value) callconv(.c) bool { +export fn bz_valueIsForeignContainer(value: v.Value) callconv(.c) bool { return value.isObj() and value.obj().obj_type == .ForeignContainer; } -export fn bz_newForeignContainerFromSlice(vm: *VM, type_def: Value, ptr: [*]u8, len: usize) callconv(.c) Value { +export fn bz_newForeignContainerFromSlice(vm: *VM, type_def: v.Value, ptr: [*]u8, len: usize) callconv(.c) v.Value { var container = (vm.gc.allocateObject( - ObjForeignContainer, + o.ObjForeignContainer, .{ - .type_def = ObjTypeDef.cast(type_def.obj()).?, + .type_def = o.ObjTypeDef.cast(type_def.obj()).?, .data = ptr[0..len], }, ) catch { @@ -1541,8 +1514,8 @@ export fn bz_zigTypeToCString(self: *ZigType, vm: *VM) callconv(.c) [*:0]const u return @ptrCast(out.items.ptr); } -export fn bz_serialize(vm: *VM, value: Value, error_value: *Value) callconv(.c) Value { - var seen = std.AutoHashMap(*Obj, void).init(vm.gc.allocator); +export fn bz_serialize(vm: *VM, value: v.Value, error_value: *v.Value) callconv(.c) v.Value { + var seen = std.AutoHashMap(*o.Obj, void).init(vm.gc.allocator); defer seen.deinit(); return value.serialize(vm, &seen) catch |err| s: { @@ -1556,7 +1529,7 @@ export fn bz_serialize(vm: *VM, value: Value, error_value: *Value) callconv(.c) null, 0, ); - break :s Value.Void; + break :s v.Value.Void; }, error.NotSerializable => { error_value.* = instanciateError( @@ -1566,7 +1539,7 @@ export fn bz_serialize(vm: *VM, value: Value, error_value: *Value) callconv(.c) null, 0, ); - break :s Value.Void; + break :s v.Value.Void; }, else => { vm.panic("Out of memory"); @@ -1576,9 +1549,9 @@ export fn bz_serialize(vm: *VM, value: Value, error_value: *Value) callconv(.c) }; } -export fn bz_currentFiber(vm: *VM) callconv(.c) Value { +export fn bz_currentFiber(vm: *VM) callconv(.c) v.Value { return (vm.gc.allocateObject( - ObjFiber, + o.ObjFiber, .{ .fiber = vm.current_fiber, }, @@ -1598,13 +1571,13 @@ export fn bz_readZigValueFromBuffer( at: usize, buf: [*]u8, len: usize, -) callconv(.c) Value { +) callconv(.c) v.Value { var buffer = std.ArrayList(u8).fromOwnedSlice(vm.gc.allocator, buf[0..len]); buffer.capacity = len; // All those cases are necessary because bytesAsValue require arrays and not slices const value = switch (ztype.*) { - .Bool => Value.fromBoolean(buffer.items[at] == 1), + .Bool => v.Value.fromBoolean(buffer.items[at] == 1), .Int => integer: { const offset = at * ztype.size(); const bytes = buffer.items[offset .. offset + (ztype.Int.bits / 8)]; @@ -1612,7 +1585,7 @@ export fn bz_readZigValueFromBuffer( switch (ztype.Int.bits) { 64 => { const userdata = vm.gc.allocateObject( - ObjUserData, + o.ObjUserData, .{ .userdata = @as( u64, @@ -1651,14 +1624,16 @@ export fn bz_readZigValueFromBuffer( }, 32 => { if (ztype.Int.signedness == .signed) { - break :integer Value.fromInteger( - std.mem.bytesToValue( - Integer, - bytes[0..4], + break :integer v.Value.fromInteger( + @intCast( + std.mem.bytesToValue( + i32, + bytes[0..4], + ), ), ); } else { - break :integer Value.fromFloat( + break :integer v.Value.fromDouble( @floatFromInt( std.mem.bytesToValue( u32, @@ -1669,7 +1644,7 @@ export fn bz_readZigValueFromBuffer( } }, 16 => { - break :integer Value.fromInteger( + break :integer v.Value.fromInteger( if (ztype.Int.signedness == .signed) std.mem.bytesToValue( i16, @@ -1683,7 +1658,7 @@ export fn bz_readZigValueFromBuffer( ); }, 8 => { - break :integer Value.fromInteger( + break :integer v.Value.fromInteger( if (ztype.Int.signedness == .signed) std.mem.bytesToValue( i8, @@ -1696,7 +1671,7 @@ export fn bz_readZigValueFromBuffer( ), ); }, - else => break :integer Value.Void, + else => break :integer v.Value.Void, } }, .Double => double: { @@ -1705,18 +1680,18 @@ export fn bz_readZigValueFromBuffer( switch (ztype.Double.bits) { 32 => { - break :double Value.fromFloat( + break :double v.Value.fromDouble( @floatCast( std.mem.bytesToValue(f32, bytes[0..4]), ), ); }, 64 => { - break :double Value.fromFloat( - std.mem.bytesToValue(Double, bytes[0..8]), + break :double v.Value.fromDouble( + std.mem.bytesToValue(v.Double, bytes[0..8]), ); }, - else => break :double Value.Void, + else => break :double v.Value.Void, } }, .Pointer, @@ -1727,7 +1702,7 @@ export fn bz_readZigValueFromBuffer( const bytes = buffer.items[offset .. offset + 8]; const userdata = vm.gc.allocateObject( - ObjUserData, + o.ObjUserData, .{ .userdata = std.mem.bytesToValue(u64, bytes[0..8]), }, @@ -1738,7 +1713,7 @@ export fn bz_readZigValueFromBuffer( break :ptr userdata.toValue(); }, - else => Value.Void, + else => v.Value.Void, }; return value; @@ -1746,7 +1721,7 @@ export fn bz_readZigValueFromBuffer( export fn bz_writeZigValueToBuffer( vm: *VM, - value: Value, + value: v.Value, ztype: *const ZigType, at: usize, buf: [*]u8, @@ -1773,7 +1748,7 @@ export fn bz_writeZigValueToBuffer( .Int => { switch (ztype.Int.bits) { 64 => { - const unwrapped = ObjUserData.cast(value.obj()).?.userdata; + const unwrapped = o.ObjUserData.cast(value.obj()).?.userdata; const bytes = std.mem.asBytes(&unwrapped); buffer.replaceRange(at, bytes.len, bytes) catch { @@ -1829,7 +1804,7 @@ export fn bz_writeZigValueToBuffer( .Fn, .Opaque, => { - const unwrapped = ObjUserData.cast(value.obj()).?.userdata; + const unwrapped = o.ObjUserData.cast(value.obj()).?.userdata; const bytes = std.mem.asBytes(&unwrapped); buffer.replaceRange(at, bytes.len, bytes) catch { diff --git a/src/jit_extern_api.zig b/src/jit_extern_api.zig index cc52ba24..0e125386 100644 --- a/src/jit_extern_api.zig +++ b/src/jit_extern_api.zig @@ -81,6 +81,7 @@ pub const ExternApi = enum { bz_valueDump, fmod, + dumpInt, memcpy, pub fn declare(self: ExternApi, jit: *JIT) !m.MIR_item_t { @@ -189,12 +190,12 @@ pub const ExternApi = enum { .size = undefined, }, .{ - .type = m.MIR_T_I32, + .type = m.MIR_T_I64, .name = "low", .size = undefined, }, .{ - .type = m.MIR_T_I32, + .type = m.MIR_T_I64, .name = "high", .size = undefined, }, @@ -237,7 +238,7 @@ pub const ExternApi = enum { .size = undefined, }, .{ - .type = m.MIR_T_I32, + .type = m.MIR_T_I64, .name = "index", .size = undefined, }, @@ -1063,6 +1064,20 @@ pub const ExternApi = enum { }, }, ), + .dumpInt => m.MIR_new_proto_arr( + ctx, + self.pname(), + 0, + &[_]m.MIR_type_t{}, + 1, + &[_]m.MIR_var_t{ + .{ + .type = m.MIR_T_U64, + .name = "value", + .size = undefined, + }, + }, + ), .memcpy => m.MIR_new_proto_arr( ctx, self.pname(), @@ -1165,6 +1180,7 @@ pub const ExternApi = enum { .bz_valueDump => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_valueDump))), .fmod => @as(*anyopaque, @ptrFromInt(@intFromPtr(&JIT.fmod))), + .dumpInt => @as(*anyopaque, @ptrFromInt(@intFromPtr(&JIT.dumpInt))), .memcpy => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.bz_memcpy))), else => { io.print("{s}\n", .{self.name()}); diff --git a/src/lib/buzz_api.zig b/src/lib/buzz_api.zig index 537b06eb..1a244f34 100644 --- a/src/lib/buzz_api.zig +++ b/src/lib/buzz_api.zig @@ -12,6 +12,9 @@ else pub const Native = fn (ctx: *NativeCtx) callconv(.C) c_int; pub const NativeFn = *const Native; +pub const Double = f64; +pub const Integer = i48; + // FIXME: can we avoid duplicating this code from value.zig? const Tag = u3; const TagBoolean: Tag = 0; @@ -26,6 +29,7 @@ const SignMask: u64 = 1 << 63; /// QNAN and one extra bit to the right. const TaggedValueMask: u64 = 0x7ffc000000000000; +pub const TaggedUpperValueMask: u64 = 0xffff000000000000; /// TaggedMask + Sign bit indicates a pointer value. const PointerMask: u64 = TaggedValueMask | SignMask; @@ -34,14 +38,13 @@ const BooleanMask: u64 = TaggedValueMask | (@as(u64, TagBoolean) << 32); const FalseMask: u64 = BooleanMask; const TrueBitMask: u64 = 1; const TrueMask: u64 = BooleanMask | TrueBitMask; - -const IntegerMask: u64 = TaggedValueMask | (@as(u64, TagInteger) << 32); +const IntegerMask: u64 = TaggedValueMask | (@as(u64, TagInteger) << 49); const NullMask: u64 = TaggedValueMask | (@as(u64, TagNull) << 32); const VoidMask: u64 = TaggedValueMask | (@as(u64, TagVoid) << 32); const ErrorMask: u64 = TaggedValueMask | (@as(u64, TagError) << 32); const TagMask: u32 = (1 << 3) - 1; -const TaggedPrimitiveMask = TaggedValueMask | (@as(u64, TagMask) << 32); +const TaggedPrimitiveMask = TaggedValueMask | (@as(u64, TagMask) << 32) | IntegerMask; pub const Value = packed struct { val: u64, @@ -57,11 +60,11 @@ pub const Value = packed struct { return if (val) True else False; } - pub inline fn fromInteger(val: i32) Value { - return .{ .val = IntegerMask | @as(u32, @bitCast(val)) }; + pub inline fn fromInteger(val: Integer) Value { + return .{ .val = IntegerMask | @as(u48, @bitCast(val)) }; } - pub inline fn fromFloat(val: f64) Value { + pub inline fn fromDouble(val: Double) Value { return .{ .val = @as(u64, @bitCast(val)) }; } @@ -78,7 +81,7 @@ pub const Value = packed struct { } pub inline fn isInteger(self: Value) bool { - return self.val & (TaggedPrimitiveMask | SignMask) == IntegerMask; + return self.val & (TaggedUpperValueMask | SignMask) == IntegerMask; } pub inline fn isFloat(self: Value) bool { @@ -109,16 +112,16 @@ pub const Value = packed struct { return self.val == TrueMask; } - pub inline fn integer(self: Value) i32 { - return @bitCast(@as(u32, @intCast(self.val & 0xffffffff))); + pub inline fn integer(self: Value) Integer { + return @bitCast(@as(u48, @intCast(self.val & 0xffffffffffff))); } - pub inline fn double(self: Value) f64 { + pub inline fn double(self: Value) Double { return @bitCast(self.val); } pub inline fn obj(self: Value) *anyopaque { - return @ptrFromInt(self.val & ~PointerMask); + return @ptrFromInt(@as(usize, @truncate(self.val & ~PointerMask))); } pub extern fn bz_valueToString(value: Value, len: *usize) ?[*]const u8; @@ -139,7 +142,7 @@ pub const Value = packed struct { pub extern fn bz_rangeNext(range_value: Value, index_slot: Value) callconv(.c) Value; pub extern fn bz_getRangeProperty(range_value: Value, property_idx: usize, bind: bool, vm: *VM) callconv(.c) Value; pub extern fn bz_listAppend(list: Value, value: Value, vm: *VM) callconv(.c) void; - pub extern fn bz_listGet(list: Value, index: i32, checked: bool) callconv(.c) Value; + pub extern fn bz_listGet(list: Value, index: i64, checked: bool) callconv(.c) Value; pub extern fn bz_listSet(list: Value, index: usize, value: Value, vm: *VM) callconv(.c) void; pub extern fn bz_listLen(list: Value) callconv(.c) usize; pub extern fn bz_listConcat(list: Value, other_list: Value, vm: *VM) callconv(.c) Value; @@ -253,7 +256,7 @@ pub const VM = opaque { pub extern fn bz_getMapProperty(vm: *VM, map: Value, property_idx: usize, bind: bool) callconv(.c) Value; pub extern fn bz_getPatternProperty(vm: *VM, pattern: Value, property_idx: usize) callconv(.c) Value; pub extern fn bz_getFiberProperty(vm: *VM, fiber: Value, property_idx: usize) callconv(.c) Value; - pub extern fn bz_newRange(vm: *VM, low: i32, high: i32) callconv(.c) Value; + pub extern fn bz_newRange(vm: *VM, low: i64, high: i64) callconv(.c) Value; pub extern fn bz_newList(vm: *VM, list_type: Value) callconv(.c) Value; pub extern fn bz_newMap(vm: *VM, map_type: Value) callconv(.c) Value; pub extern fn bz_newQualifiedObjectInstance(self: *VM, qualified_name: [*]const u8, len: usize, mutable: bool) callconv(.c) Value; diff --git a/src/lib/buzz_buffer.zig b/src/lib/buzz_buffer.zig index 172d0c4f..c6405804 100644 --- a/src/lib/buzz_buffer.zig +++ b/src/lib/buzz_buffer.zig @@ -135,7 +135,7 @@ const Buffer = struct { try self.buffer.append(if (value) 1 else 0); } - pub fn readInteger(self: *Self) !?i32 { + pub fn readInteger(self: *Self) !?api.Integer { if (self.cursor > self.buffer.items.len) { return null; } @@ -143,14 +143,14 @@ const Buffer = struct { var buffer_stream = std.io.fixedBufferStream(self.buffer.items[self.cursor..self.buffer.items.len]); var reader = buffer_stream.reader(); - const number = try reader.readInt(i32, builtin.cpu.arch.endian()); + const number = try reader.readInt(api.Integer, builtin.cpu.arch.endian()); - self.cursor += @sizeOf(i32); + self.cursor += @divExact(@typeInfo(api.Integer).int.bits, 8); return number; } - pub fn writeInteger(self: *Self, integer: i32) !void { + pub fn writeInteger(self: *Self, integer: api.Integer) !void { if (self.cursor > 0) { return Error.WriteWhileReading; } @@ -158,7 +158,7 @@ const Buffer = struct { var writer = self.buffer.writer(); // Flag so we know it an integer - try writer.writeInt(i32, integer, native_endian); + try writer.writeInt(api.Integer, integer, native_endian); } pub fn readUserData(self: *Self, vm: *api.VM) !?api.Value { @@ -191,7 +191,7 @@ const Buffer = struct { ); } - pub fn readFloat(self: *Self) !?f64 { + pub fn readDouble(self: *Self) !?api.Double { if (self.cursor > self.buffer.items.len) { return null; } @@ -201,19 +201,18 @@ const Buffer = struct { const number = try reader.readInt(u64, builtin.cpu.arch.endian()); - self.cursor += @sizeOf(f64); + self.cursor += @divExact(@typeInfo(u64).int.bits, 8); return @bitCast(number); } - pub fn writeFloat(self: *Self, double: f64) !void { + pub fn writeFloat(self: *Self, double: api.Double) !void { if (self.cursor > 0) { return Error.WriteWhileReading; } var writer = self.buffer.writer(); - // Flag so we know it an double try writer.writeInt( u64, @as(u64, @bitCast(double)), @@ -365,7 +364,7 @@ pub export fn BufferReadUserData(ctx: *api.NativeCtx) callconv(.c) c_int { pub export fn BufferReadDouble(ctx: *api.NativeCtx) callconv(.c) c_int { const buffer = Buffer.fromUserData(ctx.vm.bz_peek(0).bz_getUserDataPtr()); - if (buffer.readFloat() catch |err| { + if (buffer.readDouble() catch |err| { switch (err) { error.EndOfStream => { ctx.vm.bz_push(api.Value.Null); @@ -374,7 +373,7 @@ pub export fn BufferReadDouble(ctx: *api.NativeCtx) callconv(.c) c_int { }, } }) |value| { - ctx.vm.bz_push(api.Value.fromFloat(value)); + ctx.vm.bz_push(api.Value.fromDouble(value)); return 1; } diff --git a/src/lib/buzz_math.zig b/src/lib/buzz_math.zig index a3eba2a1..2c854460 100644 --- a/src/lib/buzz_math.zig +++ b/src/lib/buzz_math.zig @@ -10,39 +10,39 @@ else std.os; pub export fn abs(ctx: *api.NativeCtx) callconv(.c) c_int { - const n_f: f64 = ctx.vm.bz_peek(0).double(); + const n_f: api.Double = ctx.vm.bz_peek(0).double(); - ctx.vm.bz_push(api.Value.fromFloat(if (n_f < 0) n_f * -1 else n_f)); + ctx.vm.bz_push(api.Value.fromDouble(if (n_f < 0) n_f * -1 else n_f)); return 1; } pub export fn acos(ctx: *api.NativeCtx) callconv(.c) c_int { - const n_f: f64 = ctx.vm.bz_peek(0).double(); + const n_f: api.Double = ctx.vm.bz_peek(0).double(); - ctx.vm.bz_push(api.Value.fromFloat(std.math.acos(n_f))); + ctx.vm.bz_push(api.Value.fromDouble(std.math.acos(n_f))); return 1; } pub export fn asin(ctx: *api.NativeCtx) callconv(.c) c_int { - const n_f: f64 = ctx.vm.bz_peek(0).double(); + const n_f: api.Double = ctx.vm.bz_peek(0).double(); - ctx.vm.bz_push(api.Value.fromFloat(std.math.asin(n_f))); + ctx.vm.bz_push(api.Value.fromDouble(std.math.asin(n_f))); return 1; } pub export fn atan(ctx: *api.NativeCtx) callconv(.c) c_int { - const n_f: f64 = ctx.vm.bz_peek(0).double(); + const n_f: api.Double = ctx.vm.bz_peek(0).double(); - ctx.vm.bz_push(api.Value.fromFloat(std.math.atan(n_f))); + ctx.vm.bz_push(api.Value.fromDouble(std.math.atan(n_f))); return 1; } pub export fn bzceil(ctx: *api.NativeCtx) callconv(.c) c_int { - const n_f: f64 = ctx.vm.bz_peek(0).double(); + const n_f: api.Double = ctx.vm.bz_peek(0).double(); ctx.vm.bz_push(api.Value.fromInteger(@intFromFloat(std.math.ceil(n_f)))); @@ -50,23 +50,23 @@ pub export fn bzceil(ctx: *api.NativeCtx) callconv(.c) c_int { } pub export fn bzcos(ctx: *api.NativeCtx) callconv(.c) c_int { - const n_f: f64 = ctx.vm.bz_peek(0).double(); + const n_f: api.Double = ctx.vm.bz_peek(0).double(); - ctx.vm.bz_push(api.Value.fromFloat(std.math.cos(n_f))); + ctx.vm.bz_push(api.Value.fromDouble(std.math.cos(n_f))); return 1; } pub export fn bzexp(ctx: *api.NativeCtx) callconv(.c) c_int { - const n_f: f64 = ctx.vm.bz_peek(0).double(); + const n_f: api.Double = ctx.vm.bz_peek(0).double(); - ctx.vm.bz_push(api.Value.fromFloat(std.math.exp(n_f))); + ctx.vm.bz_push(api.Value.fromDouble(std.math.exp(n_f))); return 1; } pub export fn bzfloor(ctx: *api.NativeCtx) callconv(.c) c_int { - const n_f: f64 = ctx.vm.bz_peek(0).double(); + const n_f: api.Double = ctx.vm.bz_peek(0).double(); ctx.vm.bz_push(api.Value.fromInteger(@intFromFloat(std.math.floor(n_f)))); @@ -74,10 +74,10 @@ pub export fn bzfloor(ctx: *api.NativeCtx) callconv(.c) c_int { } pub export fn bzlog(ctx: *api.NativeCtx) callconv(.c) c_int { - const base_i: f64 = ctx.vm.bz_peek(1).double(); - const n_f: f64 = ctx.vm.bz_peek(0).double(); + const base_i: api.Double = ctx.vm.bz_peek(1).double(); + const n_f: api.Double = ctx.vm.bz_peek(0).double(); - ctx.vm.bz_push(api.Value.fromFloat(std.math.log(f64, base_i, n_f))); + ctx.vm.bz_push(api.Value.fromDouble(std.math.log(api.Double, base_i, n_f))); return 1; } @@ -86,7 +86,7 @@ pub export fn maxDouble(ctx: *api.NativeCtx) callconv(.c) c_int { const a_f = ctx.vm.bz_peek(0).double(); const b_f = ctx.vm.bz_peek(1).double(); - ctx.vm.bz_push(api.Value.fromFloat(@max(a_f, b_f))); + ctx.vm.bz_push(api.Value.fromDouble(@max(a_f, b_f))); return 1; } @@ -95,7 +95,7 @@ pub export fn minDouble(ctx: *api.NativeCtx) callconv(.c) c_int { const a_f = ctx.vm.bz_peek(0).double(); const b_f = ctx.vm.bz_peek(1).double(); - ctx.vm.bz_push(api.Value.fromFloat(@min(a_f, b_f))); + ctx.vm.bz_push(api.Value.fromDouble(@min(a_f, b_f))); return 1; } @@ -119,25 +119,25 @@ pub export fn minInt(ctx: *api.NativeCtx) callconv(.c) c_int { } pub export fn bzsin(ctx: *api.NativeCtx) callconv(.c) c_int { - const n: f64 = ctx.vm.bz_peek(0).double(); + const n: api.Double = ctx.vm.bz_peek(0).double(); - ctx.vm.bz_push(api.Value.fromFloat(std.math.sin(n))); + ctx.vm.bz_push(api.Value.fromDouble(std.math.sin(n))); return 1; } pub export fn bzsqrt(ctx: *api.NativeCtx) callconv(.c) c_int { - const n_f: f64 = ctx.vm.bz_peek(0).double(); + const n_f: api.Double = ctx.vm.bz_peek(0).double(); - ctx.vm.bz_push(api.Value.fromFloat(std.math.sqrt(n_f))); + ctx.vm.bz_push(api.Value.fromDouble(std.math.sqrt(n_f))); return 1; } pub export fn bztan(ctx: *api.NativeCtx) callconv(.c) c_int { - const n: f64 = ctx.vm.bz_peek(0).double(); + const n: api.Double = ctx.vm.bz_peek(0).double(); - ctx.vm.bz_push(api.Value.fromFloat(std.math.tan(n))); + ctx.vm.bz_push(api.Value.fromDouble(std.math.tan(n))); return 1; } @@ -146,24 +146,24 @@ pub export fn pow(ctx: *api.NativeCtx) callconv(.c) c_int { const n = ctx.vm.bz_peek(1); const p = ctx.vm.bz_peek(0); - const n_i: ?i32 = if (n.isInteger()) n.integer() else null; - const n_f: ?f64 = if (n.isFloat()) n.double() else null; + const n_i: ?api.Integer = if (n.isInteger()) n.integer() else null; + const n_f: ?api.Double = if (n.isFloat()) n.double() else null; - const p_i: ?i32 = if (p.isInteger()) p.integer() else null; - const p_f: ?f64 = if (p.isFloat()) p.double() else null; + const p_i: ?api.Integer = if (p.isInteger()) p.integer() else null; + const p_f: ?api.Double = if (p.isFloat()) p.double() else null; if (p_f) |pf| { - ctx.vm.bz_push(api.Value.fromFloat( - std.math.pow(f64, n_f orelse @as(f64, @floatFromInt(n_i.?)), pf), + ctx.vm.bz_push(api.Value.fromDouble( + std.math.pow(api.Double, n_f orelse @as(api.Double, @floatFromInt(n_i.?)), pf), )); } else if (n_f) |nf| { - ctx.vm.bz_push(api.Value.fromFloat( - std.math.pow(f64, nf, p_f orelse @as(f64, @floatFromInt(p_i.?))), + ctx.vm.bz_push(api.Value.fromDouble( + std.math.pow(api.Double, nf, p_f orelse @as(api.Double, @floatFromInt(p_i.?))), )); } else { ctx.vm.bz_push( api.Value.fromInteger( - std.math.powi(i32, n_i.?, p_i.?) catch |err| { + std.math.powi(api.Integer, n_i.?, p_i.?) catch |err| { switch (err) { error.Overflow => ctx.vm.pushError("errors.OverflowError", null), error.Underflow => ctx.vm.pushError("errors.UnderflowError", null), diff --git a/src/lib/buzz_os.zig b/src/lib/buzz_os.zig index 7e4fc5d7..954e0924 100644 --- a/src/lib/buzz_os.zig +++ b/src/lib/buzz_os.zig @@ -9,7 +9,7 @@ pub export fn sleep(ctx: *api.NativeCtx) callconv(.c) c_int { } pub export fn time(ctx: *api.NativeCtx) callconv(.c) c_int { - ctx.vm.bz_push(api.Value.fromFloat(@as(f64, @floatFromInt(std.time.milliTimestamp())))); + ctx.vm.bz_push(api.Value.fromDouble(@as(api.Double, @floatFromInt(std.time.milliTimestamp())))); return 1; } @@ -89,7 +89,7 @@ pub export fn tmpFilename(ctx: *api.NativeCtx) callconv(.c) c_int { var random_part = std.ArrayList(u8).init(api.VM.allocator); defer random_part.deinit(); - random_part.writer().print("{x}", .{std.crypto.random.int(i32)}) catch { + random_part.writer().print("{x}", .{std.crypto.random.int(api.Integer)}) catch { ctx.vm.bz_panic("Out of memory", "Out of memory".len); unreachable; }; @@ -130,7 +130,7 @@ pub export fn tmpFilename(ctx: *api.NativeCtx) callconv(.c) c_int { // If it was named `exit` it would be considered by zig as a callback when std.process.exit is called pub export fn buzzExit(ctx: *api.NativeCtx) callconv(.c) c_int { - const exitCode: i32 = ctx.vm.bz_peek(0).integer(); + const exitCode: api.Integer = ctx.vm.bz_peek(0).integer(); std.process.exit(@intCast(exitCode)); @@ -334,7 +334,7 @@ pub export fn SocketConnect(ctx: *api.NativeCtx) callconv(.c) c_int { var len: usize = 0; const address_value = api.Value.bz_valueToString(ctx.vm.bz_peek(2), &len); const address = if (len > 0) address_value.?[0..len] else ""; - const port: ?i32 = ctx.vm.bz_peek(1).integer(); + const port: ?api.Integer = ctx.vm.bz_peek(1).integer(); if (port == null or port.? < 0) { ctx.vm.pushError("errors.InvalidArgumentError", null); @@ -439,7 +439,7 @@ fn handleReadAllError(ctx: *api.NativeCtx, err: anytype) void { } pub export fn SocketRead(ctx: *api.NativeCtx) callconv(.c) c_int { - const n: i32 = ctx.vm.bz_peek(0).integer(); + const n: api.Integer = ctx.vm.bz_peek(0).integer(); if (n < 0) { ctx.vm.pushError("errors.InvalidArgumentError", null); @@ -665,7 +665,7 @@ pub export fn SocketServerStart(ctx: *api.NativeCtx) callconv(.c) c_int { var len: usize = 0; const address_value = api.Value.bz_valueToString(ctx.vm.bz_peek(3), &len); const address = if (len > 0) address_value.?[0..len] else ""; - const port: ?i32 = ctx.vm.bz_peek(2).integer(); + const port: ?api.Integer = ctx.vm.bz_peek(2).integer(); if (port == null or port.? < 0) { ctx.vm.pushError("errors.InvalidArgumentError", null); diff --git a/src/lib/buzz_std.zig b/src/lib/buzz_std.zig index d320745f..a85cb327 100644 --- a/src/lib/buzz_std.zig +++ b/src/lib/buzz_std.zig @@ -26,7 +26,7 @@ pub export fn random(ctx: *api.NativeCtx) callconv(.c) c_int { ctx.vm.bz_push( api.Value.fromInteger( std.crypto.random.intRangeAtMost( - i32, + api.Integer, if (min.isInteger()) min.integer() else @@ -70,7 +70,7 @@ pub export fn toDouble(ctx: *api.NativeCtx) callconv(.c) c_int { const value = ctx.vm.bz_peek(0); ctx.vm.bz_push( - api.Value.fromFloat(@floatFromInt(value.integer())), + api.Value.fromDouble(@floatFromInt(value.integer())), ); return 1; @@ -105,7 +105,7 @@ pub export fn parseInt(ctx: *api.NativeCtx) callconv(.c) c_int { const string_slice = string.?[0..len]; - const number = std.fmt.parseInt(i32, string_slice, 10) catch { + const number = std.fmt.parseInt(api.Integer, string_slice, 10) catch { ctx.vm.bz_push(api.Value.Null); return 1; @@ -166,7 +166,7 @@ pub export fn parseDouble(ctx: *api.NativeCtx) callconv(.c) c_int { return 1; }; - ctx.vm.bz_push(api.Value.fromFloat(number)); + ctx.vm.bz_push(api.Value.fromDouble(number)); return 1; } diff --git a/src/obj.zig b/src/obj.zig index b99c46ea..8dd0726f 100644 --- a/src/obj.zig +++ b/src/obj.zig @@ -12,8 +12,9 @@ const Parser = @import("Parser.zig"); const _memory = @import("memory.zig"); const GarbageCollector = _memory.GarbageCollector; const TypeRegistry = _memory.TypeRegistry; -const Integer = @import("value.zig").Integer; -const Value = @import("value.zig").Value; +const v = @import("value.zig"); +const Integer = v.Integer; +const Value = v.Value; const Token = @import("Token.zig"); const is_wasm = builtin.cpu.arch.isWasm(); const BuildOptions = @import("build_options"); @@ -990,9 +991,9 @@ pub const ObjString = struct { return vm.gc.copyString(new_string.items); } - pub fn next(self: *Self, vm: *VM, str_index: ?i32) !?i32 { + pub fn next(self: *Self, vm: *VM, str_index: ?Integer) !?Integer { if (str_index) |index| { - if (index < 0 or index >= @as(i32, @intCast(self.string.len))) { + if (index < 0 or index >= @as(Integer, @intCast(self.string.len))) { try vm.throw( VM.Error.OutOfBound, (try vm.gc.copyString("Out of bound access to str")).toValue(), @@ -1001,12 +1002,12 @@ pub const ObjString = struct { ); } - return if (index + 1 >= @as(i32, @intCast(self.string.len))) + return if (index + 1 >= @as(Integer, @intCast(self.string.len))) null else index + 1; } else { - return if (self.string.len > 0) @as(i32, 0) else null; + return if (self.string.len > 0) @as(Integer, 0) else null; } } @@ -2074,9 +2075,9 @@ pub const ObjList = struct { } // Used also by the VM - pub fn rawNext(self: *Self, vm: *VM, list_index: ?i32) !?i32 { + pub fn rawNext(self: *Self, vm: *VM, list_index: ?Integer) !?Integer { if (list_index) |index| { - if (index < 0 or index >= @as(i32, @intCast(self.items.items.len))) { + if (index < 0 or index >= @as(Integer, @intCast(self.items.items.len))) { try vm.throw( VM.Error.OutOfBound, (try vm.gc.copyString("Out of bound access to list")).toValue(), @@ -2085,12 +2086,12 @@ pub const ObjList = struct { ); } - return if (index + 1 >= @as(i32, @intCast(self.items.items.len))) + return if (index + 1 >= @as(Integer, @intCast(self.items.items.len))) null else index + 1; } else { - return if (self.items.items.len > 0) @as(i32, 0) else null; + return if (self.items.items.len > 0) @as(Integer, 0) else null; } } diff --git a/src/value.zig b/src/value.zig index 251f0fc6..b217c6e1 100644 --- a/src/value.zig +++ b/src/value.zig @@ -6,7 +6,7 @@ const VM = @import("vm.zig").VM; const GarbageCollector = @import("memory.zig").GarbageCollector; pub const Double = f64; -pub const Integer = i32; +pub const Integer = i48; const Tag = u3; pub const Value = packed struct { @@ -22,23 +22,21 @@ pub const Value = packed struct { /// QNAN and one extra bit to the right. pub const TaggedValueMask: u64 = 0x7ffc000000000000; + pub const TaggedUpperValueMask: u64 = 0xffff000000000000; /// TaggedMask + Sign bit indicates a pointer value. pub const PointerMask: u64 = TaggedValueMask | SignMask; - pub const BooleanMask: u64 = TaggedValueMask | (@as(u64, TagBoolean) << 32); pub const FalseMask: u64 = BooleanMask; pub const TrueBitMask: u64 = 1; pub const TrueMask: u64 = BooleanMask | TrueBitMask; - - // FIXME: Their's room to have a bigger integer. How would MIR handle it? - pub const IntegerMask: u64 = TaggedValueMask | (@as(u64, TagInteger) << 32); + pub const IntegerMask: u64 = TaggedValueMask | (@as(u64, TagInteger) << 49); pub const NullMask: u64 = TaggedValueMask | (@as(u64, TagNull) << 32); pub const VoidMask: u64 = TaggedValueMask | (@as(u64, TagVoid) << 32); pub const ErrorMask: u64 = TaggedValueMask | (@as(u64, TagError) << 32); pub const TagMask: u32 = (1 << 3) - 1; - pub const TaggedPrimitiveMask = TaggedValueMask | (@as(u64, TagMask) << 32); + pub const TaggedPrimitiveMask = TaggedValueMask | (@as(u64, TagMask) << 32) | IntegerMask; val: u64, @@ -53,11 +51,11 @@ pub const Value = packed struct { return if (val) True else False; } - pub inline fn fromInteger(val: i32) Value { - return .{ .val = IntegerMask | @as(u32, @bitCast(val)) }; + pub inline fn fromInteger(val: Integer) Value { + return .{ .val = IntegerMask | @as(u48, @bitCast(val)) }; } - pub inline fn fromFloat(val: f64) Value { + pub inline fn fromDouble(val: Double) Value { return .{ .val = @as(u64, @bitCast(val)) }; } @@ -74,15 +72,15 @@ pub const Value = packed struct { } pub inline fn isInteger(self: Value) bool { - return self.val & (TaggedPrimitiveMask | SignMask) == IntegerMask; + return self.val & (TaggedUpperValueMask | SignMask) == IntegerMask; } - pub inline fn isFloat(self: Value) bool { + pub inline fn isDouble(self: Value) bool { return !self.isBool() and !self.isError() and !self.isInteger() and !self.isNull() and !self.isObj() and !self.isVoid(); } pub inline fn isNumber(self: Value) bool { - return self.isFloat() or self.isInteger(); + return self.isDouble() or self.isInteger(); } pub inline fn isObj(self: Value) bool { @@ -105,28 +103,28 @@ pub const Value = packed struct { return self.val == TrueMask; } - pub inline fn integer(self: Value) i32 { - return @as(i32, @bitCast(@as(u32, @intCast(self.val & 0xffffffff)))); + pub inline fn integer(self: Value) Integer { + return @bitCast(@as(u48, @intCast(self.val & 0xffffffffffff))); } - pub inline fn double(self: Value) f64 { - return @as(f64, @bitCast(self.val)); + pub inline fn double(self: Value) Double { + return @bitCast(self.val); } pub inline fn obj(self: Value) *o.Obj { - return @as(*o.Obj, @ptrFromInt(@as(usize, @truncate(self.val & ~PointerMask)))); + return @ptrFromInt(@as(usize, @truncate(self.val & ~PointerMask))); } pub inline fn booleanOrNull(self: Value) ?bool { return if (self.isBool()) self.boolean() else null; } - pub inline fn integerOrNull(self: Value) ?i32 { + pub inline fn integerOrNull(self: Value) ?Integer { return if (self.isInteger()) self.integer() else null; } - pub inline fn floatOrNull(self: Value) ?f64 { - return if (self.isFloat()) self.double() else null; + pub inline fn doubleOrNull(self: Value) ?Double { + return if (self.isDouble()) self.double() else null; } pub inline fn objOrNull(self: Value) ?*o.Obj { @@ -138,13 +136,16 @@ pub const Value = packed struct { return try self.obj().typeOf(gc); } - if (self.isFloat()) { + if (self.isDouble()) { return gc.type_registry.float_type; } + if (self.isInteger()) { + return gc.type_registry.int_type; + } + return switch (self.getTag()) { TagBoolean => gc.type_registry.bool_type, - TagInteger => gc.type_registry.int_type, TagNull, TagVoid => gc.type_registry.void_type, else => gc.type_registry.float_type, }; @@ -173,14 +174,18 @@ pub const Value = packed struct { return; } - if (self.isFloat()) { + if (self.isDouble()) { try writer.print("{d}", .{self.double()}); return; } + if (self.isInteger()) { + try writer.print("{d}", .{self.integer()}); + return; + } + switch (self.getTag()) { TagBoolean => try writer.print("{}", .{self.boolean()}), - TagInteger => try writer.print("{d}", .{self.integer()}), TagNull => try writer.print("null", .{}), TagVoid => try writer.print("void", .{}), else => try writer.print("{d}", .{self.double()}), @@ -199,21 +204,21 @@ pub const Value = packed struct { return a.obj().eql(b.obj()); } - if (a.isInteger() or a.isFloat()) { - const a_f: ?f64 = if (a.isFloat()) a.double() else null; - const b_f: ?f64 = if (b.isFloat()) b.double() else null; - const a_i: ?i32 = if (a.isInteger()) a.integer() else null; - const b_i: ?i32 = if (b.isInteger()) b.integer() else null; + if (a.isInteger() or a.isDouble()) { + const a_f = if (a.isDouble()) a.double() else null; + const b_f = if (b.isDouble()) b.double() else null; + const a_i = if (a.isInteger()) a.integer() else null; + const b_i = if (b.isInteger()) b.integer() else null; if (a_f) |af| { if (b_f) |bf| { return af == bf; } else { - return af == @as(f64, @floatFromInt(b_i.?)); + return af == @as(Double, @floatFromInt(b_i.?)); } } else { if (b_f) |bf| { - return @as(f64, @floatFromInt(a_i.?)) == bf; + return @as(Double, @floatFromInt(a_i.?)) == bf; } else { return a_i.? == b_i.?; } @@ -239,13 +244,16 @@ pub const Value = packed struct { return value.obj().is(type_def); } - if (value.isFloat()) { + if (value.isDouble()) { return type_def.def_type == .Double; } + if (value.isInteger()) { + return type_def.def_type == .Integer; + } + return switch (value.getTag()) { TagBoolean => type_def.def_type == .Bool, - TagInteger => type_def.def_type == .Integer, // TODO: this one is ambiguous at runtime, is it the `null` constant? or an optional local with a null value? TagNull => type_def.def_type == .Void or type_def.optional, TagVoid => type_def.def_type == .Void, @@ -258,13 +266,16 @@ pub const Value = packed struct { return value.obj().typeEql(type_def); } - if (value.isFloat()) { + if (value.isDouble()) { return type_def.def_type == .Double; } + if (value.isInteger()) { + return type_def.def_type == .Integer; + } + return switch (value.getTag()) { TagBoolean => type_def.def_type == .Bool, - TagInteger => type_def.def_type == .Integer, // TODO: this one is ambiguous at runtime, is it the `null` constant? or an optional local with a null value? TagNull => type_def.def_type == .Void or type_def.optional, TagVoid => type_def.def_type == .Void, diff --git a/src/vm.zig b/src/vm.zig index 0ca29dfe..c0c4709e 100644 --- a/src/vm.zig +++ b/src/vm.zig @@ -1,6 +1,7 @@ const std = @import("std"); const builtin = @import("builtin"); -const Value = @import("value.zig").Value; +const v = @import("value.zig"); +const Value = v.Value; const Chunk = @import("Chunk.zig"); const Ast = @import("Ast.zig"); const disassembler = @import("disassembler.zig"); @@ -1188,7 +1189,7 @@ pub const VM = struct { if (value.isInteger()) { self.push(Value.fromInteger(-%value.integer())); } else { - self.push(Value.fromFloat(-value.double())); + self.push(Value.fromDouble(-value.double())); } const next_full_instruction: u32 = self.readInstruction(); @@ -2103,7 +2104,7 @@ pub const VM = struct { } fn OP_EXPORT(self: *Self, _: *CallFrame, _: u32, _: Chunk.OpCode, arg: u24) void { - self.push(Value.fromInteger(@as(i32, @intCast(arg)))); + self.push(Value.fromInteger(@as(v.Integer, @intCast(arg)))); // Ends program, so we don't call dispatch } @@ -3394,7 +3395,7 @@ pub const VM = struct { fn OP_BNOT(self: *Self, _: *CallFrame, _: u32, _: Chunk.OpCode, _: u24) void { const value = self.pop(); - self.push(Value.fromInteger(~(if (value.isInteger()) value.integer() else @as(i32, @intFromFloat(value.double()))))); + self.push(Value.fromInteger(~value.integer())); const next_full_instruction: u32 = self.readInstruction(); @call( @@ -3414,20 +3415,20 @@ pub const VM = struct { const right_value = self.pop(); const left_value = self.pop(); - const left_f: ?f64 = if (left_value.isFloat()) left_value.double() else null; - const left_i: ?i32 = if (left_value.isInteger()) left_value.integer() else null; - const right_f: ?f64 = if (right_value.isFloat()) right_value.double() else null; - const right_i: ?i32 = if (right_value.isInteger()) right_value.integer() else null; + const left_f: ?v.Double = if (left_value.isDouble()) left_value.double() else null; + const left_i: ?v.Integer = if (left_value.isInteger()) left_value.integer() else null; + const right_f: ?v.Double = if (right_value.isDouble()) right_value.double() else null; + const right_i: ?v.Integer = if (right_value.isInteger()) right_value.integer() else null; if (left_f) |lf| { if (right_f) |rf| { self.push(Value.fromBoolean(lf > rf)); } else { - self.push(Value.fromBoolean(lf > @as(f64, @floatFromInt(right_i.?)))); + self.push(Value.fromBoolean(lf > @as(v.Double, @floatFromInt(right_i.?)))); } } else { if (right_f) |rf| { - self.push(Value.fromBoolean(@as(f64, @floatFromInt(left_i.?)) > rf)); + self.push(Value.fromBoolean(@as(v.Double, @floatFromInt(left_i.?)) > rf)); } else { self.push(Value.fromBoolean(left_i.? > right_i.?)); } @@ -3451,20 +3452,20 @@ pub const VM = struct { const right_value = self.pop(); const left_value = self.pop(); - const left_f: ?f64 = if (left_value.isFloat()) left_value.double() else null; - const left_i: ?i32 = if (left_value.isInteger()) left_value.integer() else null; - const right_f: ?f64 = if (right_value.isFloat()) right_value.double() else null; - const right_i: ?i32 = if (right_value.isInteger()) right_value.integer() else null; + const left_f: ?v.Double = if (left_value.isDouble()) left_value.double() else null; + const left_i: ?v.Integer = if (left_value.isInteger()) left_value.integer() else null; + const right_f: ?v.Double = if (right_value.isDouble()) right_value.double() else null; + const right_i: ?v.Integer = if (right_value.isInteger()) right_value.integer() else null; if (left_f) |lf| { if (right_f) |rf| { self.push(Value.fromBoolean(lf < rf)); } else { - self.push(Value.fromBoolean(lf < @as(f64, @floatFromInt(right_i.?)))); + self.push(Value.fromBoolean(lf < @as(v.Double, @floatFromInt(right_i.?)))); } } else { if (right_f) |rf| { - self.push(Value.fromBoolean(@as(f64, @floatFromInt(left_i.?)) < rf)); + self.push(Value.fromBoolean(@as(v.Double, @floatFromInt(left_i.?)) < rf)); } else { self.push(Value.fromBoolean(left_i.? < right_i.?)); } @@ -3615,7 +3616,7 @@ pub const VM = struct { const right = self.pop().double(); const left = self.pop().double(); - self.push(Value.fromFloat(left + right)); + self.push(Value.fromDouble(left + right)); const next_full_instruction: u32 = self.readInstruction(); @call( @@ -3635,13 +3636,13 @@ pub const VM = struct { const right: Value = self.pop(); const left: Value = self.pop(); - const right_f: ?f64 = if (right.isFloat()) right.double() else null; - const left_f: ?f64 = if (left.isFloat()) left.double() else null; - const right_i: ?i32 = if (right.isInteger()) right.integer() else null; - const left_i: ?i32 = if (left.isInteger()) left.integer() else null; + const right_f: ?v.Double = if (right.isDouble()) right.double() else null; + const left_f: ?v.Double = if (left.isDouble()) left.double() else null; + const right_i: ?v.Integer = if (right.isInteger()) right.integer() else null; + const left_i: ?v.Integer = if (left.isInteger()) left.integer() else null; if (right_f != null or left_f != null) { - self.push(Value.fromFloat((left_f orelse @as(f64, @floatFromInt(left_i.?))) - (right_f orelse @as(f64, @floatFromInt(right_i.?))))); + self.push(Value.fromDouble((left_f orelse @as(v.Double, @floatFromInt(left_i.?))) - (right_f orelse @as(v.Double, @floatFromInt(right_i.?))))); } else { self.push(Value.fromInteger(left_i.? -% right_i.?)); } @@ -3664,13 +3665,13 @@ pub const VM = struct { const right: Value = self.pop(); const left: Value = self.pop(); - const right_f: ?f64 = if (right.isFloat()) right.double() else null; - const left_f: ?f64 = if (left.isFloat()) left.double() else null; - const right_i: ?i32 = if (right.isInteger()) right.integer() else null; - const left_i: ?i32 = if (left.isInteger()) left.integer() else null; + const right_f: ?v.Double = if (right.isDouble()) right.double() else null; + const left_f: ?v.Double = if (left.isDouble()) left.double() else null; + const right_i: ?v.Integer = if (right.isInteger()) right.integer() else null; + const left_i: ?v.Integer = if (left.isInteger()) left.integer() else null; if (right_f != null or left_f != null) { - self.push(Value.fromFloat((left_f orelse @as(f64, @floatFromInt(left_i.?))) * (right_f orelse @as(f64, @floatFromInt(right_i.?))))); + self.push(Value.fromDouble((left_f orelse @as(v.Double, @floatFromInt(left_i.?))) * (right_f orelse @as(v.Double, @floatFromInt(right_i.?))))); } else { self.push(Value.fromInteger(left_i.? *% right_i.?)); } @@ -3693,15 +3694,15 @@ pub const VM = struct { const right: Value = self.pop(); const left: Value = self.pop(); - const right_f: ?f64 = if (right.isFloat()) right.double() else null; - const left_f: ?f64 = if (left.isFloat()) left.double() else null; - const right_i: ?i32 = if (right.isInteger()) right.integer() else null; - const left_i: ?i32 = if (left.isInteger()) left.integer() else null; + const right_f: ?v.Double = if (right.isDouble()) right.double() else null; + const left_f: ?v.Double = if (left.isDouble()) left.double() else null; + const right_i: ?v.Integer = if (right.isInteger()) right.integer() else null; + const left_i: ?v.Integer = if (left.isInteger()) left.integer() else null; if (left_f != null or right_f != null) { self.push( - Value.fromFloat( - (left_f orelse @as(f64, @floatFromInt(left_i.?))) / (right_f orelse @as(f64, @floatFromInt(right_i.?))), + Value.fromDouble( + (left_f orelse @as(v.Double, @floatFromInt(left_i.?))) / (right_f orelse @as(v.Double, @floatFromInt(right_i.?))), ), ); } else { @@ -3728,17 +3729,17 @@ pub const VM = struct { const right: Value = self.pop(); const left: Value = self.pop(); - const right_f: ?f64 = if (right.isFloat()) right.double() else null; - const left_f: ?f64 = if (left.isFloat()) left.double() else null; - const right_i: ?i32 = if (right.isInteger()) right.integer() else null; - const left_i: ?i32 = if (left.isInteger()) left.integer() else null; + const right_f: ?v.Double = if (right.isDouble()) right.double() else null; + const left_f: ?v.Double = if (left.isDouble()) left.double() else null; + const right_i: ?v.Integer = if (right.isInteger()) right.integer() else null; + const left_i: ?v.Integer = if (left.isInteger()) left.integer() else null; if (right_f != null or left_f != null) { self.push( - Value.fromFloat( + Value.fromDouble( @mod( - (left_f orelse @as(f64, @floatFromInt(left_i.?))), - (right_f orelse @as(f64, @floatFromInt(right_i.?))), + (left_f orelse @as(v.Double, @floatFromInt(left_i.?))), + (right_f orelse @as(v.Double, @floatFromInt(right_i.?))), ), ), ); @@ -3768,12 +3769,7 @@ pub const VM = struct { const right: Value = self.pop(); const left: Value = self.pop(); - const right_f: ?f64 = if (right.isFloat()) right.double() else null; - const left_f: ?f64 = if (left.isFloat()) left.double() else null; - const right_i: ?i32 = if (right.isInteger()) right.integer() else null; - const left_i: ?i32 = if (left.isInteger()) left.integer() else null; - - self.push(Value.fromInteger((left_i orelse @as(i32, @intFromFloat(left_f.?))) & (right_i orelse @as(i32, @intFromFloat(right_f.?))))); + self.push(Value.fromInteger(left.integer() & right.integer())); const next_full_instruction: u32 = self.readInstruction(); @call( @@ -3793,12 +3789,7 @@ pub const VM = struct { const right: Value = self.pop(); const left: Value = self.pop(); - const right_f: ?f64 = if (right.isFloat()) right.double() else null; - const left_f: ?f64 = if (left.isFloat()) left.double() else null; - const right_i: ?i32 = if (right.isInteger()) right.integer() else null; - const left_i: ?i32 = if (left.isInteger()) left.integer() else null; - - self.push(Value.fromInteger((left_i orelse @as(i32, @intFromFloat(left_f.?))) | (right_i orelse @as(i32, @intFromFloat(right_f.?))))); + self.push(Value.fromInteger(left.integer() | right.integer())); const next_full_instruction: u32 = self.readInstruction(); @call( @@ -3818,11 +3809,7 @@ pub const VM = struct { const right: Value = self.pop(); const left: Value = self.pop(); - const right_f: ?f64 = if (right.isFloat()) right.double() else null; - const left_f: ?f64 = if (left.isFloat()) left.double() else null; - const right_i: ?i32 = if (right.isInteger()) right.integer() else null; - const left_i: ?i32 = if (left.isInteger()) left.integer() else null; - self.push(Value.fromInteger((left_i orelse @as(i32, @intFromFloat(left_f.?))) ^ (right_i orelse @as(i32, @intFromFloat(right_f.?))))); + self.push(Value.fromInteger(left.integer() ^ right.integer())); const next_full_instruction: u32 = self.readInstruction(); @call( @@ -3839,26 +3826,20 @@ pub const VM = struct { } fn OP_SHL(self: *Self, _: *CallFrame, _: u32, _: Chunk.OpCode, _: u24) void { - const right: Value = self.pop(); - const left: Value = self.pop(); - - const right_f: ?f64 = if (right.isFloat()) right.double() else null; - const left_f: ?f64 = if (left.isFloat()) left.double() else null; - const right_i: ?i32 = if (right.isInteger()) right.integer() else null; - const left_i: ?i32 = if (left.isInteger()) left.integer() else null; - const b: i32 = right_i orelse @intFromFloat(right_f.?); + const right = self.pop().integer(); + const left = self.pop().integer(); - if (b < 0) { - if (b * -1 > std.math.maxInt(u5)) { + if (right < 0) { + if (right * -1 > std.math.maxInt(u5)) { self.push(Value.fromInteger(0)); } else { - self.push(Value.fromInteger((left_i orelse @as(i32, @intFromFloat(left_f.?))) >> @as(u5, @truncate(@as(u64, @intCast(b * -1)))))); + self.push(Value.fromInteger(left >> @intCast(right * -1))); } } else { - if (b > std.math.maxInt(u5)) { + if (right > std.math.maxInt(u5)) { self.push(Value.fromInteger(0)); } else { - self.push(Value.fromInteger((left_i orelse @as(i32, @intFromFloat(left_f.?))) << @as(u5, @truncate(@as(u64, @intCast(b)))))); + self.push(Value.fromInteger(left << @as(u5, @truncate(@as(u64, @intCast(right)))))); } } @@ -3877,26 +3858,20 @@ pub const VM = struct { } fn OP_SHR(self: *Self, _: *CallFrame, _: u32, _: Chunk.OpCode, _: u24) void { - const right: Value = self.pop(); - const left: Value = self.pop(); - - const right_f: ?f64 = if (right.isFloat()) right.double() else null; - const left_f: ?f64 = if (left.isFloat()) left.double() else null; - const right_i: ?i32 = if (right.isInteger()) right.integer() else null; - const left_i: ?i32 = if (left.isInteger()) left.integer() else null; - const b: i32 = right_i orelse @intFromFloat(right_f.?); + const right = self.pop().integer(); + const left = self.pop().integer(); - if (b < 0) { - if (b * -1 > std.math.maxInt(u5)) { + if (right < 0) { + if (right * -1 > std.math.maxInt(u5)) { self.push(Value.fromInteger(0)); } else { - self.push(Value.fromInteger((left_i orelse @as(i32, @intFromFloat(left_f.?))) << @as(u5, @truncate(@as(u64, @intCast(b * -1)))))); + self.push(Value.fromInteger(left << @as(u5, @truncate(@as(u64, @intCast(right * -1)))))); } } else { - if (b > std.math.maxInt(u5)) { + if (right > std.math.maxInt(u5)) { self.push(Value.fromInteger(0)); } else { - self.push(Value.fromInteger((left_i orelse @as(i32, @intFromFloat(left_f.?))) >> @as(u5, @truncate(@as(u64, @intCast(b)))))); + self.push(Value.fromInteger(left >> @as(u5, @truncate(@as(u64, @intCast(right)))))); } } @@ -4303,7 +4278,7 @@ pub const VM = struct { .{ @tagName(self.current_ast.nodes.items(.tag)[node]), self.currentFrame().?.closure.function.type_def.resolved_type.?.Function.name.string, - @as(f64, @floatFromInt(timer.read())) / 1000000, + @as(v.Double, @floatFromInt(timer.read())) / 1000000, }, ); } @@ -4650,7 +4625,7 @@ pub const VM = struct { "Compiled function `{s}` in {d} ms\n", .{ closure.function.type_def.resolved_type.?.Function.name.string, - @as(f64, @floatFromInt(timer.read())) / 1000000, + @as(v.Double, @floatFromInt(timer.read())) / 1000000, }, ); } diff --git a/tests/039-buffer.buzz b/tests/039-buffer.buzz index 0974eb7c..26930f08 100644 --- a/tests/039-buffer.buzz +++ b/tests/039-buffer.buzz @@ -10,7 +10,7 @@ test "Reading and writing in a buffer" { buffer.writeBoolean(true); final expected = [ - 11, 0, 0, 0, // "hello world".len() + 11, 0, 0, 0, 0, 0, // "hello world".len() 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, // "hello world" 158, 239, 167, 198, 75, 89, 147, 64, // 1238.324 1, // true @@ -24,7 +24,8 @@ test "Reading and writing in a buffer" { final len = buffer.readInt() ?? -1; std\assert(len == 11, message: "could read number"); - std\assert(buffer.read(len) == "hello world", message: "could read n bytes"); + final res = buffer.read(len); + std\assert(res == "hello world", message: "could read n bytes got `{res}`"); std\assert(buffer.readDouble() == 1238.324, message: "could read double"); std\assert(buffer.readBoolean() == true, message: "could read boolean"); diff --git a/tests/040-bitwise.buzz b/tests/040-bitwise.buzz index 67a18a75..5cee4cac 100644 --- a/tests/040-bitwise.buzz +++ b/tests/040-bitwise.buzz @@ -1,10 +1,22 @@ import "std"; -test "Bitwise" { +test "Bitwise (constant folded)" { std\assert(15 << 3 == 120, message: "<<"); std\assert(15 >> 3 == 1, message: ">>"); std\assert(15 ^ 3 == 12, message: "^"); std\assert(15 | 3 == 15, message: "\\"); std\assert(~15 == -16, message: "~"); std\assert(12 & 23 == 4, message: "&"); -} \ No newline at end of file +} + +test "Bitwise" { + final a = 15; + final b = 12; + + std\assert(a << 3 == 120, message: "<<"); + std\assert(a >> 3 == 1, message: ">>"); + std\assert(a ^ 3 == 12, message: "^"); + std\assert(a | 3 == a, message: "\\"); + std\assert(~a == -16, message: "~"); + std\assert(b & 23 == 4, message: "&"); +}