aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormryouse2023-05-25 22:52:07 +0000
committermryouse2023-05-25 22:52:07 +0000
commit785b43a7b6635e6fadb94e224a094e524c9e0ccd (patch)
tree5c60ee3d25a747c21e480283a9dd4021457c43f3
parent3535bfefccea789169786767ac80c54241cae019 (diff)
length on seq
-rw-r--r--chunk.d6
-rw-r--r--compiler.d15
-rw-r--r--vm.d4
3 files changed, 25 insertions, 0 deletions
diff --git a/chunk.d b/chunk.d
index 70d7b1c..47d3c73 100644
--- a/chunk.d
+++ b/chunk.d
@@ -45,6 +45,7 @@ abstract class Seq {
SeqType type;
abstract Value first();
abstract Seq rest();
+ abstract int length();
}
class List : Seq {
@@ -71,6 +72,10 @@ class List : Seq {
return ret;
}
+ override int length() {
+ return to!int(this.inner.length);
+ }
+
override string toString() {
return format("list ('%s' + %d)", printableValue(this.inner[0]), this.inner.length - 1);
}
@@ -108,6 +113,7 @@ enum OpCode {
OP_FIRST, // No?
OP_REST,
+ OP_LENGTH,
OP_TYPE_CHECK_NUMBER,
OP_TYPE_CHECK_BOOLEAN,
diff --git a/compiler.d b/compiler.d
index 92711f1..66ee664 100644
--- a/compiler.d
+++ b/compiler.d
@@ -521,6 +521,18 @@ class Compiler {
this.func.chunk.writeOp(to!ubyte(length), args[0].line);
}
+ void compileLength(Form[] args) {
+ // TODO how do we identify/propagate errors?
+ if (args.length != 1) {
+ writeln("COMPILE ERROR: 'first' expects exactly one argument");
+ return;
+ }
+ ValueType vt = this.resolve(args[0], ValueType.SEQ); // TODO need a new type
+ this.func.chunk.writeOp(OpCode.OP_TYPE_CHECK_SEQ, args[0].line);
+
+ this.func.chunk.writeOp(OpCode.OP_LENGTH, args[0].line);
+ }
+
void compileFirst(Form[] args) {
// TODO how do we identify/propagate errors?
if (args.length != 1) {
@@ -676,6 +688,9 @@ class Compiler {
case "first":
this.compileFirst(cons.tail);
break;
+ case "length":
+ this.compileLength(cons.tail);
+ break;
case "list":
//return compileList(cons.tail);
this.compileList(cons.tail);
diff --git a/vm.d b/vm.d
index 5f1d889..40877b8 100644
--- a/vm.d
+++ b/vm.d
@@ -395,6 +395,10 @@ class VM {
Seq seq = asSeq(this.popA());
this.pushA(makeSeqValue(seq.rest()));
break;
+ case OpCode.OP_LENGTH:
+ Seq seq = asSeq(this.popA());
+ this.pushA(makeNumberValue(seq.length()));
+ break;
case OpCode.OP_ADD:
Value b = this.popA();
/*