diff options
| author | mryouse | 2023-05-25 01:14:59 +0000 |
|---|---|---|
| committer | mryouse | 2023-05-25 01:14:59 +0000 |
| commit | cb64344f44cdbcd31f4d775bd1865b1af142bba3 (patch) | |
| tree | 3a69ebbd65dd9f4f5248ce46562ee0d6d0c6cbd3 /vm.d | |
| parent | c08e9c793b138da5b373d6cb66a2eb599ea77397 (diff) | |
reference instance variables, and reset framecount in 'interpret'
Diffstat (limited to 'vm.d')
| -rw-r--r-- | vm.d | 202 |
1 files changed, 103 insertions, 99 deletions
@@ -53,50 +53,50 @@ class VM { } void pushFrame(CallFrame frame) { - if (this.frameCount < frames.length) { + if (this.frameCount < this.frames.length) { this.frames[this.frameCount] = frame; } else { this.frames ~= frame; } - current = &frames[this.frameCount]; - frameCount++; + this.current = &this.frames[this.frameCount]; + this.frameCount++; } Value peekA(int offset) { - if (offset >= aTop) { - writefln("offset of %d greater than stack size %d", offset, aTop); + if (offset >= this.aTop) { + writefln("offset of %d greater than stack size %d", offset, this.aTop); } - return this.aStack[aTop - offset - 1]; + return this.aStack[this.aTop - offset - 1]; } Value popA() { - if (aTop > 0) { - aTop--; + if (this.aTop > 0) { + this.aTop--; } else { writeln("popA() on an empty stack!!"); } - return aStack[aTop]; + return this.aStack[this.aTop]; } //InterpretResult push(Value value) { void pushA(Value value) { - if (aStack.length > aTop) { - aStack[aTop] = value; + if (this.aStack.length > this.aTop) { + this.aStack[this.aTop] = value; } else { - aStack ~= value; + this.aStack ~= value; } - aTop++; + this.aTop++; } Value popB() { - if (bTop > 0) { - bTop--; + if (this.bTop > 0) { + this.bTop--; //current.frameStart--; } else { writeln("popB() on an empty stack!!"); } //return bStack[bTop]; - return current.slots[bTop - current.frameStart - 1]; + return this.current.slots[this.bTop - this.current.frameStart - 1]; } @@ -113,22 +113,22 @@ class VM { current.frameStart++; */ - if (bStack.length > bTop) { - bStack[bTop] = value; + if (this.bStack.length > this.bTop) { + this.bStack[this.bTop] = value; } else { - bStack ~= value; + this.bStack ~= value; } - bTop++; + this.bTop++; } ubyte readByte() { - return current.func.chunk.code[current.ip++]; + return this.current.func.chunk.code[this.current.ip++]; } uint readShort() { - current.ip += 2; - uint high = current.func.chunk.code[current.ip - 2] << 8; - uint low = current.func.chunk.code[current.ip - 1]; + this.current.ip += 2; + uint high = this.current.func.chunk.code[this.current.ip - 2] << 8; + uint low = this.current.func.chunk.code[this.current.ip - 1]; return high | low; //return 0; @@ -199,7 +199,7 @@ class VM { if (isObj(callee)) { switch (callee.as.obj.type) { case ObjType.FUNCTION: - return call(asFunction(callee), argCount); + return this.call(asFunction(callee), argCount); case ObjType.SCRIPT: writeln("trying to call the script?"); break; @@ -214,34 +214,35 @@ class VM { } bool call(Function func, int argCount) { - CallFrame frame = { func, 0, bStack, bTop - argCount - 1 }; // i need to do sthg with argCount + CallFrame frame = { func, 0, this.bStack, this.bTop - argCount - 1 }; // i need to do sthg with argCount //frames ~= frame; //frameCount++; - pushFrame(frame); + this.pushFrame(frame); return true; } InterpretResult run() { writeln("== VM running =="); + writefln("> > > framecount: %d", this.frameCount); while (true) { if (DEBUG) { writeln(" Stacks:"); write(" A> "); for (int i = 0; i < aTop; i++) { - writef("[ %s ]", printableValue(aStack[i])); + writef("[ %s ]", printableValue(this.aStack[i])); } write("\n B> "); for (int i = 0; i < bTop; i++) { //writef("[ %s ]", printableValue(bStack[i])); - writef("[ %s ]", printableValue(current.slots[i])); + writef("[ %s ]", printableValue(this.current.slots[i])); } write("\n constants> "); - for (int i = 0; i < current.func.chunk.constants.length; i++) { - writef("[ %s ]", printableValue(current.func.chunk.constants[i])); + for (int i = 0; i < this.current.func.chunk.constants.length; i++) { + writef("[ %s ]", printableValue(this.current.func.chunk.constants[i])); } writeln("\n--"); - disassemble(current.func.chunk, current.ip); + disassemble(this.current.func.chunk, this.current.ip); } /* @@ -256,101 +257,101 @@ class VM { ubyte inst; switch (inst = this.readByte()) { case OpCode.OP_DEF_GLOBAL: - Value name = current.func.chunk.constants[readByte()]; + Value name = this.current.func.chunk.constants[this.readByte()]; if (!isString(name)) { writefln("variables must be strings, got %s", printableValue(name)); return InterpretResult.RUNTIME_ERROR; // TODO error } - Value val = popA(); - globals[asString(name)] = val; + Value val = this.popA(); + this.globals[asString(name)] = val; break; case OpCode.OP_GET_GLOBAL: - Value name = current.func.chunk.constants[readByte()]; + Value name = this.current.func.chunk.constants[this.readByte()]; //writefln(asString(name)); if (!isString(name)) { writefln("variables must be strings, got %s", printableValue(name)); return InterpretResult.RUNTIME_ERROR; // TODO error } - Value* member = asString(name) in globals; + Value* member = asString(name) in this.globals; if (member is null) { writefln("no such variable: %s", printableValue(name)); return InterpretResult.RUNTIME_ERROR; // TODO error } - pushA(*member); // do i need to dereference? + this.pushA(*member); // do i need to dereference? break; case OpCode.OP_DEF_LOCAL: - Value val = popA(); - pushB(val); + Value val = this.popA(); + this.pushB(val); //current.slots ~= val; break; case OpCode.OP_GET_LOCAL: - ubyte slot = readByte(); + ubyte slot = this.readByte(); //pushA(bStack[bTop - slot - 1]); //pushA(current.slots[slot - 1]); //pushA(current.slots[current.frameStart + slot + 1]); - pushA(current.slots[current.frameStart + slot]); + pushA(this.current.slots[this.current.frameStart + slot]); break; case OpCode.OP_SET_LOCAL: - ubyte slot = readByte(); + ubyte slot = this.readByte(); //bStack[bTop + slot - 1] = peekA(0); - current.slots[slot] = peekA(0); + this.current.slots[slot] = this.peekA(0); //bStack[bTop + slot - 1] = peekA(0); - popA(); + this.popA(); break; case OpCode.OP_CONSTANT: - Value constant = current.func.chunk.constants[readByte()]; + Value constant = this.current.func.chunk.constants[this.readByte()]; //Value constant = current.func.chunk.constants[b]; - pushA(constant); + this.pushA(constant); break; case OpCode.OP_NEGATE: - if (!isNumber(peekA(0))) { + if (!isNumber(this.peekA(0))) { writeln("negate operand must be a number"); return InterpretResult.RUNTIME_ERROR; } - double val = asNumber(popA()); - pushA(makeNumberValue(val * -1)); + double val = asNumber(this.popA()); + this.pushA(makeNumberValue(val * -1)); break; case OpCode.OP_TYPE_CHECK_LIST: - if (!isList(peekA(0))) { + if (!isList(this.peekA(0))) { writeln("VM type check: not a list!"); return InterpretResult.RUNTIME_ERROR; // TODO error } break; case OpCode.OP_TYPE_CHECK_STRING: - if (!isString(peekA(0))) { + if (!isString(this.peekA(0))) { writeln("VM type check: not a string!"); return InterpretResult.RUNTIME_ERROR; // TODO error } break; case OpCode.OP_TYPE_CHECK_NUMBER: - if (!isNumber(peekA(0))) { + if (!isNumber(this.peekA(0))) { writeln("VM type check: not a number!"); return InterpretResult.RUNTIME_ERROR; // TODO error } break; case OpCode.OP_TYPE_CHECK_BOOLEAN: - if (!isBoolean(peekA(0))) { + if (!isBoolean(this.peekA(0))) { writeln("VM type check: not a boolean!"); return InterpretResult.RUNTIME_ERROR; // TODO error } break; case OpCode.OP_FIRST: - Value val = popA(); + Value val = this.popA(); List lst = cast(List)val.as.obj; // TODO this needs better checking int addr = lst.first(); writefln("got this address: %d", addr); - Value first = current.func.chunk.constants[to!ubyte(addr)]; - pushA(first); + Value first = this.current.func.chunk.constants[to!ubyte(addr)]; + this.pushA(first); break; case OpCode.OP_ADD: - Value b = popA(); + Value b = this.popA(); /* if (!isNumber(b)) { writeln("b is not a number!"); return InterpretResult.RUNTIME_ERROR; // TODO error } */ - Value a = popA(); + Value a = this.popA(); /* if (!isNumber(a)) { writeln("a is not a number!"); @@ -359,17 +360,17 @@ class VM { */ double bnum = asNumber(b); double anum = asNumber(a); - pushA(makeNumberValue(anum + bnum)); + this.pushA(makeNumberValue(anum + bnum)); break; case OpCode.OP_SUBTRACT: - Value b = popA(); + Value b = this.popA(); /* if (!isNumber(b)) { writeln("b is not a number!"); return InterpretResult.RUNTIME_ERROR; // TODO error } */ - Value a = popA(); + Value a = this.popA(); /* if (!isNumber(a)) { writeln("a is not a number!"); @@ -378,36 +379,36 @@ class VM { */ double bnum = asNumber(b); double anum = asNumber(a); - pushA(makeNumberValue(anum - bnum)); + this.pushA(makeNumberValue(anum - bnum)); break; case OpCode.OP_NOT: - Value val = popA(); + Value val = this.popA(); bool bval = asBoolean(val); - pushA(makeBooleanValue(!bval)); + this.pushA(makeBooleanValue(!bval)); break; case OpCode.OP_CONCAT: - Value b = popA(); - Value a = popA(); + Value b = this.popA(); + Value a = this.popA(); string bstr = asString(b); string astr = asString(a); - pushA(makeStringValue(astr ~ bstr)); + this.pushA(makeStringValue(astr ~ bstr)); break; case OpCode.OP_GREATER: - Value b = popA(); - Value a = popA(); + Value b = this.popA(); + Value a = this.popA(); double bnum = asNumber(b); double anum = asNumber(a); - pushA(makeBooleanValue(anum > bnum)); + this.pushA(makeBooleanValue(anum > bnum)); break; case OpCode.OP_LESS: - Value b = popA(); + Value b = this.popA(); /* if (!isNumber(b)) { writeln("b is not a number!"); return InterpretResult.RUNTIME_ERROR; // TODO error } */ - Value a = popA(); + Value a = this.popA(); /* if (!isNumber(a)) { writeln("a is not a number!"); @@ -416,85 +417,85 @@ class VM { */ double bnum = asNumber(b); double anum = asNumber(a); - pushA(makeBooleanValue(anum < bnum)); + this.pushA(makeBooleanValue(anum < bnum)); break; case OpCode.OP_RETURN: - Value ret = popA(); - popA(); // function + Value ret = this.popA(); + this.popA(); // function this.frameCount--; if (this.frameCount == 1) { writefln("returned %s", printableValue(ret)); return InterpretResult.OK; } // do something with the stack top/frame slots?? - while(bTop > current.frameStart + 1) { - popB(); + while(bTop > this.current.frameStart + 1) { + this.popB(); } - pushA(ret); - current = &frames[this.frameCount -1]; + this.pushA(ret); + this.current = &this.frames[this.frameCount -1]; break; case OpCode.OP_POP: - popA(); + this.popA(); break; case OpCode.OP_POPB: - popB(); + this.popB(); break; case OpCode.OP_POP_SCOPE: // pop the n-1 position - Value val = popA(); - popA(); // throw this one away - pushA(val); + Value val = this.popA(); + this.popA(); // throw this one away + this.pushA(val); break; case OpCode.OP_JUMP: - uint offset = readShort(); + uint offset = this.readShort(); //ip += offset; - current.ip += offset; + this.current.ip += offset; break; case OpCode.OP_JUMP_IF_FALSE: - uint offset = readShort(); - if (!isBoolean(peekA(0))) { + uint offset = this.readShort(); + if (!isBoolean(this.peekA(0))) { writeln("expecting a boolean condition"); return InterpretResult.RUNTIME_ERROR; // TODO error } - if (!asBoolean(peekA(0))) { + if (!asBoolean(this.peekA(0))) { //ip += offset; - current.ip += offset; + this.current.ip += offset; } break; case OpCode.OP_JUMP_IF_TRUE: - uint offset = readShort(); + uint offset = this.readShort(); /* if (!isBoolean(peekA(0))) { writeln("expecting a boolean condition"); return InterpretResult.RUNTIME_ERROR; // TODO error } */ - if (asBoolean(peekA(0))) { - current.ip += offset; + if (asBoolean(this.peekA(0))) { + this.current.ip += offset; } break; case OpCode.OP_CALL: - ubyte argCount = readByte(); + ubyte argCount = this.readByte(); // TODO i think i need to move the arguments from stack A to stack B (preserving order) int cnt = to!int(argCount) - 1; Value[] tmp; while (cnt >= 0) { - tmp ~= popA(); + tmp ~= this.popA(); cnt--; } foreach (Value val ; tmp) { - pushB(val); + this.pushB(val); } //if (!callValue(peekA(argCount), argCount)) { // i'm allocating variables wrong - if (!callValue(peekA(0), argCount)) { // i'm allocating variables wrong + if (!this.callValue(this.peekA(0), argCount)) { // i'm allocating variables wrong return InterpretResult.RUNTIME_ERROR; } - current = &frames[this.frameCount - 1]; + this.current = &this.frames[this.frameCount - 1]; break; default: writeln("unknown opcode to run"); @@ -512,6 +513,9 @@ InterpretResult interpret(string source, VM vm) { // vm.globals[":int"] = makeTypeValue(":int"); + // reset the frame count (why do i need to do this?) + vm.frameCount = 0; + vm.pushA(makeObjValue(func)); CallFrame frame = { func, 0, vm.bStack, 0 }; vm.pushFrame(frame); |
