add basic virtual machine code

This commit is contained in:
Luna 2019-06-01 14:55:11 -03:00
parent 14fa63e1f6
commit dae3c259fd
2 changed files with 83 additions and 9 deletions

View file

@ -4,6 +4,7 @@ const Allocator = std.mem.Allocator;
// const Scanner = @import("scanner.zig").Scanner; // const Scanner = @import("scanner.zig").Scanner;
const chunk = @import("chunk.zig"); const chunk = @import("chunk.zig");
const vm = @import("vm.zig");
//const Compiler = @import("compiler.zig").Compiler; //const Compiler = @import("compiler.zig").Compiler;
@ -107,7 +108,7 @@ pub fn main() !void {
var allocator = &arena.allocator; var allocator = &arena.allocator;
var stdout_file = try std.io.getStdOut(); 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); var chk = try chunk.Chunk.init(allocator);
@ -115,11 +116,13 @@ pub fn main() !void {
//var opcode_byte: u8 = @enumToInt(chunk.OpCode.Return); //var opcode_byte: u8 = @enumToInt(chunk.OpCode.Return);
//try chk.write(chunk.OpCode.Return); //try chk.write(chunk.OpCode.Return);
var i: usize = 0; var constant = try chk.writeConstant(1.2, 123);
while (i < 260) : (i += 1) {
var constant = try chk.writeConstant(1.2, 123);
}
try chk.write(chunk.OpCode.Return, 123); try chk.write(chunk.OpCode.Return, 123);
try chk.disassemble(stdout, "test chunk"); 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");
} }

View file

@ -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 { 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();
}
}; };