diff options
| -rw-r--r-- | chunk.d | 8 | ||||
| -rw-r--r-- | compiler.d | 3 | ||||
| -rw-r--r-- | dbg.d | 4 | ||||
| -rw-r--r-- | vm.d | 17 |
4 files changed, 24 insertions, 8 deletions
@@ -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, @@ -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) { @@ -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; @@ -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(); |
