add basic virtual machine code
This commit is contained in:
parent
14fa63e1f6
commit
dae3c259fd
2 changed files with 83 additions and 9 deletions
15
src/main.zig
15
src/main.zig
|
@ -4,6 +4,7 @@ const Allocator = std.mem.Allocator;
|
|||
|
||||
// const Scanner = @import("scanner.zig").Scanner;
|
||||
const chunk = @import("chunk.zig");
|
||||
const vm = @import("vm.zig");
|
||||
|
||||
//const Compiler = @import("compiler.zig").Compiler;
|
||||
|
||||
|
@ -107,7 +108,7 @@ pub fn main() !void {
|
|||
var allocator = &arena.allocator;
|
||||
|
||||
var stdout_file = try std.io.getStdOut();
|
||||
const stdout = &stdout_file.outStream().stream;
|
||||
var stdout = &stdout_file.outStream().stream;
|
||||
|
||||
var chk = try chunk.Chunk.init(allocator);
|
||||
|
||||
|
@ -115,11 +116,13 @@ pub fn main() !void {
|
|||
//var opcode_byte: u8 = @enumToInt(chunk.OpCode.Return);
|
||||
//try chk.write(chunk.OpCode.Return);
|
||||
|
||||
var i: usize = 0;
|
||||
while (i < 260) : (i += 1) {
|
||||
var constant = try chk.writeConstant(1.2, 123);
|
||||
}
|
||||
var constant = try chk.writeConstant(1.2, 123);
|
||||
try chk.write(chunk.OpCode.Return, 123);
|
||||
|
||||
try chk.disassemble(stdout, "test chunk");
|
||||
|
||||
var vmach = vm.VM.init(stdout, &chk);
|
||||
|
||||
std.debug.warn("vm start\n");
|
||||
_ = try vmach.interpret();
|
||||
std.debug.warn("vm end\n");
|
||||
}
|
||||
|
|
77
src/vm.zig
77
src/vm.zig
|
@ -1,7 +1,78 @@
|
|||
const Chunk = @import("chunk.zig");
|
||||
const std = @import("std");
|
||||
const chunk = @import("chunk.zig");
|
||||
const value = @import("value.zig");
|
||||
|
||||
const Chunk = chunk.Chunk;
|
||||
const StdOut = *std.io.OutStream(std.fs.File.WriteError);
|
||||
|
||||
pub const InterpretResult = enum {
|
||||
Ok,
|
||||
CompileError,
|
||||
RuntimeError,
|
||||
};
|
||||
|
||||
pub const VM = struct {
|
||||
chunk: *Chunk,
|
||||
chk: *Chunk,
|
||||
ip: usize,
|
||||
stdout: StdOut,
|
||||
|
||||
pub fn init() VM {}
|
||||
pub fn init(stdout: StdOut, chk: *Chunk) VM {
|
||||
return VM{
|
||||
.stdout = stdout,
|
||||
.chk = chk,
|
||||
.ip = 0,
|
||||
};
|
||||
}
|
||||
|
||||
fn readByte(self: *VM) u8 {
|
||||
var byte: u8 = self.chk.code[self.ip];
|
||||
self.ip += 1;
|
||||
return byte;
|
||||
}
|
||||
|
||||
fn readConst(self: *VM) value.Value {
|
||||
return self.chk.constants.values[self.readByte()];
|
||||
}
|
||||
|
||||
fn readConstLong(self: *VM) value.Value {
|
||||
const v3 = self.readByte();
|
||||
const v2 = self.readByte();
|
||||
const v1 = self.readByte();
|
||||
const const_idx = (@intCast(u24, v3) << 16) |
|
||||
(@intCast(u24, v2) << 8) |
|
||||
v1;
|
||||
|
||||
return self.chk.constants.values[const_idx];
|
||||
}
|
||||
|
||||
fn run(self: *VM) !InterpretResult {
|
||||
while (true) {
|
||||
var instruction = self.readByte();
|
||||
|
||||
switch (instruction) {
|
||||
chunk.OpCode.Constant => blk: {
|
||||
var constant = self.readConst();
|
||||
try value.printValue(self.stdout, constant);
|
||||
break :blk;
|
||||
},
|
||||
chunk.OpCode.ConstantLong => blk: {
|
||||
var constant = self.readConstLong();
|
||||
try value.printValue(self.stdout, constant);
|
||||
break :blk;
|
||||
},
|
||||
chunk.OpCode.Return => blk: {
|
||||
return InterpretResult.Ok;
|
||||
},
|
||||
else => blk: {
|
||||
std.debug.warn("Unknown instruction: {x}\n", instruction);
|
||||
return InterpretResult.RuntimeError;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn interpret(self: *VM) !InterpretResult {
|
||||
self.ip = 0;
|
||||
return try self.run();
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue