diff options
Diffstat (limited to 'parser.d')
| -rw-r--r-- | parser.d | 94 |
1 files changed, 85 insertions, 9 deletions
@@ -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); |
