aboutsummaryrefslogtreecommitdiff
path: root/vm.d
diff options
context:
space:
mode:
authormryouse2023-05-26 19:21:25 +0000
committermryouse2023-05-26 19:21:25 +0000
commitb57c1630da58d55dbb7855d9de76f776600038ea (patch)
treeda8c22b43de8d4afe9c6caf2120c953e5213c254 /vm.d
parent6261be78421d6a842b21653b069ca7b032f8fecc (diff)
add more opcodes, preparing for HOF
Diffstat (limited to 'vm.d')
-rw-r--r--vm.d53
1 files changed, 53 insertions, 0 deletions
diff --git a/vm.d b/vm.d
index 6ab2e96..75f6328 100644
--- a/vm.d
+++ b/vm.d
@@ -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);