Compare commits

...

2 Commits

Author SHA1 Message Date
kayomn eca2cfffb8 Fix off-by-one if statement jump error
continuous-integration/drone/pr Build is passing Details
continuous-integration/drone/push Build is passing Details
2023-08-21 23:51:49 +01:00
kayomn 56d9899ac2 Work around miscompilation 2023-08-21 12:27:02 +01:00
2 changed files with 23 additions and 10 deletions

View File

@ -272,16 +272,15 @@ pub const RuntimeEnv = struct {
try self.compile_expression(chunk, @"if".condition_expression); try self.compile_expression(chunk, @"if".condition_expression);
try chunk.opcodes.push_one(.{.jf = 0}); try chunk.opcodes.push_one(.{.jf = 0});
const jump_opcode = &chunk.opcodes.values[chunk.opcodes.values.len - 1]; const jump_opcode_index = chunk.opcodes.values.len - 1;
for (@"if".block_statements.values) |block_statement| { for (@"if".block_statements.values) |block_statement| {
try self.compile_statement(chunk, block_statement); try self.compile_statement(chunk, block_statement);
} }
coral.debug.assert(jump_opcode.* == .jf);
coral.debug.assert(chunk.opcodes.values.len < coral.math.max_int(@typeInfo(u32).Int)); coral.debug.assert(chunk.opcodes.values.len < coral.math.max_int(@typeInfo(u32).Int));
jump_opcode.jf = @intCast(chunk.opcodes.values.len); chunk.opcodes.values[jump_opcode_index].jf = @intCast(chunk.opcodes.values.len - 1);
}, },
.expression => |expression| try self.compile_expression(chunk, expression), .expression => |expression| try self.compile_expression(chunk, expression),
@ -422,15 +421,11 @@ pub const RuntimeEnv = struct {
}, },
.object_get => { .object_get => {
const index = (try self.pop_local()) orelse { const index = try self.env.expect(try self.pop_local());
return self.env.raise(error.TypeMismatch, "nil is not a valid index");
};
defer self.env.discard(index); defer self.env.discard(index);
const indexable = (try self.pop_local()) orelse { const indexable = try self.env.expect(try self.pop_local());
return self.env.raise(error.TypeMismatch, "nil is not a valid indexable");
};
defer self.env.discard(indexable); defer self.env.discard(indexable);
@ -1554,6 +1549,21 @@ pub const RuntimeRef = opaque {
.dynamic => true, .dynamic => true,
}; };
} }
pub fn typename(self: *const RuntimeRef) []const coral.io.Byte {
return switch (self.object().payload) {
.false => "false",
.true => "true",
.float => "float",
.fixed => "fixed",
.symbol => "symbol",
.vector2 => "vector2",
.vector3 => "vector3",
.syscall => "syscall",
.string => "string",
.dynamic => "dynamic",
};
}
}; };
pub const Syscall = fn (env: *RuntimeEnv) RuntimeError!?*RuntimeRef; pub const Syscall = fn (env: *RuntimeEnv) RuntimeError!?*RuntimeRef;

View File

@ -42,10 +42,13 @@ pub const BinaryOperator = enum {
"`"); "`");
} }
// TODO: Remove once Zig has fixed struct self-reassignment.
const unnecessary_temp = try coral.io.allocate_one(allocator, expression);
expression = .{ expression = .{
.binary_operation = .{ .binary_operation = .{
.operator = operator, .operator = operator,
.lhs_expression = try coral.io.allocate_one(allocator, expression), .lhs_expression = unnecessary_temp,
.rhs_expression = try coral.io.allocate_one(allocator, try build_next(self)), .rhs_expression = try coral.io.allocate_one(allocator, try build_next(self)),
}, },
}; };