feat: code generation for conditional and switch statements
This commit is contained in:
parent
889f678dd8
commit
d6ff3a40bd
7 changed files with 476 additions and 59 deletions
|
|
@ -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),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue