aboutsummaryrefslogtreecommitdiff
path: root/parser.d
diff options
context:
space:
mode:
authorBen Winston2023-05-21 16:20:41 -0400
committerBen Winston2023-05-21 16:20:41 -0400
commit618de4c70d8916f64781997f3ae538e3e6109d00 (patch)
treebcd8ee70d82402407399a49c9cf6914858bd9449 /parser.d
parentb1183af95f45ba0162a91f7a308a4846418f03be (diff)
if/else, 'and' control flow
Diffstat (limited to 'parser.d')
-rw-r--r--parser.d94
1 files changed, 85 insertions, 9 deletions
diff --git a/parser.d b/parser.d
index 80e1626..3dd32ef 100644
--- a/parser.d
+++ b/parser.d
@@ -14,6 +14,8 @@ enum FormType {
FUNC,
DEF,
BLOCK,
+ IF,
+ AND,
EOF,
PARSE_ERROR
@@ -134,6 +136,46 @@ class Cons : Form {
}
}
+class If : Form {
+
+ Form cond;
+ Form thenForm;
+ Form elseForm;
+ bool hasElse;
+
+ this(int line, Form cond, Form then) {
+ this.line = line;
+ this.type = FormType.IF;
+ this.cond = cond;
+ this.thenForm = then;
+ this.hasElse = false;
+ }
+
+ this(int line, Form cond, Form then, Form else_) {
+ this.line = line;
+ this.type = FormType.IF;
+ this.cond = cond;
+ this.thenForm = then;
+ this.elseForm = else_;
+ this.hasElse = true;
+ }
+
+}
+
+class And : Form {
+
+ Form[] clauses;
+
+ this(int line) {
+ this.line = line;
+ this.type = FormType.AND;
+ }
+
+ void addClause(Form clause) {
+ clauses ~= clause;
+ }
+}
+
class Func : Form {
Symbol name;
@@ -252,7 +294,6 @@ class Parser {
int line;
bool peekable() {
- writefln("pos %d source %d", pos, source.length);
return (pos < source.length);
}
@@ -260,14 +301,14 @@ class Parser {
if (pos < source.length) {
return source[pos];
} else {
- writeln("peek returns null");
+ //writeln("peek returns null");
return '\0';
}
}
char advance() {
if (!peekable()) {
- writeln("trying to advance() beyond the end!!!");
+ //writeln("trying to advance() beyond the end!!!");
return '\0';
} else {
char ret = peek();
@@ -288,7 +329,6 @@ class Parser {
if (peek() == '\n') {
line++;
}
- //pos++;
advance();
}
}
@@ -365,8 +405,6 @@ class Parser {
advance(); // closing paren
- writefln("ending DEF pos %d", pos);
-
return def;
}
@@ -405,6 +443,43 @@ class Parser {
return func;
}
+ Form parseIf() {
+ If if_;
+ Form cond = parseForm();
+ Form then = parseForm();
+ if(peekable() && peek() == ')') {
+ if_ = new If(cond.line, cond, then);
+ } else {
+ Form else_ = parseForm();
+ if_ = new If(cond.line, cond, then, else_);
+ }
+
+ advance(); // consume closing paren
+
+ return if_;
+ }
+
+ Form parseAnd() {
+ And and_ = new And(line);
+ char next;
+ while(peekable()) {
+ next = peek();
+ if (next == ')') {
+ break;
+ }
+ and_.addClause(parseForm());
+ }
+
+ if (!peekable()) {
+ return new ParseError("unterminated and", line);
+ }
+
+ advance(); // consume closing paren
+
+ return and_;
+
+ }
+
Form parseBlock() {
Block block = new Block(line);
char next;
@@ -420,7 +495,6 @@ class Parser {
return new ParseError("unterminated block", line);
}
- writefln("ending block pos %d", pos);
advance(); // consume closing paren
return block;
@@ -448,6 +522,10 @@ class Parser {
return parseDef();
case "block":
return parseBlock();
+ case "if":
+ return parseIf();
+ case "and":
+ return parseAnd();
default:
break;
}
@@ -496,8 +574,6 @@ class Parser {
return parseSymbol();
}
- writeln("FELL THROUGH ON PARSE FORM");
-
advance();
return new Atom(0, -1);