add objects and string comparison
This commit is contained in:
parent
44c27f43b7
commit
9ac5fccc2b
4 changed files with 60 additions and 3 deletions
|
@ -4,6 +4,7 @@ const vm = @import("vm.zig");
|
|||
const chunks = @import("chunk.zig");
|
||||
const tokens = @import("token.zig");
|
||||
const values = @import("value.zig");
|
||||
const objects = @import("object.zig");
|
||||
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Scanner = scanner.Scanner;
|
||||
|
@ -89,7 +90,7 @@ var rules = []ParseRule{
|
|||
ParseRule{ .infix = Compiler.binary, .precedence = .Comparison },
|
||||
|
||||
ParseRule{},
|
||||
ParseRule{},
|
||||
ParseRule{ .prefix = Compiler.string },
|
||||
ParseRule{ .prefix = Compiler.number },
|
||||
ParseRule{ .precedence = .And },
|
||||
ParseRule{},
|
||||
|
@ -228,6 +229,13 @@ pub const Compiler = struct {
|
|||
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.
|
||||
fn unary(self: *Compiler) !void {
|
||||
var ttype = self.parser.previous.ttype;
|
||||
|
|
34
src/object.zig
Normal file
34
src/object.zig
Normal 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,
|
||||
}
|
||||
}
|
|
@ -1,19 +1,20 @@
|
|||
const std = @import("std");
|
||||
const objects = @import("object.zig");
|
||||
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
// NOTE: right now, only numbers.
|
||||
|
||||
pub const ValueType = enum(u8) {
|
||||
Bool,
|
||||
Nil,
|
||||
Number,
|
||||
Object,
|
||||
};
|
||||
|
||||
pub const ValueValue = union(ValueType) {
|
||||
Bool: bool,
|
||||
Nil: void,
|
||||
Number: f64,
|
||||
Object: *objects.Object,
|
||||
};
|
||||
|
||||
pub const Value = struct {
|
||||
|
@ -34,11 +35,20 @@ pub fn NumberVal(val: f64) Value {
|
|||
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 {
|
||||
switch (value.as) {
|
||||
.Nil => try stdout.print("nil"),
|
||||
.Bool => try stdout.print("{}", value.as.Bool),
|
||||
.Number => try stdout.print("{}", value.as.Number),
|
||||
.Object => try objects.printObject(stdout, value.as.Object.*),
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,11 @@ fn valuesEqual(a: value.Value, b: value.Value) bool {
|
|||
.Nil => return true,
|
||||
.Bool => return a.as.Bool == b.as.Bool,
|
||||
.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;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue