feat: formatting strings at runtime
This commit is contained in:
parent
6924e929d8
commit
d2cd7fa888
10 changed files with 211 additions and 34 deletions
|
|
@ -31,6 +31,7 @@ stack: []Value = &.{},
|
|||
call_stack: []CallFrame = &.{},
|
||||
code_chunks: std.ArrayListUnmanaged(*Object.Code) = .empty,
|
||||
/// Linked list of all tracked runtime objects.
|
||||
/// We don't currently have a garbage collector, though this will necessary.
|
||||
gc_objects: std.SinglyLinkedList = .{},
|
||||
/// Global constants pool.
|
||||
constants_pool: []const Value = &.{},
|
||||
|
|
@ -110,6 +111,9 @@ pub const Opcode = enum(u8) {
|
|||
br_table,
|
||||
br_dispatch,
|
||||
br_select_index,
|
||||
string_builder,
|
||||
string_append,
|
||||
string_freeze,
|
||||
_,
|
||||
};
|
||||
|
||||
|
|
@ -138,6 +142,13 @@ pub const Value = union(enum) {
|
|||
};
|
||||
}
|
||||
|
||||
pub fn castObject(v: Value, comptime T: type) *T {
|
||||
return switch (v) {
|
||||
.object => |object| return @ptrCast(object),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn isNumeric(v: Value) bool {
|
||||
return v == .int or v == .float;
|
||||
}
|
||||
|
|
@ -230,24 +241,20 @@ pub const Value = union(enum) {
|
|||
pub fn eql(lhs: Value, rhs: Value) bool {
|
||||
return switch (lhs) {
|
||||
.nil => rhs == .nil,
|
||||
|
||||
.bool => |l| switch (rhs) {
|
||||
.bool => |r| l == r,
|
||||
else => false,
|
||||
},
|
||||
|
||||
.int => |l| switch (rhs) {
|
||||
.int => |r| l == r,
|
||||
.float => |r| @as(f64, @floatFromInt(l)) == r,
|
||||
else => false,
|
||||
},
|
||||
|
||||
.float => |l| switch (rhs) {
|
||||
.int => |r| l == @as(f64, @floatFromInt(r)),
|
||||
.float => |r| l == r,
|
||||
else => false,
|
||||
},
|
||||
|
||||
.object => |lobj| switch (rhs) {
|
||||
.object => |robj| Object.eql(lobj, robj),
|
||||
else => false,
|
||||
|
|
@ -771,6 +778,32 @@ fn step(vm: *Story, variables: *VariablesState) !StepSignal {
|
|||
return error.InvalidArgument;
|
||||
}
|
||||
},
|
||||
.string_builder => {
|
||||
const builder_object = try Object.StringBuilder.create(vm);
|
||||
try pushStack(vm, .{ .object = &builder_object.base });
|
||||
frame.ip += 1;
|
||||
},
|
||||
.string_append => {
|
||||
if (popStack(vm)) |value| {
|
||||
if (peekStack(vm, 0)) |builder| {
|
||||
const string_builder = builder.castObject(Object.StringBuilder);
|
||||
try string_builder.append(value);
|
||||
frame.ip += 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return error.InvalidArgument;
|
||||
},
|
||||
.string_freeze => {
|
||||
if (popStack(vm)) |value| {
|
||||
const string_builder = value.castObject(Object.StringBuilder);
|
||||
const frozen = try string_builder.freeze(vm);
|
||||
try pushStack(vm, .{ .object = &frozen.base });
|
||||
frame.ip += 1;
|
||||
continue;
|
||||
}
|
||||
return error.InvalidArgument;
|
||||
},
|
||||
else => return error.InvalidInstruction,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue