aboutsummaryrefslogtreecommitdiff
path: root/compiler.d
diff options
context:
space:
mode:
Diffstat (limited to 'compiler.d')
-rw-r--r--compiler.d258
1 files changed, 129 insertions, 129 deletions
diff --git a/compiler.d b/compiler.d
index 3b684d4..665fe61 100644
--- a/compiler.d
+++ b/compiler.d
@@ -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++;
}
}