feat: folding logical operations
This commit is contained in:
parent
92e8bcd866
commit
2260ccda25
24 changed files with 310 additions and 151 deletions
|
|
@ -46,6 +46,15 @@ pub const Value = union(enum) {
|
|||
return v == .int or v == .float;
|
||||
}
|
||||
|
||||
pub fn coerce(v: Value) ?Value {
|
||||
return switch (v) {
|
||||
.int => v,
|
||||
.float => v,
|
||||
.bool => |boolean| .{ .int = if (boolean) 1 else 0 },
|
||||
else => null,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn isTruthy(v: Value) bool {
|
||||
return switch (v) {
|
||||
//.nil => false,
|
||||
|
|
@ -69,8 +78,11 @@ pub const Value = union(enum) {
|
|||
}
|
||||
|
||||
pub fn arith(lhs: Value, rhs: Value, op: Opcode, story: *Story) !Value {
|
||||
if (lhs.isNumeric() and rhs.isNumeric())
|
||||
return numericArith(lhs, rhs, op);
|
||||
if (lhs.coerce()) |l| {
|
||||
if (rhs.coerce()) |r| {
|
||||
return numericArith(l, r, op);
|
||||
}
|
||||
}
|
||||
if (op == .add) {
|
||||
if (lhs == .object and lhs.object.tag == .string)
|
||||
return concat(lhs, rhs, story);
|
||||
|
|
@ -177,6 +189,36 @@ pub const Value = union(enum) {
|
|||
.object => return error.TypeError,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn format(value: Value, writer: *std.Io.Writer) error{WriteFailed}!void {
|
||||
switch (value) {
|
||||
.bool => |boolean| try writer.writeAll(if (boolean) "true" else "false"),
|
||||
.int => |int| try writer.print("{d}", .{int}),
|
||||
.float => |float| {
|
||||
var buf: [64]u8 = undefined;
|
||||
if (std.math.isNan(float)) return writer.writeAll("NaN");
|
||||
if (std.math.isInf(float)) return writer.writeAll(if (float > 0) "Inf" else "-Inf");
|
||||
|
||||
var str = std.fmt.bufPrint(&buf, "{d:.7}", .{float}) catch |err| switch (err) {
|
||||
error.NoSpaceLeft => unreachable,
|
||||
else => |e| return e,
|
||||
};
|
||||
if (std.mem.indexOfScalar(u8, str, '.')) |dot| {
|
||||
var end = str.len;
|
||||
while (end > dot + 2 and str[end - 1] == '0') end -= 1;
|
||||
str = str[0..end];
|
||||
}
|
||||
try writer.writeAll(str);
|
||||
},
|
||||
.object => |object| switch (object.tag) {
|
||||
.string => {
|
||||
const typed: *const Object.String = @ptrCast(object);
|
||||
try writer.writeAll(typed.toSlice());
|
||||
},
|
||||
else => try writer.print("<{s} {*}>", .{ object.tag.tagBytes(), object }),
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub const CallFrame = struct {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue