From af07e3fba55ef98aabd54057c6e3433734b81111 Mon Sep 17 00:00:00 2001 From: mryouse Date: Thu, 1 Jun 2023 20:17:37 -0400 Subject: split concat/append into 2 ops --- chunk.d | 8 ++++---- compiler.d | 3 +-- dbg.d | 4 ++++ vm.d | 17 +++++++++++++++-- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/chunk.d b/chunk.d index e24e3ab..47a2d7e 100644 --- a/chunk.d +++ b/chunk.d @@ -46,7 +46,6 @@ abstract class Seq { abstract Value first(); abstract Seq rest(); abstract int length(); - abstract Seq concat(Seq seq); abstract bool isIn(Value val); } @@ -75,7 +74,7 @@ class String : Seq { return to!int(str.length); } - override Seq concat(Seq seq) { + Seq concat(Seq seq) { if (seq.type != SeqType.STRING) { // how do i throw an error here? writeln("must concat strings to strings!"); @@ -138,13 +137,13 @@ class List : Seq { return to!int(this.inner.length); } - override Seq concat(Seq seq) { + Seq append(Value val) { int length = to!int(this.inner.length); List ret = new List(length + 1); for (int i = 0; i < length; i++) { ret.addItemAtIndex(this.inner[i], i); } - ret.addItemAtIndex(makeSeqValue(seq), length); + ret.addItemAtIndex(val, length); return ret; } @@ -189,6 +188,7 @@ enum OpCode { // SEQUENCES OP_CONCAT, // No? + OP_APPEND, OP_FIRST, // No? OP_LENGTH, OP_MEMBER, diff --git a/compiler.d b/compiler.d index 28785a6..8a00547 100644 --- a/compiler.d +++ b/compiler.d @@ -566,7 +566,6 @@ class Compiler { if (args.length == 0) { this.func.chunk.writeOp(OpCode.OP_LIST, -1); this.func.chunk.writeOp(to!ubyte(0), -1); - //this.advance(); return; } int length = to!int(args.length); @@ -601,7 +600,7 @@ class Compiler { // TODO if this is used for both string/list, should be able to typecheck second arg here ValueType vt2 = this.resolve(args[1], ValueType.ANY); - this.func.chunk.writeOp(OpCode.OP_CONCAT, args[0].line); + this.func.chunk.writeOp(OpCode.OP_APPEND, args[0].line); } void compileIn(Form[] args) { diff --git a/dbg.d b/dbg.d index 6958a05..98f5b26 100644 --- a/dbg.d +++ b/dbg.d @@ -225,6 +225,10 @@ int disassemble(Chunk chunk, int offset) { return simpleInstruction("OP_FIRST", offset); case OpCode.OP_REST: return simpleInstruction("OP_REST", offset); + case OpCode.OP_CONCAT: + return simpleInstruction("OP_CONCAT", offset); + case OpCode.OP_APPEND: + return simpleInstruction("OP_APPEND", offset); default: writeln("unknown opcode?"); return offset + 1; diff --git a/vm.d b/vm.d index fbf874c..c5de28c 100644 --- a/vm.d +++ b/vm.d @@ -192,6 +192,14 @@ class VM { return value.as.seq; } + List asList(Value value) { + return cast(List)value.as.seq; + } + + String asNebString(Value value) { + return cast(String)value.as.seq; + } + double asNumber(Value value) { return value.as.number; } @@ -491,10 +499,15 @@ class VM { this.pushA(makeBooleanValue(areValuesEqual(a, b))); break; case OpCode.OP_CONCAT: - Seq b = asSeq(this.popA()); - Seq a = asSeq(this.popA()); + String b = asNebString(this.popA()); + String a = asNebString(this.popA()); this.pushA(makeSeqValue(a.concat(b))); break; + case OpCode.OP_APPEND: + Value b = this.popA(); + List a = asList(this.popA()); + this.pushA(makeSeqValue(a.append(b))); + break; case OpCode.OP_GREATER: Value b = this.popA(); Value a = this.popA(); -- cgit v1.2.3