diff options
| author | Ben Winston | 2023-05-21 23:50:04 -0400 |
|---|---|---|
| committer | Ben Winston | 2023-05-21 23:50:04 -0400 |
| commit | 03b4987afc5e32ec560fac6f74c153d592f75259 (patch) | |
| tree | ca29375c89260d7678e7b173bd663327170533f5 /compiler.d | |
| parent | 8e1f84b1369909745859777d07a5e8e74b5df334 (diff) | |
functionsgit add *.d!
Diffstat (limited to 'compiler.d')
| -rw-r--r-- | compiler.d | 94 |
1 files changed, 77 insertions, 17 deletions
@@ -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); |
