vm: add string concatenation
- compiler: fix string creation
This commit is contained in:
parent
9ac5fccc2b
commit
38715af200
3 changed files with 35 additions and 5 deletions
|
@ -230,9 +230,10 @@ pub const Compiler = struct {
|
|||
}
|
||||
|
||||
fn string(self: *Compiler) !void {
|
||||
const lexeme_len = self.parser.previous.lexeme.len;
|
||||
try self.emitConstant(values.ObjVal(try objects.copyString(
|
||||
self.allocator,
|
||||
self.parser.previous.lexeme,
|
||||
self.parser.previous.lexeme[1 .. lexeme_len - 1],
|
||||
)));
|
||||
}
|
||||
|
||||
|
|
|
@ -15,15 +15,23 @@ pub const Object = struct {
|
|||
value: ObjValue,
|
||||
};
|
||||
|
||||
fn createString(allocator: *Allocator, data: []u8) !*Object {
|
||||
var obj = try allocator.create(Object);
|
||||
obj.otype = ObjType.String;
|
||||
obj.value = ObjValue{ .String = data };
|
||||
return obj;
|
||||
}
|
||||
|
||||
pub fn copyString(allocator: *Allocator, data: []const u8) !*Object {
|
||||
var str = try allocator.alloc(u8, data.len);
|
||||
std.mem.copy(u8, str, data);
|
||||
|
||||
var obj = try allocator.create(Object);
|
||||
obj.otype = ObjType.String;
|
||||
obj.value = ObjValue{ .String = str };
|
||||
return try createString(allocator, str);
|
||||
}
|
||||
|
||||
return obj;
|
||||
/// Assumes it can take ownership of the given data.
|
||||
pub fn takeString(allocator: *Allocator, data: []u8) !*Object {
|
||||
return try createString(allocator, data);
|
||||
}
|
||||
|
||||
pub fn printObject(stdout: var, obj: Object) !void {
|
||||
|
|
21
src/vm.zig
21
src/vm.zig
|
@ -3,6 +3,7 @@ const chunk = @import("chunk.zig");
|
|||
const value = @import("value.zig");
|
||||
const values = value;
|
||||
const compiler = @import("compiler.zig");
|
||||
const objects = @import("object.zig");
|
||||
|
||||
const Chunk = chunk.Chunk;
|
||||
const Value = value.Value;
|
||||
|
@ -124,7 +125,27 @@ pub const VM = struct {
|
|||
}
|
||||
}
|
||||
|
||||
fn concatenateStrings(self: *VM) !void {
|
||||
var b = self.pop().as.Object.value.String;
|
||||
var a = self.pop().as.Object.value.String;
|
||||
|
||||
var res_str = try std.mem.join(
|
||||
self.allocator,
|
||||
"",
|
||||
[][]u8{ a, b },
|
||||
);
|
||||
|
||||
var val = values.ObjVal(try objects.takeString(self.allocator, res_str));
|
||||
try self.push(val);
|
||||
}
|
||||
|
||||
fn doAdd(self: *VM) !void {
|
||||
if (values.isObjType(self.peek(0), .String) and
|
||||
values.isObjType(self.peek(1), .String))
|
||||
{
|
||||
return try self.concatenateStrings();
|
||||
}
|
||||
|
||||
var b = try self.popNum();
|
||||
var a = try self.popNum();
|
||||
try self.push(values.NumberVal(a + b));
|
||||
|
|
Loading…
Reference in a new issue