aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormryouse2023-06-01 22:47:43 -0400
committermryouse2023-06-01 22:47:43 -0400
commitb66702e49ab7f90a348bb2bea015fd5901c457d8 (patch)
treed87ed09ea6446f50964bf23bf5b810638ad3efc4
parentaf07e3fba55ef98aabd54057c6e3433734b81111 (diff)
add print (no escape sequences) and REPL returns
-rw-r--r--chunk.d7
-rw-r--r--compiler.d19
-rw-r--r--dbg.d2
-rw-r--r--main.d2
-rw-r--r--vm.d27
5 files changed, 55 insertions, 2 deletions
diff --git a/chunk.d b/chunk.d
index 47a2d7e..55772dc 100644
--- a/chunk.d
+++ b/chunk.d
@@ -160,7 +160,11 @@ class List : Seq {
if (this.inner.length == 0) {
return "nil";
} else {
- return format("list ('%s' + %d)", printableValue(this.inner[0]), this.inner.length - 1);
+ string[] ret;
+ foreach (Value val ; this.inner) {
+ ret ~= printableValue(val);
+ }
+ return format("(%s)", join(ret, " "));
}
}
}
@@ -219,6 +223,7 @@ enum OpCode {
// RANDOM
OP_NIL,
+ OP_PRINT,
// FUNCTIONS
OP_CALL,
diff --git a/compiler.d b/compiler.d
index 8a00547..08b916b 100644
--- a/compiler.d
+++ b/compiler.d
@@ -325,6 +325,14 @@ class Compiler {
return ValueType.BOOLEAN;
}
+ void compilePrint(Form[] args) {
+ if (args.length != 1) {
+ this.error(format("'print': expected [1] argument, received %d", to!int(args.length)), -1);
+ }
+ ValueType vt1 = this.resolve(args[0], ValueType.ANY);
+ this.func.chunk.writeOp(OpCode.OP_PRINT, args[0].line);
+ }
+
int parseVariable(Symbol sym) {
this.declareVariable(sym);
@@ -856,6 +864,10 @@ class Compiler {
case "nil?":
this.compileIsNil(cons.tail);
break;
+ case "->string":
+ // does nothing at the moment, as primarily used for printing
+ // and everything can be printed
+ break;
// LISTS
case "append":
@@ -877,10 +889,17 @@ class Compiler {
case "rest":
this.compileRest(cons.tail);
break;
+
+ // OTHER
+ case "print":
+ this.compilePrint(cons.tail);
+ break;
+
default:
this.resolve(head);
this.call(cons.tail);
break;
+
}
return ValueType.NIL;
diff --git a/dbg.d b/dbg.d
index 98f5b26..c09b199 100644
--- a/dbg.d
+++ b/dbg.d
@@ -11,6 +11,8 @@ import parser;
//bool DEBUG = true;
bool DEBUG = false;
+bool REPL = false;
+
void printForm(Form f, string prefix = "") {
switch (f.type) {
diff --git a/main.d b/main.d
index b540058..7006a52 100644
--- a/main.d
+++ b/main.d
@@ -10,6 +10,7 @@ import chunk;
import compiler;
*/
import vm;
+import dbg;
/*
import compiler;
@@ -21,6 +22,7 @@ import vm;
void repl() {
+ REPL = true;
VM vm = new VM();
while(true) {
diff --git a/vm.d b/vm.d
index c5de28c..e34e4bc 100644
--- a/vm.d
+++ b/vm.d
@@ -145,6 +145,11 @@ class VM {
return high | low;
}
+ Seq nil() {
+ List nil = new List(0);
+ return nil;
+ }
+
bool isNumber(Value value) {
return value.type == ValueType.NUMBER;
}
@@ -155,6 +160,13 @@ class VM {
value.type == ValueType.SEQ; // WRONG
}
+ bool isNebString(Value value) {
+ if (value.type != ValueType.SEQ) {
+ return false;
+ }
+ return value.as.seq.type == SeqType.STRING;
+ }
+
bool isType(Value value) {
return value.type == ValueType.TYPE;
}
@@ -527,7 +539,11 @@ class VM {
this.popA(); // function
this.frameCount--;
if (this.frameCount == 1) {
- writefln("returned %s", printableValue(ret));
+ if (DEBUG) {
+ writefln("returned %s", printableValue(ret));
+ } else if (REPL) {
+ writefln("=> %s", printableValue(ret));
+ }
return InterpretResult.OK;
}
// do something with the stack top/frame slots??
@@ -548,6 +564,15 @@ class VM {
this.popA(); // throw this one away
this.pushA(val);
break;
+ case OpCode.OP_PRINT:
+ Value val = this.popA();
+ if (isNebString(val)) {
+ writefln("%s", tr(asNebString(val).str, `\`, ""));
+ } else {
+ writefln("%s", printableValue(val));
+ }
+ this.pushA(makeSeqValue(nil()));
+ break;
case OpCode.OP_JUMP_TO:
uint addr = this.readShort();
//this.current.ip -= offset;