diff options
Diffstat (limited to 'compiler.d')
| -rw-r--r-- | compiler.d | 258 |
1 files changed, 129 insertions, 129 deletions
@@ -34,7 +34,7 @@ class Compiler { int outerIdx; void advance() { - previous = current; + this.previous = this.current; /* if (outer.type != FormType.EOF && outerIdx < outer) { current = parser.parseForm(); @@ -42,12 +42,12 @@ class Compiler { } */ - current = parser.parseForm(); + this.current = this.parser.parseForm(); } void compileNil(Form form) { - form.compile(func); - advance(); + form.compile(this.func); + this.advance(); } TC typeCheck(ValueType actual, ValueType expecting) { @@ -120,8 +120,8 @@ class Compiler { } } */ - TC tc = typeCheck(atom.value.type, expecting); - form.compile(func); + TC tc = this.typeCheck(atom.value.type, expecting); + form.compile(this.func); //if (tc.exact) { //} else if (tc.maybe) { @@ -135,7 +135,7 @@ class Compiler { } */ - advance(); + this.advance(); @@ -180,8 +180,8 @@ 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); + this.resolve(args[0], expecting); + this.func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, line); // (+ n) always returns n if (args.length == 1) { @@ -189,26 +189,26 @@ 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_ADD, line); + this.resolve(args[i], expecting); + this.func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, line); + this.func.chunk.writeOp(OpCode.OP_ADD, line); } } void compileNegate(Form arg) { - resolve(arg); - func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, currentLine); - func.chunk.writeOp(OpCode.OP_NEGATE, currentLine); + this.resolve(arg); + this.func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, arg.line); + this.func.chunk.writeOp(OpCode.OP_NEGATE, arg.line); } ValueType compileSubtract(Form[] args, ValueType expected) { ValueType vt; - vt = resolve(args[0], expected); - func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, currentLine); + vt = this.resolve(args[0], expected); + this.func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, args[0].line); for (int i = 1; i < args.length; i++) { - vt = resolve(args[i], expected); - func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, currentLine); - func.chunk.writeOp(OpCode.OP_SUBTRACT, currentLine); + vt = this.resolve(args[i], expected); + this.func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, args[i].line); + this.func.chunk.writeOp(OpCode.OP_SUBTRACT, args[i].line); } return ValueType.NUMBER; } @@ -217,10 +217,10 @@ class Compiler { ValueType compileLess(Form[] args, ValueType expected) { if (args.length != 2) { writeln("'<' requires 2 arguments"); - advance(); + this.advance(); return ValueType.NIL; } - ValueType vt1 = resolve(args[0], ValueType.NUMBER); + ValueType vt1 = this.resolve(args[0], ValueType.NUMBER); /* TC tc1 = typeCheck(vt1, expected); if (tc1.maybe) { @@ -229,9 +229,9 @@ class Compiler { writeln("COMPILE ERROR: bad type (less)"); } */ - func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, currentLine); + this.func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, args[0].line); - ValueType vt2 = resolve(args[1], ValueType.NUMBER); + ValueType vt2 = this.resolve(args[1], ValueType.NUMBER); /* TC tc2 = typeCheck(vt2, expected); if (tc2.maybe) { @@ -240,14 +240,14 @@ class Compiler { writeln("COMPILE ERROR: bad type (less)"); } */ - func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, currentLine); + this.func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, args[1].line); //ValueType vt1 = resolve(args[0], expected); //func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, currentLine); //ValueType vt2 = resolve(args[1], expected); //func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, currentLine); - func.chunk.writeOp(OpCode.OP_LESS, currentLine); + this.func.chunk.writeOp(OpCode.OP_LESS, args[1].line); // this should probably return a ValueType return ValueType.BOOLEAN; @@ -256,16 +256,16 @@ class Compiler { ValueType compileGreater(Form[] args) { if (args.length != 2) { writeln("'>' requires 2 arguments"); - advance(); + this.advance(); return ValueType.NIL; } - ValueType vt1 = resolve(args[0], ValueType.NUMBER); - func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, currentLine); + ValueType vt1 = this.resolve(args[0], ValueType.NUMBER); + this.func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, args[0].line); - ValueType vt2 = resolve(args[1], ValueType.NUMBER); - func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, currentLine); + ValueType vt2 = this.resolve(args[1], ValueType.NUMBER); + this.func.chunk.writeOp(OpCode.OP_TYPE_CHECK_NUMBER, args[1].line); - func.chunk.writeOp(OpCode.OP_GREATER, currentLine); + this.func.chunk.writeOp(OpCode.OP_GREATER, args[1].line); // this should probably return a ValueType return ValueType.BOOLEAN; @@ -275,12 +275,12 @@ class Compiler { //int parseVariable(Def def) { int parseVariable(Symbol sym) { - declareVariable(sym); + this.declareVariable(sym); if (this.scopeDepth > 0) { return 0; } - int addr = func.chunk.addConstant(makeStringValue(sym.name)); + int addr = this.func.chunk.addConstant(makeStringValue(sym.name)); return addr; } @@ -288,8 +288,8 @@ class Compiler { if (this.scopeDepth > 0) { return; } - func.chunk.writeOp(OpCode.OP_DEF_GLOBAL, current.line); - func.chunk.writeOp(to!ubyte(addr), current.line); + this.func.chunk.writeOp(OpCode.OP_DEF_GLOBAL, this.current.line); + this.func.chunk.writeOp(to!ubyte(addr), this.current.line); } void declareVariable(Symbol sym) { @@ -298,8 +298,8 @@ class Compiler { return; } - for (int i = localCount - 1; i >= 0; i--) { - Local local = locals[i]; + for (int i = this.localCount - 1; i >= 0; i--) { + Local local = this.locals[i]; if (local.depth != -1 && local.depth < this.scopeDepth) { break; } @@ -311,30 +311,30 @@ class Compiler { } Local loc = Local(sym, this.scopeDepth); - if (localCount == locals.length) { - locals ~= loc; + if (this.localCount == this.locals.length) { + this.locals ~= loc; } else { - locals[localCount] = loc; + this.locals[this.localCount] = loc; } - localCount++; + this.localCount++; } void compileDef(Form form, ValueType expecting) { Def def = cast(Def)form; // resolve the value - resolve(def.val, expecting); + this.resolve(def.val, expecting); // add the variable name to the chunk (if applicable) - int addr = parseVariable(def.name); + int addr = this.parseVariable(def.name); // are we setting a local? if (this.scopeDepth > 0) { - func.chunk.writeOp(OpCode.OP_DEF_LOCAL, def.line); + this.func.chunk.writeOp(OpCode.OP_DEF_LOCAL, def.line); } // define the variable - defineVariable(addr); + this.defineVariable(addr); } /* @@ -345,8 +345,8 @@ class Compiler { */ int resolveLocal(Symbol sym) { - for (int i = localCount - 1; i >= 0; i--) { - Local local = locals[i]; + for (int i = this.localCount - 1; i >= 0; i--) { + Local local = this.locals[i]; if (local.sym.name == sym.name) { return i; } @@ -363,7 +363,7 @@ class Compiler { } Symbol sym = cast(Symbol)form; - int arg = resolveLocal(sym); + int arg = this.resolveLocal(sym); if (arg != -1) { this.func.chunk.writeOp(OpCode.OP_GET_LOCAL, sym.line); } else { @@ -376,19 +376,19 @@ class Compiler { // get the variable this.func.chunk.writeOp(to!ubyte(arg), sym.line); - advance(); + this.advance(); } int jump(OpCode type) { - func.chunk.writeOp(to!ubyte(type), current.line); - func.chunk.writeOp(0xff, current.line); - func.chunk.writeOp(0xff, current.line); - return to!int(func.chunk.code.length) - 2; + this.func.chunk.writeOp(to!ubyte(type), this.current.line); + this.func.chunk.writeOp(0xff, this.current.line); + this.func.chunk.writeOp(0xff, this.current.line); + return to!int(this.func.chunk.code.length) - 2; } void patchJump(int offset) { // additional -2 to account for the 2 byte jump itself - int jmp = to!int(func.chunk.code.length) - offset - 2; + int jmp = to!int(this.func.chunk.code.length) - offset - 2; // TODO check to make sure we didn't jump too far? @@ -399,96 +399,96 @@ class Compiler { void compileIf(Form form) { If if_ = cast(If)form; - resolve(if_.cond); - func.chunk.writeOp(OpCode.OP_TYPE_CHECK_BOOLEAN, if_.line); + this.resolve(if_.cond); + this.func.chunk.writeOp(OpCode.OP_TYPE_CHECK_BOOLEAN, if_.line); - int thenJump = jump(OpCode.OP_JUMP_IF_FALSE); + int thenJump = this.jump(OpCode.OP_JUMP_IF_FALSE); this.func.chunk.writeOp(OpCode.OP_POP, if_.line); - resolve(if_.thenForm); + this.resolve(if_.thenForm); - int elseJump = jump(OpCode.OP_JUMP); + int elseJump = this.jump(OpCode.OP_JUMP); - patchJump(thenJump); + this.patchJump(thenJump); this.func.chunk.writeOp(OpCode.OP_POP, if_.line); if (if_.hasElse) { - resolve(if_.elseForm); + this.resolve(if_.elseForm); } - patchJump(elseJump); + this.patchJump(elseJump); } void compileAnd(Form form) { And and_ = cast(And)form; - resolve(and_.clauses[0]); - func.chunk.writeOp(OpCode.OP_TYPE_CHECK_BOOLEAN, currentLine); + this.resolve(and_.clauses[0]); + this.func.chunk.writeOp(OpCode.OP_TYPE_CHECK_BOOLEAN, and_.clauses[0].line); int[] jumps; - jumps ~= jump(OpCode.OP_JUMP_IF_FALSE); + jumps ~= this.jump(OpCode.OP_JUMP_IF_FALSE); int count = 1; while (count < and_.clauses.length) { - 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); + this.func.chunk.writeOp(OpCode.OP_POP, and_.clauses[count].line); + this.resolve(and_.clauses[count]); + this.func.chunk.writeOp(OpCode.OP_TYPE_CHECK_BOOLEAN, and_.clauses[count].line); + jumps ~= this.jump(OpCode.OP_JUMP_IF_FALSE); count++; } // patch all the jumps foreach (int jmp; jumps) { - patchJump(jmp); + this.patchJump(jmp); } } void compileOr(Form form) { Or or_ = cast(Or)form; - resolve(or_.clauses[0]); - func.chunk.writeOp(OpCode.OP_TYPE_CHECK_BOOLEAN, currentLine); + this.resolve(or_.clauses[0]); + this.func.chunk.writeOp(OpCode.OP_TYPE_CHECK_BOOLEAN, or_.clauses[0].line); int[] jumps; - jumps ~= jump(OpCode.OP_JUMP_IF_TRUE); + jumps ~= this.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); + this.func.chunk.writeOp(OpCode.OP_POP, or_.clauses[count].line); + this.resolve(or_.clauses[count]); + this.func.chunk.writeOp(OpCode.OP_TYPE_CHECK_BOOLEAN, or_.clauses[count].line); + jumps ~= this.jump(OpCode.OP_JUMP_IF_TRUE); count++; } // patch all the jumps foreach (int jmp; jumps) { - patchJump(jmp); + this.patchJump(jmp); } } ValueType compileNot(Form[] args) { - ValueType vt = resolve(args[0], ValueType.BOOLEAN); - func.chunk.writeOp(OpCode.OP_TYPE_CHECK_BOOLEAN, currentLine); - func.chunk.writeOp(OpCode.OP_NOT, currentLine); + ValueType vt = this.resolve(args[0], ValueType.BOOLEAN); + this.func.chunk.writeOp(OpCode.OP_TYPE_CHECK_BOOLEAN, args[0].line); + this.func.chunk.writeOp(OpCode.OP_NOT, args[0].line); return vt; } ValueType compileConcat(Form[] args) { - ValueType vt = resolve(args[0], ValueType.STRING); + ValueType vt = this.resolve(args[0], ValueType.STRING); for (int i = 1; i < args.length; i++) { - vt = resolve(args[i], ValueType.STRING); - func.chunk.writeOp(OpCode.OP_TYPE_CHECK_STRING, currentLine); - func.chunk.writeOp(OpCode.OP_CONCAT, currentLine); + vt = this.resolve(args[i], ValueType.STRING); + this.func.chunk.writeOp(OpCode.OP_TYPE_CHECK_STRING, args[i].line); + this.func.chunk.writeOp(OpCode.OP_CONCAT, args[i].line); } return ValueType.STRING; } void compileBlock(Form form) { Block block = cast(Block)form; - beginScope(); + this.beginScope(); foreach (Form inner; block.blockBody) { - resolve(inner); + this.resolve(inner); } - endScope(); + this.endScope(); } void beginScope() { @@ -499,21 +499,21 @@ class Compiler { this.scopeDepth--; - while (localCount > 0 && - locals[localCount - 1].depth > this.scopeDepth) { - func.chunk.writeOp(OpCode.OP_POPB, -1); - localCount--; + while (this.localCount > 0 && + this.locals[this.localCount - 1].depth > this.scopeDepth) { + this.func.chunk.writeOp(OpCode.OP_POPB, -1); + this.localCount--; } } void call(Form[] args) { //ubyte argCount = argumentList(); foreach (Form f ; args) { - resolve(f); + this.resolve(f); } - func.chunk.writeOp(OpCode.OP_CALL, -1); + this.func.chunk.writeOp(OpCode.OP_CALL, -1); //func.chunk.writeOp(argCount, -1); - func.chunk.writeOp(to!ubyte(args.length), -1); + this.func.chunk.writeOp(to!ubyte(args.length), -1); } void compileList(Form[] args) { @@ -521,7 +521,7 @@ class Compiler { ValueType vt; int addr; foreach (Form arg ; args) { - vt = resolve(arg, ValueType.ANY); + vt = this.resolve(arg, ValueType.ANY); // how do we get at the address? addr = to!int(this.func.chunk.constants.length) - 1; // this is probably often wrong lst.addItem(addr); @@ -543,7 +543,7 @@ class Compiler { writeln("COMPILE ERROR: 'first' expects exactly one argument"); return; } - ValueType vt = resolve(args[0], ValueType.OBJ); // TODO need a new type + ValueType vt = this.resolve(args[0], ValueType.OBJ); // TODO need a new type this.func.chunk.writeOp(OpCode.OP_TYPE_CHECK_LIST, args[0].line); // pop the value off the stack @@ -558,9 +558,9 @@ class Compiler { Func f = cast(Func)form; // name the function - int global = parseVariable(f.name); + int global = this.parseVariable(f.name); - Compiler compiler = new Compiler(ObjType.FUNCTION, parser, f.name.name); + Compiler compiler = new Compiler(ObjType.FUNCTION, this.parser, f.name.name); compiler.beginScope(); if (f.args.type != FormType.NIL) { @@ -590,12 +590,12 @@ class Compiler { // write the function as a Value Function outFunc = compiler.finish(); - func.chunk.writeOp(OpCode.OP_CONSTANT, f.line); - int funcAddr = func.chunk.addConstant(makeObjValue(outFunc)); - func.chunk.writeOp(to!ubyte(funcAddr), f.line); + this.func.chunk.writeOp(OpCode.OP_CONSTANT, f.line); + int funcAddr = this.func.chunk.addConstant(makeObjValue(outFunc)); + this.func.chunk.writeOp(to!ubyte(funcAddr), f.line); // define the global variable - defineVariable(global); + this.defineVariable(global); } ValueType compileCons(Form form, ValueType expected) { @@ -603,59 +603,59 @@ class Compiler { Form head = cons.head; if (head.type != FormType.SYMBOL) { writeln("cons must start with a symbol"); - advance(); + this.advance(); return ValueType.NIL; } Symbol sym = cast(Symbol)head; switch (sym.name) { case "+": - compileAdd(cons.tail, ValueType.NUMBER); + this.compileAdd(cons.tail, ValueType.NUMBER); break; case "-": if (cons.tail.length == 1) { - compileNegate(cons.tail[0]); + this.compileNegate(cons.tail[0]); } else { - return compileSubtract(cons.tail, ValueType.NUMBER); + return this.compileSubtract(cons.tail, ValueType.NUMBER); } break; case "<": - return compileLess(cons.tail, ValueType.NUMBER); + return this.compileLess(cons.tail, ValueType.NUMBER); break; case "<=": - ValueType vt = compileGreater(cons.tail); - func.chunk.writeOp(OpCode.OP_NOT, cons.line); + ValueType vt = this.compileGreater(cons.tail); + this.func.chunk.writeOp(OpCode.OP_NOT, cons.line); return vt; case ">": - return compileGreater(cons.tail); + return this.compileGreater(cons.tail); break; case ">=": - ValueType vt = compileLess(cons.tail, ValueType.NUMBER); - func.chunk.writeOp(OpCode.OP_NOT, cons.line); + ValueType vt = this.compileLess(cons.tail, ValueType.NUMBER); + this.func.chunk.writeOp(OpCode.OP_NOT, cons.line); return vt; case "not": - return compileNot(cons.tail); + return this.compileNot(cons.tail); // STRINGS case "concat": - return compileConcat(cons.tail); + return this.compileConcat(cons.tail); // LISTS case "first": - compileFirst(cons.tail); + this.compileFirst(cons.tail); break; case "list": //return compileList(cons.tail); - compileList(cons.tail); + this.compileList(cons.tail); break; default: /* writefln("unsure how to compile %s", sym.name); advance(); */ - resolve(head); - call(cons.tail); - advance(); + this.resolve(head); + this.call(cons.tail); + this.advance(); break; } return ValueType.NIL; @@ -664,7 +664,7 @@ class Compiler { ValueType resolve(Form form, const ValueType expecting = ValueType.ANY) { //printForm(form); - currentLine = form.line; + this.currentLine = form.line; switch(form.type) { case FormType.ATOM: this.compileAtom(form, expecting); @@ -699,23 +699,23 @@ class Compiler { default: write("not sure how to resolve: "); printForm(form); - advance(); + this.advance(); break; } return ValueType.NIL; } Function compile() { - advance(); + this.advance(); while(current.type != FormType.EOF) { - resolve(current); + this.resolve(current); } - return finish(); + return this.finish(); } Function finish() { - this.func.chunk.writeOp(OpCode.OP_RETURN, current.line); + this.func.chunk.writeOp(OpCode.OP_RETURN, this.current.line); if (DEBUG) { disassembleChunk(this.func.chunk, to!string(func)); } @@ -727,7 +727,7 @@ class Compiler { this.func = new Function(type, name); //localCount = 0; - locals ~= Local(new Symbol("", -1), 0); - localCount++; + this.locals ~= Local(new Symbol("", -1), 0); + this.localCount++; } } |
