aboutsummaryrefslogtreecommitdiff
path: root/vm.d
diff options
context:
space:
mode:
Diffstat (limited to 'vm.d')
-rw-r--r--vm.d44
1 files changed, 42 insertions, 2 deletions
diff --git a/vm.d b/vm.d
index 6011928..7955963 100644
--- a/vm.d
+++ b/vm.d
@@ -1,5 +1,6 @@
import std.stdio;
import std.string;
+import std.conv;
import chunk;
import parser;
@@ -19,6 +20,7 @@ class VM {
Value[] stack;
//ObjFunction func;
Function func;
+ Value[string] globals;
this(Function func) {
this.func = func;
@@ -26,6 +28,7 @@ class VM {
Value peek(int offset) {
if (offset >= this.topOffset) {
+ //if (offset > this.topOffset) {
writefln("offset of %d greater than stack size %d", offset, topOffset);
}
return this.stack[topOffset - offset - 1];
@@ -58,22 +61,55 @@ class VM {
return value.type == ValueType.NUMBER;
}
+ bool isString(Value value) {
+ return value.type == ValueType.STRING;
+ }
+
double asNumber(Value value) {
return value.as.number;
}
+ string asString(Value value) {
+ return value.as.str;
+ }
+
InterpretResult run() {
//int ip = 0; // TODO this is wrong
while (true) {
write(" ");
- //foreach (Value val; this.stack) {
for (int i = 0; i < this.topOffset; i++) {
writef("[ %s ]", printableValue(this.stack[i]));
}
writeln("\n--");
+
disassemble(this.func.chunk, this.ip);
ubyte inst;
switch (inst = this.readByte()) {
+ case OpCode.OP_DEFINE_GLOBAL:
+ Value name = func.chunk.constants[readByte()];
+ if (!isString(name)) {
+ writefln("variables must be strings, got %s", printableValue(name));
+ return InterpretResult.RUNTIME_ERROR; // TODO error
+ }
+ Value val = pop();
+ globals[asString(name)] = val;
+ break;
+ case OpCode.OP_GET_GLOBAL:
+ writeln("in OP_GET_GLOBAL");
+ Value name = func.chunk.constants[readByte()];
+ writefln(asString(name));
+ if (!isString(name)) {
+ writefln("variables must be strings, got %s", printableValue(name));
+ return InterpretResult.RUNTIME_ERROR; // TODO error
+ }
+ writefln(asString(name));
+ Value* member = asString(name) in globals;
+ if (member is null) {
+ writefln("no such variable: %s", printableValue(name));
+ return InterpretResult.RUNTIME_ERROR; // TODO error
+ }
+ push(*member); // do i need to dereference?
+ break;
case OpCode.OP_CONSTANT:
Value constant = this.func.chunk.constants[this.readByte()];
this.push(constant);
@@ -142,5 +178,9 @@ class VM {
}
}
-
}
+
+/*
+InterpretResult interpret(string source) {
+ Parser parser = new Parser(source);
+*/