Mercurial > projects > dang
view ast/Exp.d @ 195:4e1a7265d620
Made a BuildTypes pass, to give all exp's a type.
author | Anders Johnsen <skabet@gmail.com> |
---|---|
date | Tue, 29 Jul 2008 15:50:24 +0200 |
parents | 08f68d684047 |
children |
line wrap: on
line source
module ast.Exp; import tango.text.Util, Integer = tango.text.convert.Integer; import tango.io.Stdout; import ast.Decl, ast.Stmt; import lexer.Token; import sema.Scope, sema.Symbol, sema.DType; import basic.LiteralParsing; enum ExpType { Binary, Negate, Deref, AddressOfExp, IntegerLit, MemberReference, Index, Identifier, AssignExp, CallExp, CastExp, StringExp, NewExp, NullExp, ArrayLiteralExp, IdentifierTypeExp, ArrayTypeExp, StaticArrayTypeExp, PointerTypeExp, FunctionTypeExp, } abstract class Exp { this(ExpType expType, SLoc loc) { this.expType = expType; this.loc = loc; } /** Get the fully qualified name for the expression (if it can be resolved to one) - otherwise null is returned **/ char[] getFQN() { return null; } /// The same as getFQN, except that the name is mangled char[] getMangledFQN() { return null; } /** Try to get the symbol the expression represents. Returns null for most expressions as they don't represent any symbol. Identifiers and member references can have a sensible value. **/ Symbol getSymbol() { return null; } /// Get the type of the expression DType type; /// Indicates which type the expression is - to avoid a lot of casts ExpType expType; /// The environment of the expression Scope env; int stmtIndex; /** The "main" location of the expression. What exactly this represents varies but for most things its the start while for a binary expression its the operator. **/ SourceLocation loc; /// Return the starting location of this expression SourceLocation startLoc() { return loc; } /// Get the full extents of the expression SourceRange sourceRange() { return SourceRange(loc, loc + 1); } /// Do some simplifications Exp simplify() { return this; } } class CallExp : Exp { this(Exp exp, Exp[] args) { super(ExpType.CallExp, exp.loc); this.exp = exp; this.args = args; } DType callerType() { DFunction f = new DFunction(new Identifier("function")); f.returnType = type; foreach (a ; args) f.params ~= a.type; return f; } override CallExp simplify() { foreach (ref arg; args) arg = arg.simplify(); exp = exp.simplify(); return this; } Exp exp; Exp[] args; Symbol callSym; bool sret = false; override SourceRange sourceRange() { SourceRange res = exp.sourceRange; if (args.length > 0) res = res + args[$ - 1].sourceRange; return res; } } class AssignExp : BinaryExp { this(SLoc op_loc, Operator op, Exp identifier, Exp exp) { super(ExpType.AssignExp, op_loc, op, identifier, exp); this.identifier = identifier; this.exp = exp; } override AssignExp simplify() { identifier = identifier.simplify(); exp = exp.simplify(); return this; } override SourceRange sourceRange() { return identifier.sourceRange + exp.sourceRange; } Exp identifier; Exp exp; } class BinaryExp : Exp { public enum Operator { Assign, AddAssign, SubAssign, MulAssign, DivAssign, ModAssign, Eq, Ne, Lt, Le, Gt, Ge, Add, Sub, Mul, Div, Mod, LeftShift, RightShift, UnsignedRightShift, And, Or, Xor, } char[][] getOp = ["=","+=","-=","*=","/=","%=","==","!=","<","<=",">",">=","+","-","*","/","%","<<",">>",">>>"]; this(SLoc op_loc, Operator op, Exp left, Exp right) { super(ExpType.Binary, op_loc); this.op = op; this.left = left; this.right = right; } protected this(ExpType e, SLoc op_loc, Operator op, Exp left, Exp right) { super(e, op_loc); this.op = op; this.left = left; this.right = right; } override SLoc startLoc() { return left.startLoc(); } override SourceRange sourceRange() { return left.sourceRange + right.sourceRange; } char[] resultType() { if (op >= Operator.Eq && op <= Operator.Ge) return "bool"; return null; } override BinaryExp simplify() { left = left.simplify(); right = right.simplify(); return this; } Operator op; Exp left, right; } class NegateExp : Exp { this(SLoc op, Exp exp) { super(ExpType.Negate, op); this.exp = exp; } override NegateExp simplify() { exp = exp.simplify(); return this; } override SourceRange sourceRange() { return SourceRange(loc) + exp.sourceRange; } public Exp exp; } class DerefExp : Exp { this(SLoc op, Exp exp) { super(ExpType.Deref, op); this.exp = exp; } override DerefExp simplify() { exp = exp.simplify(); return this; } override SourceRange sourceRange() { return SourceRange(loc) + exp.sourceRange; } public Exp exp; } class AddressOfExp : Exp { this(SLoc op, Exp exp) { super(ExpType.AddressOfExp, op); this.exp = exp; } override AddressOfExp simplify() { exp = exp.simplify(); return this; } override SourceRange sourceRange() { return SourceRange(loc) + exp.sourceRange; } public Exp exp; } class IntegerLit : Exp { this(SLoc loc, char[] t) { super(ExpType.IntegerLit, loc); range = SourceRange(loc, loc + t.length); this.name = t; } char[] get() { return name; } override IntegerLit simplify() { return this; } override SourceRange sourceRange() { return range; } Number number; char[] name; private SourceRange range; } class MemberReference : Exp { this(SLoc dot, Exp target, Identifier child) { super(ExpType.MemberReference, dot); this.target = target; this.child = child; } override char[] getFQN() { return getSymbol().getFQN(); } override char[] getMangledFQN() { return target.type.mangle() ~ child.getMangledFQN(); } override Symbol getSymbol() { auto s = target.getSymbol(); if (s !is null) return s.findMembers(child.get)[0]; return null; } override MemberReference simplify() { target = target.simplify(); return this; } override SLoc startLoc() { return target.startLoc(); } override SourceRange sourceRange() { return target.sourceRange + child.sourceRange; } Identifier child; Exp target; } class IndexExp : Exp { this(Exp target, SLoc left_bracket, Exp index, SLoc right_bracket) { super(ExpType.Index, target.startLoc); this.target = target; this.left_bracket = left_bracket; this.index = index; this.right_bracket = right_bracket; } override SourceRange sourceRange() { return target.sourceRange + SourceRange(right_bracket); } override IndexExp simplify() { target = target.simplify(); index = index.simplify(); return this; } Exp target; Exp index; SLoc left_bracket, right_bracket; } class CastExp : Exp { this(SLoc loc, Identifier castType, Exp exp) { super(ExpType.CastExp, loc); this.castType = castType; this.exp = exp; } override CastExp simplify() { castType = castType.simplify(); exp = exp.simplify(); return this; } override SourceRange sourceRange() { return SourceRange(loc) + exp.sourceRange; } Identifier castType; Exp exp; } class StringExp : Exp { this(SLoc loc, char[] str) { super(ExpType.StringExp, loc); this.str = str; } char[] str; String data; } class NewExp : Exp { this(Identifier newType, Exp[] a_args, Exp[] c_args) { super(ExpType.NewExp, newType.loc); this.newType = newType; this.a_args = a_args; this.c_args = c_args; } Exp[] a_args, c_args; Identifier newType; Symbol callSym; } class NullExp : Exp { this(SLoc loc) { super(ExpType.NullExp, loc); } } class Identifier : Exp { this(SLoc loc, char[] name) { super(ExpType.Identifier, loc); this.name = name; } protected this(ExpType t, SLoc loc) { super(t, loc); } override char[] getFQN() { return name; } override char[] getMangledFQN() { return Integer.toString(name.length) ~ name; } override Symbol getSymbol() { if (!env) return null; if (auto decl = env.find(this.get)) if(decl.length) return decl[$-1].sym; return null; } this(char[] name) { super(ExpType.Identifier, SLoc.Invalid); 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; } override Identifier simplify() { return this; } override SourceRange sourceRange() { return SourceRange(loc, loc + name.length); } char[] name; } class IdentifierTypeExp : Identifier { this(SLoc loc, char[] name) { super(ExpType.IdentifierTypeExp, loc); this.name = name; } protected this(ExpType t, SLoc loc) { super(t, loc); } } class PointerTypeExp : IdentifierTypeExp { this(IdentifierTypeExp pointerOf) { super(ExpType.PointerTypeExp, pointerOf.loc); this.pointerOf = pointerOf; this.name = pointerOf.name; } Identifier pointerOf; } class StaticArrayTypeExp : IdentifierTypeExp { this(IdentifierTypeExp arrayOf, IntegerLit size) { super(ExpType.StaticArrayTypeExp, arrayOf.loc); this.arrayOf = arrayOf; this.size = Integer.parse(size.get); this.name = arrayOf.name; } Identifier arrayOf; int size; } class ArrayTypeExp : IdentifierTypeExp { this(IdentifierTypeExp arrayOf) { super(ExpType.ArrayTypeExp, arrayOf.loc); this.arrayOf = arrayOf; this.name = arrayOf.name; } Identifier arrayOf; } class FunctionTypeExp : IdentifierTypeExp { this(IdentifierTypeExp returnType, VarDecl[] decls) { super(ExpType.FunctionTypeExp, returnType.loc); this.returnType = returnType; this.decls = decls; } VarDecl[] decls; IdentifierTypeExp returnType; } class ArrayLiteralExp : Exp { this(Exp[] exps, SLoc begin, SLoc end) { super(ExpType.ArrayLiteralExp, begin); this.exps = exps; this.begin = begin; this.end = end; } Exp[] exps; SLoc begin, end; }