aboutsummaryrefslogtreecommitdiff
path: root/compiler.d
diff options
context:
space:
mode:
Diffstat (limited to 'compiler.d')
-rw-r--r--compiler.d38
1 files changed, 38 insertions, 0 deletions
diff --git a/compiler.d b/compiler.d
index 675ec4c..8cb65ee 100644
--- a/compiler.d
+++ b/compiler.d
@@ -83,6 +83,41 @@ class Compiler {
}
}
+ void compileBranch(Form form) {
+
+ Branch branch = cast(Branch)form;
+
+ Cons clause;
+ int[] endJumps;
+ int currentJump;
+ foreach (Form cl ; branch.clauses) {
+ // resolve the condition
+ clause = cast(Cons)cl;
+ this.resolve(clause.head);
+ this.func.chunk.writeOp(OpCode.OP_TYPE_CHECK_BOOLEAN, clause.line);
+
+ // write a jump spot and pop
+ currentJump = this.jump(OpCode.OP_JUMP_IF_FALSE);
+ this.func.chunk.writeOp(OpCode.OP_POP, clause.line);
+
+ // resolve the result of the condition (only executes if true)
+ foreach (Form f ; clause.tail) {
+ this.resolve(f);
+ }
+
+ // jump to the end (if we got here)
+ endJumps ~= this.jump(OpCode.OP_JUMP);
+
+ // this is where we jump to if the condition was false
+ this.patchJump(currentJump);
+ }
+
+ // patch all the end jumps
+ foreach (int jmp; endJumps) {
+ this.patchJump(jmp);
+ }
+ }
+
void compileIf(Form form) {
If if_ = cast(If)form;
@@ -908,6 +943,9 @@ class Compiler {
case FormType.IF:
this.compileIf(form);
break;
+ case FormType.BRANCH:
+ this.compileBranch(form);
+ break;
case FormType.AND:
this.compileAnd(form);
break;