aboutsummaryrefslogtreecommitdiff
path: root/compiler.d
diff options
context:
space:
mode:
Diffstat (limited to 'compiler.d')
-rw-r--r--compiler.d94
1 files changed, 77 insertions, 17 deletions
diff --git a/compiler.d b/compiler.d
index ae4cb4a..0c6611c 100644
--- a/compiler.d
+++ b/compiler.d
@@ -84,19 +84,20 @@ class Compiler {
func.chunk.writeOp(OpCode.OP_LESS, current.line);
}
- int parseVariable(Def def) {
+ //int parseVariable(Def def) {
+ int parseVariable(Symbol sym) {
- declareVariable(def.name);
- if (scopeDepth > 0) {
+ declareVariable(sym);
+ if (this.scopeDepth > 0) {
return 0;
}
- int addr = func.chunk.addConstant(makeStringValue(def.name.name));
+ int addr = func.chunk.addConstant(makeStringValue(sym.name));
return addr;
}
void defineVariable(int addr) {
- if (scopeDepth > 0) {
+ if (this.scopeDepth > 0) {
return;
}
func.chunk.writeOp(OpCode.OP_DEF_GLOBAL, current.line);
@@ -105,13 +106,13 @@ class Compiler {
void declareVariable(Symbol sym) {
- if (scopeDepth == 0) {
+ if (this.scopeDepth == 0) {
return;
}
for (int i = localCount - 1; i >= 0; i--) {
Local local = locals[i];
- if (local.depth != -1 && local.depth < scopeDepth) {
+ if (local.depth != -1 && local.depth < this.scopeDepth) {
break;
}
@@ -121,7 +122,7 @@ class Compiler {
}
}
- Local loc = Local(sym, scopeDepth);
+ Local loc = Local(sym, this.scopeDepth);
if (localCount == locals.length) {
locals ~= loc;
} else {
@@ -137,10 +138,10 @@ class Compiler {
resolve(def.val);
// add the variable name to the chunk (if applicable)
- int addr = parseVariable(def);
+ int addr = parseVariable(def.name);
// are we setting a local?
- if (scopeDepth > 0) {
+ if (this.scopeDepth > 0) {
func.chunk.writeOp(OpCode.OP_DEF_LOCAL, current.line);
}
@@ -266,20 +267,74 @@ class Compiler {
}
void beginScope() {
- scopeDepth++;
+ this.scopeDepth++;
}
void endScope() {
- scopeDepth--;
+ this.scopeDepth--;
while (localCount > 0 &&
- locals[localCount - 1].depth > scopeDepth) {
+ locals[localCount - 1].depth > this.scopeDepth) {
func.chunk.writeOp(OpCode.OP_POPB, -1);
localCount--;
}
}
+ void call(Form[] args) {
+ //ubyte argCount = argumentList();
+ foreach (Form f ; args) {
+ resolve(f);
+ }
+ func.chunk.writeOp(OpCode.OP_CALL, -1);
+ //func.chunk.writeOp(argCount, -1);
+ func.chunk.writeOp(to!ubyte(args.length), -1);
+ }
+
+ void compileFunc(Form form) {
+ Func f = cast(Func)form;
+
+ // name the function
+ int global = parseVariable(f.name);
+
+ Compiler compiler = new Compiler(ObjType.FUNCTION, parser, f.name.name);
+ compiler.beginScope();
+
+ if (f.args.type != FormType.NIL) {
+ Symbol sym = cast(Symbol)f.args.head;
+ int constant = compiler.parseVariable(sym);
+ compiler.defineVariable(constant);
+
+ foreach (Form inner ; f.args.tail) {
+ sym = cast(Symbol)inner;
+ constant = compiler.parseVariable(sym);
+ compiler.defineVariable(constant);
+ }
+ }
+
+ /*
+ // compile each inner Form
+ foreach (Form inner; f.funcBody) {
+ compiler.resolve(inner);
+ }
+ */
+
+ advance(); // ??
+
+ Block b = new Block(f.line);
+ b.blockBody = f.funcBody;
+ compiler.compileBlock(b);
+
+ // 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);
+
+ // define the global variable
+ defineVariable(global);
+ }
+
void compileCons(Form form) {
Cons cons = cast(Cons)form;
Form head = cons.head;
@@ -309,6 +364,8 @@ class Compiler {
advance();
*/
resolve(head);
+ call(cons.tail);
+ advance();
break;
}
@@ -344,6 +401,9 @@ class Compiler {
case FormType.OR:
this.compileOr(form);
break;
+ case FormType.FUNC:
+ this.compileFunc(form);
+ break;
default:
write("not sure how to resolve: ");
printForm(form);
@@ -363,13 +423,13 @@ class Compiler {
Function finish() {
this.func.chunk.writeOp(OpCode.OP_RETURN, current.line);
- disassembleChunk(func.chunk, to!string(func));
- return func;
+ //disassembleChunk(func.chunk, to!string(func));
+ return this.func;
}
- this(ObjType type, Parser* parser) {
+ this(ObjType type, Parser* parser, string name = "") {
this.parser = parser;
- this.func = new Function(type);
+ this.func = new Function(type, name);
//localCount = 0;
locals ~= Local(new Symbol("", -1), 0);