Mercurial > projects > dang
view ast/Stmt.d @ 88:eb5b2c719a39 new_gen
Major change to locations, tokens and expressions.
A location (now SourceLocation or SLoc) is only 32 bit in size -
disadvantage is that it can't find its own text. You have to go through the
new SourceManager to do that.
This has caused changes to a lot of stuff and removal of DataSource and the
old Location
Additionally Exp has gotten some location stuff, so we can give proper
error messages. Not in Decl and Stmt yet, but thats coming too.
author | Anders Halager <halager@gmail.com> |
---|---|
date | Sun, 04 May 2008 18:13:46 +0200 |
parents | 91f10c34cd7b |
children | 771ac63898e2 |
line wrap: on
line source
module ast.Stmt; import Array = tango.core.Array, Integer = tango.text.convert.Integer, tango.io.Stdout; import ast.Exp, ast.Decl; import sema.SymbolTable, basic.SourceLocation, misc.Error; enum StmtType { Stmt, Compound, Decl, Exp, Return, If, While, Switch, } class Stmt { this(StmtType stmtType = StmtType.Stmt) { this.stmtType = stmtType; } void simplify() { } StmtType stmtType; Scope env; int stmtIndex; } class CompoundStatement : Stmt { this(Stmt[] stmts) { super(StmtType.Compound); this.statements = stmts; } void simplify() { foreach ( stmt ; statements ) stmt.simplify; } Stmt[] statements; } class ReturnStmt : Stmt { this() { super(StmtType.Return); } void simplify() { FuncDecl f = env.parentFunction; if(exp) exp.simplify; if(f !is null && f.sret) { auto i = new Identifier("ret.val"); i.env = f.env; auto ass = new AssignExp(SLoc.Invalid, i, exp); ass.env = f.env; auto assStmt = new ExpStmt(ass); assStmt.env = f.env; Stmt[] stmts; foreach(index, stmt ; f.statements) { if(stmtIndex == index) stmts ~= assStmt; stmts ~= stmt; } f.statements = stmts; exp = null; } } public Exp exp; } class DeclStmt : Stmt { this(Decl decl) { super(StmtType.Decl); this.decl = decl; } void simplify() { decl.simplify; } public Decl decl; } class ExpStmt : Stmt { this(Exp exp) { super(StmtType.Exp); this.exp = exp; } void simplify() { exp = exp.simplify; } 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; } void simplify() { cond.simplify; then_body.simplify; if (else_body) else_body.simplify; } Exp cond; Stmt then_body; Stmt else_body; } class WhileStmt : Stmt { this(Exp cond, Stmt stmts) { super(StmtType.While); this.cond = cond; this.whileBody = stmts; } void simplify() { cond.simplify; whileBody.simplify; } Exp cond; Stmt whileBody; } 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.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; } void simplify() { cond.simplify; foreach ( stmt ; defaultBlock ) stmt.simplify; foreach ( c ; cases ) foreach ( stmt ; c.stmts ) stmt.simplify; } Exp cond; Case[] cases; Stmt[] defaultBlock; struct Case { IntegerLit[] values; Stmt[] stmts; long[] values_converted; bool followedByDefault = false; } private long[] old_values; }