Mercurial > projects > dang
view ast/Exp.d @ 56:4ae365eff712 new_gen
Now return types works for structs... Also, simplyfing in AST have been startet - but still messy. This update is a little messy...
author | Anders Johnsen <skabet@gmail.com> |
---|---|
date | Mon, 28 Apr 2008 21:40:00 +0200 |
parents | 79cb0afafabe |
children | fc62c5296a1c |
line wrap: on
line source
module ast.Exp; import tango.text.Util : jhash; import tango.io.Stdout; import ast.Decl, ast.Stmt; import lexer.Token; import sema.SymbolTable; enum ExpType { Binary, Negate, IntegerLit, MemberReference, ArrayLookup, Identifier, AssignExp, CallExp, } class Exp { this(ExpType expType) { this.expType = expType; } ExpType expType; Scope env; int stmtIndex; Exp simplify() { return this; } } class CallExp : Exp { this(Exp exp, Exp[] args) { super(ExpType.CallExp); this.exp = exp; this.args = args; } Exp exp; Exp[] args; bool sret = false; Exp simplify() { auto call = cast(Identifier)exp; FuncDecl f = env.parentFunction; auto i = new Identifier("temp.var"); i.env = f.env; f.env.add(i); f.env.find(i).type = f.env.find(call).type; auto var = new VarDecl(f.type, i, null); Exp[] args; args ~= i; args ~= this.args; auto callExp = new CallExp(exp, args); callExp.env = f.env; // auto ass = new AssignExp(i, callExp); var.env = f.env; // ass.env = f.env; auto stmtVar = new DeclStmt(var); auto stmtCall = new ExpStmt(callExp); Stmt[] stmts; foreach( index, s ; f.statements) { if(stmtIndex == index) { stmts ~= stmtVar; stmts ~= stmtCall; } stmts ~= s; } f.statements = stmts; callExp.sret = true; return i; } } class AssignExp : Exp { this(Exp identifier, Exp exp) { super(ExpType.AssignExp); this.identifier = identifier; this.exp = exp; } Exp simplify() { identifier = identifier.simplify; exp = exp.simplify; return this; } Exp identifier; Exp exp; } class BinaryExp : Exp { public enum Operator { Assign, Eq, Ne, Lt, Le, Gt, Ge, Add, Sub, Mul, Div, Mod, } this(Operator op, Exp left, Exp right) { super(ExpType.Binary); this.op = op; this.left = left; this.right = right; } char[] resultType() { if (op >= Operator.Eq && op <= Operator.Ge) return "bool"; return null; } Exp simplify() { left = left.simplify; right = right.simplify; return this; } Operator op; Exp left, right; } class NegateExp : Exp { this(Exp exp) { super(ExpType.Negate); this.exp = exp; } Exp simplify() { exp = exp.simplify; return this; } public Exp exp; } class IntegerLit : Exp { this(Token t) { super(ExpType.IntegerLit); this.token = t; } Exp simplify() { return this; } Token token; } class MemberReference : Exp { this(Exp target, Identifier child) { super(ExpType.MemberReference); this.target = target; this.child = child; } Exp simplify() { child.simplify; target = target.simplify; return this; } Identifier child; Exp target; } class ArrayLookup : Exp { this(Exp target, IntegerLit pos) { super(ExpType.ArrayLookup); this.target = target; this.pos = pos; } Exp simplify() { target = target.simplify; pos.simplify; return this; } Exp target; IntegerLit pos; } class Identifier : Exp { this(Token t) { super(ExpType.Identifier); this.token = t; name = t.get; } this(char[] name) { super(ExpType.Identifier); this.name = name; } char[] get() { return name; } hash_t toHash() { return jhash(name); } int opCmp(Object o) { if (auto id = cast(Identifier)o) return typeid(char[]).compare(&name, &id.name); return 0; } int opEquals(Object o) { if (auto id = cast(Identifier)o) return typeid(char[]).equals(&name, &id.name); return 0; } Exp simplify() { return this; } Token token; char[] name; }