aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormryouse2023-06-07 22:52:09 -0400
committermryouse2023-06-07 22:52:09 -0400
commitfbc75bca57a3f66006468fb1a8f3988cdc8227d2 (patch)
tree48c37fe529dcb55d2bd8516841c516d799ef05a9
parent730a6d777530a33fbb8df86df8b16d842b12c283 (diff)
initial commit of branch
-rw-r--r--compiler.d38
-rw-r--r--parser.d38
2 files changed, 76 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;
diff --git a/parser.d b/parser.d
index 004e1fb..0b31be8 100644
--- a/parser.d
+++ b/parser.d
@@ -17,6 +17,7 @@ enum FormType {
DEF,
BLOCK,
IF,
+ BRANCH,
AND,
OR,
@@ -157,6 +158,20 @@ class If : Form {
}
+class Branch : Form {
+
+ Form[] clauses;
+
+ this(int line) {
+ this.line = line;
+ this.type = FormType.BRANCH;
+ }
+
+ void addClause(Form clause) {
+ this.clauses ~= clause;
+ }
+}
+
class And : Form {
Form[] clauses;
@@ -605,6 +620,27 @@ class Parser {
return if_;
}
+ Form parseBranch() {
+ Branch branch = new Branch(-1);
+ Form f;
+ char next;
+ while(peekable()) {
+ next = peek();
+ if (next == ')') {
+ break;
+ }
+ branch.addClause(parseForm());
+ }
+
+ if (!peekable()) {
+ return new ParseError("unterminated branch", line);
+ }
+
+ advance(); // consume closing paren
+
+ return branch;
+ }
+
Form parseAnd() {
And and_ = new And(line);
char next;
@@ -691,6 +727,8 @@ class Parser {
return parseBlock();
case "if":
return parseIf();
+ case "branch":
+ return parseBranch();
case "and":
return parseAnd();
case "or":