diff options
Diffstat (limited to 'compiler.d')
| -rw-r--r-- | compiler.d | 86 |
1 files changed, 72 insertions, 14 deletions
@@ -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); |
