From 59d076f6dc179315b6dfc1c141dc9ee48cc66a54 Mon Sep 17 00:00:00 2001 From: mryouse Date: Tue, 6 Jun 2023 20:27:18 -0400 Subject: initial commit of reverse --- chunk.d | 20 ++++++++++++++++++++ compiler.d | 15 +++++++++++++++ vm.d | 4 ++++ 3 files changed, 39 insertions(+) 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(); -- cgit v1.2.3