aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormryouse2023-06-06 20:27:18 -0400
committermryouse2023-06-06 20:27:18 -0400
commit59d076f6dc179315b6dfc1c141dc9ee48cc66a54 (patch)
treeec667f8146e12299404ab11d52fed2e8d79c62b3
parent87ee44163d0f7ec86963cefea51e721ce4eb156c (diff)
initial commit of reverse
-rw-r--r--chunk.d20
-rw-r--r--compiler.d15
-rw-r--r--vm.d4
3 files changed, 39 insertions, 0 deletions
diff --git a/chunk.d b/chunk.d
index 21ebb9d..fb1f97c 100644
--- a/chunk.d
+++ b/chunk.d
@@ -47,6 +47,7 @@ abstract class Seq {
abstract Seq rest();
abstract Seq most();
abstract Value last();
+ abstract Seq reverse();
abstract int length();
abstract bool isIn(Value val);
}
@@ -76,6 +77,15 @@ class String : Seq {
return new String(this.str[0..$ - 1]);
}
+ override Seq reverse() {
+ string s = "";
+ int end = to!int(this.str.length) - 1;
+ for (int i = end; i >= 0; i--) {
+ s ~= this.str[i];
+ }
+ return new String(s);
+ }
+
override Value last() {
return makeStringValue(to!string(this.str[$ - 1]));
}
@@ -155,6 +165,15 @@ class List : Seq {
return ret;
}
+ override Seq reverse() {
+ int length = to!int(this.inner.length);
+ List ret = new List(length);
+ for (int i = 0; i < length; i++) {
+ ret.addItemAtIndex(this.inner[i], length - i - 1);
+ }
+ return ret;
+ }
+
override Value last() {
return this.inner[$ - 1]; // this fails on NIL
}
@@ -225,6 +244,7 @@ enum OpCode {
OP_MEMBER,
OP_MOST,
OP_REST,
+ OP_REVERSE,
// DEFINITIONS/VARIABLES
OP_CONSTANT,
diff --git a/compiler.d b/compiler.d
index 6756882..51fca25 100644
--- a/compiler.d
+++ b/compiler.d
@@ -662,6 +662,18 @@ class Compiler {
this.func.chunk.writeOp(OpCode.OP_REST, args[0].line);
}
+ void compileReverse(Form[] args) {
+ // TODO how do we identify/propagate errors?
+ if (args.length != 1) {
+ this.error("'reverse': expected [1] argument, received ?", -1);
+ return;
+ }
+ ValueType vt = this.resolve(args[0], ValueType.OBJ); // TODO need a new type
+ this.func.chunk.writeOp(OpCode.OP_TYPE_CHECK_SEQ, args[0].line);
+
+ this.func.chunk.writeOp(OpCode.OP_REVERSE, args[0].line);
+ }
+
// TERMINAL
void compilePrint(Form[] args) {
if (args.length != 1) {
@@ -843,6 +855,9 @@ class Compiler {
case "rest":
this.compileRest(cons.tail);
break;
+ case "reverse":
+ this.compileReverse(cons.tail);
+ break;
// OTHER
case "print":
diff --git a/vm.d b/vm.d
index a8d3d6e..db2d4a0 100644
--- a/vm.d
+++ b/vm.d
@@ -475,6 +475,10 @@ class VM {
Seq seq = asSeq(this.popA());
this.pushA(makeNumberValue(seq.length()));
break;
+ case OpCode.OP_REVERSE:
+ Seq seq = asSeq(this.popA());
+ this.pushA(makeSeqValue(seq.reverse()));
+ break;
case OpCode.OP_MEMBER:
Seq seq = asSeq(this.popA());
Value val = this.popA();