aboutsummaryrefslogtreecommitdiff
path: root/compiler.d
diff options
context:
space:
mode:
Diffstat (limited to 'compiler.d')
-rw-r--r--compiler.d86
1 files changed, 72 insertions, 14 deletions
diff --git a/compiler.d b/compiler.d
index 0125dc5..ee9fcef 100644
--- a/compiler.d
+++ b/compiler.d
@@ -53,7 +53,7 @@ class Compiler {
TC typeCheck(ValueType actual, ValueType expecting) {
TC ret = { false, false, OpCode.OP_NIL };
if (actual == expecting) {
- writeln("good types");
+ //writeln("good types");
ret.exact = true;
return ret;
} else if (actual == ValueType.ANY) {
@@ -125,6 +125,7 @@ class Compiler {
//if (tc.exact) {
//} else if (tc.maybe) {
+ /*
if (tc.maybe) {
form.compile(func);
func.chunk.writeOp(to!ubyte(tc.op), atom.line);
@@ -132,6 +133,8 @@ class Compiler {
writefln("COMPILE ERROR: typecheck on line %d", atom.line);
//form.compile(func); // don't do this later
}
+ */
+
advance();
@@ -178,7 +181,7 @@ class Compiler {
void compileAdd(Form[] args, ValueType expecting) {
int line = args[0].line;
resolve(args[0], expecting);
- //func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, line);
+ func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, line);
// (+ n) always returns n
if (args.length == 1) {
@@ -187,7 +190,7 @@ class Compiler {
for (int i = 1; i < args.length; i++) {
resolve(args[i], expecting);
- //func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, line);
+ func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, line);
func.chunk.writeOp(OpCode.OP_ADD, line);
}
}
@@ -198,27 +201,51 @@ class Compiler {
func.chunk.writeOp(OpCode.OP_NEGATE, currentLine);
}
- void compileSubtract(Form[] args) {
- resolve(args[0]);
+ ValueType compileSubtract(Form[] args, ValueType expected) {
+ ValueType vt;
+ vt = resolve(args[0], expected);
func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, currentLine);
for (int i = 1; i < args.length; i++) {
- resolve(args[i]);
+ vt = resolve(args[i], expected);
func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, currentLine);
func.chunk.writeOp(OpCode.OP_SUBTRACT, currentLine);
}
+ return ValueType.NUMBER;
}
- ValueType compileLess(Form[] args, ValueType expected = ValueType.ANY) {
+ //ValueType compileLess(Form[] args, ValueType expected = ValueType.ANY) {
+ ValueType compileLess(Form[] args, ValueType expected) {
if (args.length != 2) {
writeln("'<' requires 2 arguments");
advance();
return ValueType.NIL;
}
- //ValueType vt1 = resolve(args[0], ValueType.NUMBER);
- ValueType vt1 = resolve(args[0], expected);
+ ValueType vt1 = resolve(args[0], ValueType.NUMBER);
+ /*
+ TC tc1 = typeCheck(vt1, expected);
+ if (tc1.maybe) {
+ func.chunk.writeOp(to!ubyte(tc1.op), currentLine);
+ } else if (!tc1.exact) {
+ writeln("COMPILE ERROR: bad type (less)");
+ }
+ */
+ func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, currentLine);
+
+ ValueType vt2 = resolve(args[1], ValueType.NUMBER);
+ /*
+ TC tc2 = typeCheck(vt2, expected);
+ if (tc2.maybe) {
+ func.chunk.writeOp(to!ubyte(tc2.op), currentLine);
+ } else if (!tc2.exact) {
+ writeln("COMPILE ERROR: bad type (less)");
+ }
+ */
+ func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, currentLine);
+
+
+ //ValueType vt1 = resolve(args[0], expected);
//func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, currentLine);
- //ValueType vt2 = resolve(args[1], ValueType.NUMBER);
- ValueType vt2 = resolve(args[1], expected);
+ //ValueType vt2 = resolve(args[1], expected);
//func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, currentLine);
func.chunk.writeOp(OpCode.OP_LESS, currentLine);
@@ -226,6 +253,25 @@ class Compiler {
return ValueType.BOOLEAN;
}
+ ValueType compileGreater(Form[] args) {
+ if (args.length != 2) {
+ writeln("'>' requires 2 arguments");
+ advance();
+ return ValueType.NIL;
+ }
+ ValueType vt1 = resolve(args[0], ValueType.NUMBER);
+ func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, currentLine);
+
+ ValueType vt2 = resolve(args[1], ValueType.NUMBER);
+ func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, currentLine);
+
+ func.chunk.writeOp(OpCode.OP_GREATER, currentLine);
+
+ // this should probably return a ValueType
+ return ValueType.BOOLEAN;
+ }
+
+
//int parseVariable(Def def) {
int parseVariable(Symbol sym) {
@@ -490,11 +536,12 @@ class Compiler {
defineVariable(global);
}
- ValueType compileCons(Form form, ValueType returnType = ValueType.ANY) {
+ ValueType compileCons(Form form, ValueType expected) {
Cons cons = cast(Cons)form;
Form head = cons.head;
if (head.type != FormType.SYMBOL) {
writeln("cons must start with a symbol");
+ advance();
return ValueType.NIL;
}
@@ -507,12 +554,23 @@ class Compiler {
if (cons.tail.length == 1) {
compileNegate(cons.tail[0]);
} else {
- compileSubtract(cons.tail);
+ return compileSubtract(cons.tail, ValueType.NUMBER);
}
break;
case "<":
- return compileLess(cons.tail);
+ return compileLess(cons.tail, ValueType.NUMBER);
+ break;
+ case "<=":
+ ValueType vt = compileGreater(cons.tail);
+ func.chunk.writeOp(OpCode.OP_NOT, cons.line);
+ return vt;
+ case ">":
+ return compileGreater(cons.tail);
break;
+ case ">=":
+ ValueType vt = compileLess(cons.tail, ValueType.NUMBER);
+ func.chunk.writeOp(OpCode.OP_NOT, cons.line);
+ return vt;
default:
/*
writefln("unsure how to compile %s", sym.name);