diff options
| author | Ben Winston | 2023-05-22 20:12:40 -0400 |
|---|---|---|
| committer | Ben Winston | 2023-05-22 20:12:40 -0400 |
| commit | b7fba62e9f1f9f7a5a67fd64d4aed55646d1b58e (patch) | |
| tree | 42c192475ed3e17dd57203cab03b41f1cbca40a9 /vm.d | |
| parent | 229859cde2f0dae4714b972cf18e923027db265c (diff) | |
runtime type checking
Diffstat (limited to 'vm.d')
| -rw-r--r-- | vm.d | 44 |
1 files changed, 39 insertions, 5 deletions
@@ -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); |
