Mercurial > projects > dang
view ast/Stmt.d @ 44:495188f9078e new_gen
Big update - Moving towards a better, more seperated parser
The parser no loner creates the AST directly, but through
callbacks(actions). This means the parser can be run with a different set
of actions that do something else.
The parser is not back to full strength yet, the main thing missing is the
various statements and structs.
Also added a SmallArray that uses the stack only until a given size is
exceeded, after which the array is copied unto the heap.
author | Anders Halager <halager@gmail.com> |
---|---|
date | Wed, 23 Apr 2008 00:57:45 +0200 |
parents | ce17bea8e9bd |
children | 9bc660cbdbec |
line wrap: on
line source
module ast.Stmt; import Array = tango.core.Array, Integer = tango.text.convert.Integer; import ast.Exp, ast.Decl; import sema.SymbolTable, misc.Error; enum StmtType { Stmt, Compound, Decl, Exp, Return, If, While, Switch, } class Stmt { this(StmtType stmtType = StmtType.Stmt) { this.stmtType = stmtType; } StmtType stmtType; Scope env; } class CompoundStatement : Stmt { this(Stmt[] stmts) { super(StmtType.Compound); this.statements = stmts; } Stmt[] statements; } class ReturnStmt : Stmt { this() { super(StmtType.Return); } public Exp exp; } class DeclStmt : Stmt { this(Decl decl) { super(StmtType.Decl); this.decl = decl; } public Decl decl; } class ExpStmt : Stmt { this(Exp exp) { super(StmtType.Exp); this.exp = exp; } public Exp exp; } class IfStmt : Stmt { this(Exp cond, Stmt[] then, Stmt[] el = null) { super(StmtType.If); this.cond = cond; this.then_body = then; this.else_body = el; } Exp cond; Stmt[] then_body; Stmt[] else_body; } class WhileStmt : Stmt { this(Exp cond, Stmt[] stmts) { super(StmtType.While); this.cond = cond; this.stmts = stmts; } Exp cond; Stmt[] stmts; } class SwitchStmt : Stmt { this(Exp target) { super(StmtType.Switch); cond = target; } void addCase(IntegerLit[] values, Stmt[] stmts) { long[] new_values; foreach (lit; values) new_values ~= Integer.parse(lit.token.get); cases ~= Case(values, stmts, new_values); // Make sure there is no two cases with the same value // Does it belong here? new_values = new_values.dup; Array.sort(new_values); long[] all_values = Array.unionOf(old_values, new_values); if (all_values.length != old_values.length + new_values.length) { // overlap! auto e = new Error( "Can't have multiple cases with the same value." " Values appearing in multiple cases: %0"); e.loc(values[0].token.location); all_values = Array.intersectionOf(old_values, new_values); char[][] vals; foreach (val; all_values) vals ~= Integer.toString(val); e.arg(vals); /* foreach (c; cases) foreach (i, v; c.values_converted) if (Array.bsearch(all_values, v)) e.tok(c.values[i].token); */ throw e; } old_values = all_values; } void setDefault(Stmt[] stmts) { if (defaultBlock.length != 0) throw new Error("Switch statements can't have multiple defaults"); defaultBlock = stmts; if (cases.length > 0) cases[$ - 1].followedByDefault = true; } Exp cond; Case[] cases; Stmt[] defaultBlock; struct Case { IntegerLit[] values; Stmt[] stmts; long[] values_converted; bool followedByDefault = false; } private long[] old_values; }