vm: add string concatenation

- compiler: fix string creation
This commit is contained in:
Luna 2019-06-02 14:18:01 -03:00
parent 9ac5fccc2b
commit 38715af200
3 changed files with 35 additions and 5 deletions

View file

@ -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],
))); )));
} }

View file

@ -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 {

View file

@ -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));