add constant values to the virtual machine

This commit is contained in:
Luna 2019-06-01 01:46:01 -03:00
parent c4401dc8cf
commit ba78b39300
3 changed files with 88 additions and 5 deletions

View file

@ -1,10 +1,12 @@
const std = @import("std");
const value = @import("value.zig");
const Allocator = std.mem.Allocator;
// hack. ugly hack. zig has compiler crash.
const AllOpcodes = struct {
pub Return: u8 = 0,
pub Constant: u8 = 0,
pub Return: u8 = 1,
};
pub const OpCode = AllOpcodes{};
@ -18,31 +20,63 @@ fn simpleInstruction(
return offset + 1;
}
fn constantInstruction(
stdout: var,
comptime name: []const u8,
chunk: *Chunk,
offset: usize,
) !usize {
// get the constant's index in constants slice
var idx = chunk.code[offset + 1];
try stdout.print("\t{}\t{} '", name, idx);
try value.printValue(stdout, chunk.constants.values[idx]);
try stdout.print("'\n");
return offset + 2;
}
pub const Chunk = struct {
count: usize,
lines: []usize,
code: []u8,
allocator: *Allocator,
constants: value.ValueList,
pub fn init(allocator: *Allocator) !Chunk {
return Chunk{
.count = 0,
.allocator = allocator,
.code = try allocator.alloc(u8, 0),
.lines = try allocator.alloc(usize, 0),
.constants = try value.ValueList.init(allocator),
};
}
pub fn write(self: *Chunk, byte: u8) !void {
pub fn write(self: *Chunk, byte: u8, line: usize) !void {
if (self.code.len < self.count + 1) {
self.code = try self.allocator.realloc(
self.code,
self.count + 1,
);
self.lines = try self.allocator.realloc(
self.lines,
self.count + 1,
);
}
self.code[self.count] = byte;
self.lines[self.count] = line;
self.count += 1;
}
pub fn addConstant(self: *Chunk, val: value.Value) !u8 {
try self.constants.write(val);
return self.constants.count - 1;
}
pub fn disassembleInstruction(
self: *Chunk,
stdout: var,
@ -50,10 +84,18 @@ pub const Chunk = struct {
) !usize {
try stdout.print("{} ", index);
if (index > 0 and self.lines[index] == self.lines[index - 1]) {
try stdout.print(" | ");
} else {
try stdout.print("{} ", self.lines[index]);
}
var instruction = self.code[index];
if (instruction == 0) {
if (instruction == OpCode.Return) {
return try simpleInstruction(stdout, "OP_RETURN", index);
} else if (instruction == OpCode.Constant) {
return try constantInstruction(stdout, "OP_CONSTANT", self, index);
} else {
try stdout.print("Unknown opcode: {}\n", instruction);
return index + 1;
@ -64,7 +106,7 @@ pub const Chunk = struct {
try stdout.print("== {} ==\n", name);
var i: usize = 0;
while (i < self.count) : (i += 1) {
while (i < self.count) {
i = try self.disassembleInstruction(stdout, i);
}
}

View file

@ -113,7 +113,12 @@ pub fn main() !void {
// this crashes zig??? lol
//var opcode_byte: u8 = @enumToInt(chunk.OpCode.Return);
try chk.write(chunk.OpCode.Return);
//try chk.write(chunk.OpCode.Return);
var constant = try chk.addConstant(1.2);
try chk.write(chunk.OpCode.Constant, 123);
try chk.write(constant, 123);
try chk.write(chunk.OpCode.Return, 123);
try chk.disassemble(stdout, "test chunk");
}

36
src/value.zig Normal file
View file

@ -0,0 +1,36 @@
const std = @import("std");
const Allocator = std.mem.Allocator;
// NOTE: right now, only numbers.
pub const Value = f64;
pub fn printValue(stdout: var, value: Value) !void {
try stdout.print("{}", value);
}
pub const ValueList = struct {
count: u8,
values: []Value,
allocator: *Allocator,
pub fn init(allocator: *Allocator) !ValueList {
return ValueList{
.count = 0,
.allocator = allocator,
.values = try allocator.alloc(Value, 0),
};
}
pub fn write(self: *ValueList, value: Value) !void {
if (self.values.len < self.count + 1) {
self.values = try self.allocator.realloc(
self.values,
self.count + 1,
);
}
self.values[self.count] = value;
self.count += 1;
}
};