aboutsummaryrefslogtreecommitdiff
path: root/vm.d
diff options
context:
space:
mode:
authorBen Winston2023-05-22 20:12:40 -0400
committerBen Winston2023-05-22 20:12:40 -0400
commitb7fba62e9f1f9f7a5a67fd64d4aed55646d1b58e (patch)
tree42c192475ed3e17dd57203cab03b41f1cbca40a9 /vm.d
parent229859cde2f0dae4714b972cf18e923027db265c (diff)
runtime type checking
Diffstat (limited to 'vm.d')
-rw-r--r--vm.d44
1 files changed, 39 insertions, 5 deletions
diff --git a/vm.d b/vm.d
index ef6efbf..5b69a23 100644
--- a/vm.d
+++ b/vm.d
@@ -139,7 +139,12 @@ class VM {
}
bool isString(Value value) {
- return value.type == ValueType.STRING;
+ return value.type == ValueType.STRING ||
+ value.type == ValueType.TYPE;
+ }
+
+ bool isType(Value value) {
+ return value.type == ValueType.TYPE;
}
bool isBoolean(Value value) {
@@ -159,7 +164,11 @@ class VM {
}
string asString(Value value) {
- return value.as.str;
+ if (value.type == ValueType.TYPE) {
+ return value.as.type;
+ } else {
+ return value.as.str;
+ }
}
bool asBoolean(Value value) {
@@ -292,47 +301,71 @@ class VM {
double val = asNumber(popA());
pushA(makeNumberValue(val * -1));
break;
+ case OpCode.OP_TYPE_CHECK_NUMBER:
+ if (!isNumber(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))) {
+ writeln("VM type check: not a boolean!");
+ return InterpretResult.RUNTIME_ERROR; // TODO error
+ }
+ break;
case OpCode.OP_ADD:
Value b = popA();
+ /*
if (!isNumber(b)) {
writeln("b is not a number!");
return InterpretResult.RUNTIME_ERROR; // TODO error
}
+ */
Value a = popA();
+ /*
if (!isNumber(a)) {
writeln("a is not a number!");
return InterpretResult.RUNTIME_ERROR; // TODO error
}
+ */
double bnum = asNumber(b);
double anum = asNumber(a);
pushA(makeNumberValue(anum + bnum));
break;
case OpCode.OP_SUBTRACT:
Value b = popA();
+ /*
if (!isNumber(b)) {
writeln("b is not a number!");
return InterpretResult.RUNTIME_ERROR; // TODO error
}
+ */
Value a = popA();
+ /*
if (!isNumber(a)) {
writeln("a is not a number!");
return InterpretResult.RUNTIME_ERROR; // TODO error
}
+ */
double bnum = asNumber(b);
double anum = asNumber(a);
pushA(makeNumberValue(anum - bnum));
break;
case OpCode.OP_LESS:
Value b = popA();
+ /*
if (!isNumber(b)) {
writeln("b is not a number!");
return InterpretResult.RUNTIME_ERROR; // TODO error
}
+ */
Value a = popA();
+ /*
if (!isNumber(a)) {
writeln("a is not a number!");
return InterpretResult.RUNTIME_ERROR; // TODO error
}
+ */
double bnum = asNumber(b);
double anum = asNumber(a);
pushA(makeBooleanValue(anum < bnum));
@@ -342,10 +375,7 @@ class VM {
Value ret = popA();
popA(); // function
this.frameCount--;
- //writefln("frameCount: %d", frameCount);
- //if (this.frameCount == 0) {
if (this.frameCount == 1) {
- popA();
writefln("returned %s", printableValue(ret));
return InterpretResult.OK;
}
@@ -387,10 +417,12 @@ class VM {
break;
case OpCode.OP_JUMP_IF_TRUE:
uint offset = readShort();
+ /*
if (!isBoolean(peekA(0))) {
writeln("expecting a boolean condition");
return InterpretResult.RUNTIME_ERROR; // TODO error
}
+ */
if (asBoolean(peekA(0))) {
current.ip += offset;
}
@@ -432,6 +464,8 @@ InterpretResult interpret(string source) {
VM vm = new VM();
+// vm.globals[":int"] = makeTypeValue(":int");
+
vm.pushA(makeObjValue(func));
CallFrame frame = { func, 0, vm.bStack, 0 };
vm.pushFrame(frame);