aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chunk.d8
-rw-r--r--compiler.d3
-rw-r--r--dbg.d4
-rw-r--r--vm.d17
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();