Mercurial > projects > dang
view ast/Stmt.d @ 126:c3b24e7e8cf8
Carius changes to the parser. Parsing attributes, lexing many keywords(not all yet).
author | Anders Johnsen <skabet@gmail.com> |
---|---|
date | Tue, 27 May 2008 10:32:31 +0200 |
parents | 3a0cd42de9cc |
children | a22e3663de89 |
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.Scope, basic.SourceLocation; 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, BinaryExp.Operator.Assign, 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! // TODO: Move this to another sema file where it can be enforced. /+ 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) { // TODO: Move this to another sema file where it can be enforced. /* 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; }