feat: code generation for conditional and switch statements

This commit is contained in:
Brett Broadhurst 2026-03-03 16:22:35 -07:00
parent 889f678dd8
commit d6ff3a40bd
Failed to generate hash of commit
7 changed files with 476 additions and 59 deletions

View file

@ -50,6 +50,26 @@ pub const Object = struct {
}
}
pub fn cmpEql(story: *Story, lhs: *Object, rhs: *Object) !*Object {
// TODO: This is temporary
if (lhs.tag != .number or lhs.tag != rhs.tag) return error.InvalidComparison;
const result = try Object.Number.performLogic(story, .cmp_eq, @ptrCast(lhs), @ptrCast(rhs));
return @ptrCast(result);
}
pub fn isFalsey(obj: *Object) bool {
switch (obj.tag) {
.number => {
const number: *Object.Number = @ptrCast(obj);
switch (number.data) {
.boolean => |value| return !value,
else => return false,
}
},
else => return false,
}
}
pub const Number = struct {
base: Object,
data: Data,
@ -96,7 +116,7 @@ pub const Object = struct {
.floating => |value| break :v .{ .floating = value },
}
},
else => break :v .{ .integer = 1 },
else => break :v .{ .boolean = true },
};
const obj = Object.Number.create(story, data);
@ -104,6 +124,17 @@ pub const Object = struct {
return obj;
}
fn logicalOp(comptime T: type, op: Story.Opcode, lhs: T, rhs: T) bool {
switch (op) {
.cmp_eq => return lhs == rhs,
.cmp_lt => return lhs < rhs,
.cmp_gt => return lhs > rhs,
.cmp_lte => return lhs <= rhs,
.cmp_gte => return lhs >= rhs,
else => unreachable,
}
}
fn arithmeticOp(comptime T: type, op: Story.Opcode, lhs: T, rhs: T) T {
switch (op) {
.add => return lhs + rhs,
@ -124,6 +155,17 @@ pub const Object = struct {
return object;
}
pub fn performLogic(
story: *Story,
op: Story.Opcode,
lhs: *Object.Number,
rhs: *Object.Number,
) !*Object.Number {
return .create(story, .{
.boolean = logicalOp(i64, op, lhs.data.integer, rhs.data.integer),
});
}
pub fn performArithmetic(
story: *Story,
op: Story.Opcode,
@ -131,17 +173,12 @@ pub const Object = struct {
rhs: *Object.Number,
) !*Object.Number {
if (lhs.data == .floating or rhs.data == .floating) {
const _lhs = try Object.Number.fromObject(story, @ptrCast(lhs));
const _rhs = try Object.Number.fromObject(story, @ptrCast(rhs));
return .create(story, .{
.floating = arithmeticOp(f64, op, _lhs.data.floating, _rhs.data.floating),
.floating = arithmeticOp(f64, op, lhs.data.floating, rhs.data.floating),
});
}
const _lhs = try Object.Number.fromObject(story, @ptrCast(lhs));
const _rhs = try Object.Number.fromObject(story, @ptrCast(rhs));
return .create(story, .{
.integer = arithmeticOp(i64, op, _lhs.data.integer, _rhs.data.integer),
.integer = arithmeticOp(i64, op, lhs.data.integer, rhs.data.integer),
});
}
};