diff options
Diffstat (limited to 'vm.d')
| -rw-r--r-- | vm.d | 53 |
1 files changed, 53 insertions, 0 deletions
@@ -174,6 +174,11 @@ class VM { return value.type == ValueType.SEQ; } + bool isNil(Value value) { + return isList(value) && + value.as.seq.length() == 0; + } + bool isList(Value value) { return isSeq(value) && seqTypeOf(value) == SeqType.LIST; } @@ -287,6 +292,45 @@ class VM { ubyte inst; switch (inst = this.readByte()) { + case OpCode.OP_IS_NIL: + Value val = this.popA(); + this.pushA(makeBooleanValue(isNil(val))); + break; + case OpCode.OP_DUPLICATE: + this.pushA(this.peekA(0)); + break; + case OpCode.OP_DUPLICATE_2: + this.pushA(this.peekA(1)); + this.pushA(this.peekA(1)); + break; + case OpCode.OP_ROTATE_N: + int n = to!int(this.readByte()); + + // pop the top of the stack + Value top = this.popA(); + + // pop the next n-1 values + Value[] inner; + for (int i = 0; i < n - 1; i++) { + inner ~= this.popA(); + } + + // push the top + this.pushA(top); + + // push the other values (preserve order) + for (int i = n - 1; i >= 0; i--) { + this.pushA(inner[i]); + } + break; + case OpCode.OP_ZERO: + this.pushA(makeNumberValue(0)); + break; + case OpCode.OP_INCREMENT: + Value val = this.popA(); + double num = asNumber(val); + this.pushA(makeNumberValue(num + 1)); + break; case OpCode.OP_DEF_GLOBAL: Value name = this.current.func.chunk.constants[this.readByte()]; if (!isString(name)) { @@ -340,6 +384,15 @@ class VM { //bStack[bTop + slot - 1] = peekA(0); this.popA(); break; + case OpCode.OP_LIST_N: + Value lengthVal = this.popA(); + int length = to!int(asNumber(lengthVal)); + List lst = new List(length); + for (int i = length - 1; i >= 0; i--) { + lst.addItemAtIndex(this.popA(), i); + } + this.pushA(makeSeqValue(lst)); + break; case OpCode.OP_LIST: int length = to!int(this.readByte()); List lst = new List(length); |
