aboutsummaryrefslogtreecommitdiff
path: root/compiler.d
diff options
context:
space:
mode:
authorBen Winston2023-05-22 20:12:40 -0400
committerBen Winston2023-05-22 20:12:40 -0400
commitb7fba62e9f1f9f7a5a67fd64d4aed55646d1b58e (patch)
tree42c192475ed3e17dd57203cab03b41f1cbca40a9 /compiler.d
parent229859cde2f0dae4714b972cf18e923027db265c (diff)
runtime type checking
Diffstat (limited to 'compiler.d')
-rw-r--r--compiler.d42
1 files changed, 35 insertions, 7 deletions
diff --git a/compiler.d b/compiler.d
index 0c6611c..76f6c04 100644
--- a/compiler.d
+++ b/compiler.d
@@ -22,6 +22,8 @@ class Compiler {
Form current;
Form previous;
+ int currentLine;
+
Form outer;
int outerIdx;
@@ -48,7 +50,12 @@ class Compiler {
}
void compileAdd(Form[] args) {
+ writeln("compiling add");
+ int line = args[0].line;
resolve(args[0]);
+ writeln("resolved the first argument");
+ func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, line);
+ writeln("wrote the typecheck op");
// (+ n) always returns n
if (args.length == 1) {
@@ -57,20 +64,24 @@ class Compiler {
for (int i = 1; i < args.length; i++) {
resolve(args[i]);
- func.chunk.writeOp(OpCode.OP_ADD, current.line);
+ func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, line);
+ func.chunk.writeOp(OpCode.OP_ADD, line);
}
}
void compileNegate(Form arg) {
resolve(arg);
- func.chunk.writeOp(OpCode.OP_NEGATE, current.line);
+ func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, currentLine);
+ func.chunk.writeOp(OpCode.OP_NEGATE, currentLine);
}
void compileSubtract(Form[] args) {
resolve(args[0]);
+ func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, currentLine);
for (int i = 1; i < args.length; i++) {
resolve(args[i]);
- func.chunk.writeOp(OpCode.OP_SUBTRACT, current.line);
+ func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, currentLine);
+ func.chunk.writeOp(OpCode.OP_SUBTRACT, currentLine);
}
}
@@ -80,8 +91,10 @@ class Compiler {
return;
}
resolve(args[0]);
+ func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, currentLine);
resolve(args[1]);
- func.chunk.writeOp(OpCode.OP_LESS, current.line);
+ func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, currentLine);
+ func.chunk.writeOp(OpCode.OP_LESS, currentLine);
}
//int parseVariable(Def def) {
@@ -142,7 +155,7 @@ class Compiler {
// are we setting a local?
if (this.scopeDepth > 0) {
- func.chunk.writeOp(OpCode.OP_DEF_LOCAL, current.line);
+ func.chunk.writeOp(OpCode.OP_DEF_LOCAL, def.line);
}
// define the variable
@@ -195,9 +208,11 @@ class Compiler {
}
void compileIf(Form form) {
+ writeln("compiling if...");
If if_ = cast(If)form;
resolve(if_.cond);
+ func.chunk.writeOp(OpCode.OP_TYPE_CHECK_BOOLEAN, if_.line);
int thenJump = jump(OpCode.OP_JUMP_IF_FALSE);
this.func.chunk.writeOp(OpCode.OP_POP, if_.line);
@@ -221,12 +236,15 @@ class Compiler {
And and_ = cast(And)form;
resolve(and_.clauses[0]);
+ func.chunk.writeOp(OpCode.OP_TYPE_CHECK_BOOLEAN, currentLine);
+
int[] jumps;
jumps ~= jump(OpCode.OP_JUMP_IF_FALSE);
int count = 1;
while (count < and_.clauses.length) {
- this.func.chunk.writeOp(OpCode.OP_POP, and_.line);
+ this.func.chunk.writeOp(OpCode.OP_POP, currentLine);
resolve(and_.clauses[count]);
+ func.chunk.writeOp(OpCode.OP_TYPE_CHECK_BOOLEAN, currentLine);
jumps ~= jump(OpCode.OP_JUMP_IF_FALSE);
count++;
}
@@ -241,12 +259,14 @@ class Compiler {
Or or_ = cast(Or)form;
resolve(or_.clauses[0]);
+ func.chunk.writeOp(OpCode.OP_TYPE_CHECK_BOOLEAN, currentLine);
int[] jumps;
jumps ~= jump(OpCode.OP_JUMP_IF_TRUE);
int count = 1;
while (count < or_.clauses.length) {
this.func.chunk.writeOp(OpCode.OP_POP, or_.line);
resolve(or_.clauses[count]);
+ func.chunk.writeOp(OpCode.OP_TYPE_CHECK_BOOLEAN, currentLine);
jumps ~= jump(OpCode.OP_JUMP_IF_TRUE);
count++;
}
@@ -261,7 +281,9 @@ class Compiler {
Block block = cast(Block)form;
beginScope();
foreach (Form inner; block.blockBody) {
+ writeln("about to compile an inner form");
resolve(inner);
+ writeln("finished compiling inner form");
}
endScope();
}
@@ -292,6 +314,7 @@ class Compiler {
}
void compileFunc(Form form) {
+ writeln("compiling func");
Func f = cast(Func)form;
// name the function
@@ -312,6 +335,8 @@ class Compiler {
}
}
+ writeln("got the arguments");
+
/*
// compile each inner Form
foreach (Form inner; f.funcBody) {
@@ -325,6 +350,8 @@ class Compiler {
b.blockBody = f.funcBody;
compiler.compileBlock(b);
+ writeln("compiled the body");
+
// write the function as a Value
Function outFunc = compiler.finish();
func.chunk.writeOp(OpCode.OP_CONSTANT, f.line);
@@ -373,6 +400,7 @@ class Compiler {
void resolve(Form form) {
//printForm(form);
+ currentLine = form.line;
switch(form.type) {
case FormType.ATOM:
this.compileAtom(form);
@@ -423,7 +451,7 @@ class Compiler {
Function finish() {
this.func.chunk.writeOp(OpCode.OP_RETURN, current.line);
- //disassembleChunk(func.chunk, to!string(func));
+ disassembleChunk(func.chunk, to!string(func));
return this.func;
}