add objects and string comparison

This commit is contained in:
Luna 2019-06-02 14:01:54 -03:00
parent 44c27f43b7
commit 9ac5fccc2b
4 changed files with 60 additions and 3 deletions

View file

@ -4,6 +4,7 @@ const vm = @import("vm.zig");
const chunks = @import("chunk.zig"); const chunks = @import("chunk.zig");
const tokens = @import("token.zig"); const tokens = @import("token.zig");
const values = @import("value.zig"); const values = @import("value.zig");
const objects = @import("object.zig");
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const Scanner = scanner.Scanner; const Scanner = scanner.Scanner;
@ -89,7 +90,7 @@ var rules = []ParseRule{
ParseRule{ .infix = Compiler.binary, .precedence = .Comparison }, ParseRule{ .infix = Compiler.binary, .precedence = .Comparison },
ParseRule{}, ParseRule{},
ParseRule{}, ParseRule{ .prefix = Compiler.string },
ParseRule{ .prefix = Compiler.number }, ParseRule{ .prefix = Compiler.number },
ParseRule{ .precedence = .And }, ParseRule{ .precedence = .And },
ParseRule{}, ParseRule{},
@ -228,6 +229,13 @@ pub const Compiler = struct {
try self.emitConstant(values.NumberVal(value)); try self.emitConstant(values.NumberVal(value));
} }
fn string(self: *Compiler) !void {
try self.emitConstant(values.ObjVal(try objects.copyString(
self.allocator,
self.parser.previous.lexeme,
)));
}
/// Emits bytecode for a given unary. /// Emits bytecode for a given unary.
fn unary(self: *Compiler) !void { fn unary(self: *Compiler) !void {
var ttype = self.parser.previous.ttype; var ttype = self.parser.previous.ttype;

34
src/object.zig Normal file
View file

@ -0,0 +1,34 @@
const std = @import("std");
const Allocator = std.mem.Allocator;
pub const ObjType = enum {
String,
};
pub const ObjValue = struct {
String: []u8,
};
pub const Object = struct {
otype: ObjType,
value: ObjValue,
};
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 obj;
}
pub fn printObject(stdout: var, obj: Object) !void {
switch (obj.otype) {
.String => try stdout.print("{}", obj.value.String),
else => unreachable,
}
}

View file

@ -1,19 +1,20 @@
const std = @import("std"); const std = @import("std");
const objects = @import("object.zig");
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
// NOTE: right now, only numbers.
pub const ValueType = enum(u8) { pub const ValueType = enum(u8) {
Bool, Bool,
Nil, Nil,
Number, Number,
Object,
}; };
pub const ValueValue = union(ValueType) { pub const ValueValue = union(ValueType) {
Bool: bool, Bool: bool,
Nil: void, Nil: void,
Number: f64, Number: f64,
Object: *objects.Object,
}; };
pub const Value = struct { pub const Value = struct {
@ -34,11 +35,20 @@ pub fn NumberVal(val: f64) Value {
return Value{ .vtype = .Number, .as = ValueValue{ .Number = val } }; return Value{ .vtype = .Number, .as = ValueValue{ .Number = val } };
} }
pub fn ObjVal(val: *objects.Object) Value {
return Value{ .vtype = .Object, .as = ValueValue{ .Object = val } };
}
pub fn isObjType(val: Value, otype: objects.ObjType) bool {
return val.vtype == .Object and val.as.Object.otype == otype;
}
pub fn printValue(stdout: var, value: Value) !void { pub fn printValue(stdout: var, value: Value) !void {
switch (value.as) { switch (value.as) {
.Nil => try stdout.print("nil"), .Nil => try stdout.print("nil"),
.Bool => try stdout.print("{}", value.as.Bool), .Bool => try stdout.print("{}", value.as.Bool),
.Number => try stdout.print("{}", value.as.Number), .Number => try stdout.print("{}", value.as.Number),
.Object => try objects.printObject(stdout, value.as.Object.*),
else => unreachable, else => unreachable,
} }
} }

View file

@ -27,6 +27,11 @@ fn valuesEqual(a: value.Value, b: value.Value) bool {
.Nil => return true, .Nil => return true,
.Bool => return a.as.Bool == b.as.Bool, .Bool => return a.as.Bool == b.as.Bool,
.Number => return a.as.Number == b.as.Number, .Number => return a.as.Number == b.as.Number,
.Object => blk: {
var aStr = a.as.Object.value.String;
var bStr = b.as.Object.value.String;
return std.mem.compare(u8, aStr, bStr) == .Equal;
},
} }
} }