forked from luna/jorts
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 {
|
fn string(self: *Compiler) !void {
|
||||||
|
const lexeme_len = self.parser.previous.lexeme.len;
|
||||||
try self.emitConstant(values.ObjVal(try objects.copyString(
|
try self.emitConstant(values.ObjVal(try objects.copyString(
|
||||||
self.allocator,
|
self.allocator,
|
||||||
self.parser.previous.lexeme,
|
self.parser.previous.lexeme[1 .. lexeme_len - 1],
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,15 +15,23 @@ pub const Object = struct {
|
||||||
value: ObjValue,
|
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 {
|
pub fn copyString(allocator: *Allocator, data: []const u8) !*Object {
|
||||||
var str = try allocator.alloc(u8, data.len);
|
var str = try allocator.alloc(u8, data.len);
|
||||||
std.mem.copy(u8, str, data);
|
std.mem.copy(u8, str, data);
|
||||||
|
|
||||||
var obj = try allocator.create(Object);
|
return try createString(allocator, str);
|
||||||
obj.otype = ObjType.String;
|
}
|
||||||
obj.value = ObjValue{ .String = 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 {
|
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 value = @import("value.zig");
|
||||||
const values = value;
|
const values = value;
|
||||||
const compiler = @import("compiler.zig");
|
const compiler = @import("compiler.zig");
|
||||||
|
const objects = @import("object.zig");
|
||||||
|
|
||||||
const Chunk = chunk.Chunk;
|
const Chunk = chunk.Chunk;
|
||||||
const Value = value.Value;
|
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 {
|
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 b = try self.popNum();
|
||||||
var a = try self.popNum();
|
var a = try self.popNum();
|
||||||
try self.push(values.NumberVal(a + b));
|
try self.push(values.NumberVal(a + b));
|
||||||
|
|
Loading…
Reference in a new issue