Mercurial > projects > dang
view sema/AstAction.d @ 143:d76cc5cad4fc
Added partial support for switches.
Added support for extern(C) in CodeGen.
author | Anders Johnsen <skabet@gmail.com> |
---|---|
date | Mon, 21 Jul 2008 01:05:20 +0200 |
parents | 2be29b296081 |
children | 6e6355fb5f0f |
line wrap: on
line source
module sema.AstAction; import Integer = tango.text.convert.Integer; import lexer.Token; import basic.SourceManager, basic.Attribute; import ast.Module, ast.Exp, ast.Stmt, ast.Decl; public import parser.Action; /** This class implements the default actions for Dang, by building up an AST with the data needed in a compiler. */ class AstAction : Action { this(SourceManager sm) { this.sm = sm; } private SourceManager sm; private Identifier handleType(Id type) { if(auto t = cast(PointerId)type) return new PointerIdentifier(handleType(t.id)); if(auto t = cast(StaticArrayId)type) return new StaticArrayIdentifier(handleType(t.id), cast(IntegerLit)t.number); else return identifierFromTok(type.tok); } private Identifier identifierFromTok(Token t) { return new Identifier(t.location, sm.getText(t.asRange)); } override ModuleT actOnModule(ref Token _module, char[] name) { return new Module(name); } override ModuleT actOnImplicitModule(SLoc startLoc, char[] name) { return new Module(name); } override void actOnModuleDecl(ModuleT m, DeclT d) { (cast(Module)m).addDecl(cast(Decl)d); } // -- Declarations -- override DeclT actOnImport(ref Token _, ref ModuleName target, Id* name) { auto res = new ImportDecl; Identifier[] packages = new Identifier[target.packages.length]; foreach (i, v; target.packages) packages[i] = identifierFromTok(v.tok); res.packages = packages; res.name = identifierFromTok(target.id.tok); if (name !is null) res.aliasedName = identifierFromTok(name.tok); return res; } override void addSelectiveImport(DeclT _import, ref Id target, Id* name) { auto d = cast(ImportDecl)_import; Identifier t = identifierFromTok(target.tok); Identifier n = t; if (name !is null) n = identifierFromTok(name.tok); d.explicitSymbols ~= [t, n]; } override DeclT actOnDeclarator(ref Id type, ref Id id, ExprT init, Attribute att) { Decl d; Exp exp = cast(Exp)init; if(type.tok.type == Tok.Struct) d = new StructDecl(identifierFromTok(id.tok)); else d = new VarDecl(handleType(type), identifierFromTok(id.tok), exp); d.att = att; return d; } override void actOnStructMember(DeclT st_decl, DeclT m_decl) //ref Id type, ref Id name, ExprT init) { StructDecl st = cast(StructDecl)st_decl; st.addMember(cast(Decl)m_decl); } override ExprT actOnMemberReference(ExprT lhs, SLoc op, Id member) { Exp exp = cast(Exp)lhs; Identifier id = identifierFromTok(member.tok); return new MemberReference(op, exp, id); } override DeclT actOnStartOfFunctionDef(ref Id type, ref Id name, Attribute att) { auto res = new FuncDecl(identifierFromTok(type.tok), identifierFromTok(name.tok)); res.att = att; return res; } override void addFuncArg(DeclT func, Id type, Id name) { FuncDecl fd = cast(FuncDecl)func; if(name) fd.addParam(handleType(type), identifierFromTok(name.tok)); else fd.addParam(identifierFromTok(type.tok)); } override DeclT actOnEndOfFunction(DeclT func, StmtT stmts) { FuncDecl fd = cast(FuncDecl)func; fd.setBody(cast(CompoundStatement)stmts); return fd; } // -- Statements -- override StmtT actOnCompoundStmt(ref Token l, ref Token r, StmtT[] stmts) { Stmt[] statements = cast(Stmt[])stmts; return new CompoundStatement(statements.dup); } override StmtT actOnExprStmt(ExprT exp) { return new ExpStmt(cast(Exp)exp); } override StmtT actOnReturnStmt(ref Token loc, ExprT exp) { Exp e = cast(Exp)exp; auto res = new ReturnStmt; res.exp = e; return res; } override StmtT actOnIfStmt(ref Token ifTok, ExprT cond, StmtT thenBody, ref Token elseTok, StmtT elseBody) { Exp c = cast(Exp)cond; Stmt t = cast(Stmt)thenBody; Stmt e = cast(Stmt)elseBody; return new IfStmt(c, t, e); } override StmtT actOnWhileStmt(ref Token tok, ExprT cond, StmtT whileBody) { Exp c = cast(Exp)cond; Stmt b = cast(Stmt)whileBody; return new WhileStmt(c, b); } override StmtT actOnDeclStmt(DeclT decl) { Decl d = cast(Decl)decl; return new DeclStmt(d); } override StmtT actOnStartOfSwitchStmt(ExprT exp) { return new SwitchStmt(cast(Exp)exp); } override void actOnCaseStmt(StmtT stmt, ExprT[] exps, StmtT[] stmts) { auto sw = cast(SwitchStmt)stmt; sw.addCase(cast(Exp[])exps, cast(Stmt[])stmts); } override void actOnDefaultStmt(StmtT stmt, StmtT[] stmts) { auto sw = cast(SwitchStmt)stmt; sw.setDefault(cast(Stmt[])stmts); } // -- Expressions -- override ExprT actOnNumericConstant(Token c) { return new IntegerLit(c.location, sm.getText(c.asRange)); } override ExprT actOnStringExp(Token s) { return new StringExp(s.location, sm.getText(s.asRange)); } override ExprT actOnIdentifierExp(Id id) { return identifierFromTok(id.tok); } override ExprT actOnBinaryOp(SLoc op_loc, Operator op, ExprT l, ExprT r) { Exp left = cast(Exp)l; Exp right = cast(Exp)r; switch(op) { case Operator.Assign: case Operator.AddAssign: case Operator.SubAssign: case Operator.MulAssign: case Operator.DivAssign: case Operator.ModAssign: return new AssignExp(op_loc, cast(BinaryExp.Operator)op, left, right); default: BinaryExp.Operator bin_op = cast(BinaryExp.Operator)op; return new BinaryExp(op_loc, bin_op, left, right); } } override ExprT actOnUnaryOp(Token op, ExprT operand) { Exp target = cast(Exp)operand; if (op.type == Tok.Minus) return new NegateExp(op.location, target); if (op.type == Tok.Star) return new DerefExp(op.location, target); assert(0, "Only valid unary expressions are -x and *x"); } override ExprT actOnCallExpr(ExprT fn, ref Token, ExprT[] args, ref Token) { Exp f = cast(Exp)fn; Exp[] arguments = cast(Exp[])args.dup; return new CallExp(f, arguments); } override ExprT actOnCastExpr(ref Token _cast, Id id, ExprT exp) { Exp target = cast(Exp)exp; Identifier target_type = identifierFromTok(id.tok); return new CastExp(_cast.location, target_type, target); } override ExprT actOnIndexEpr(ExprT arr, ref Token lb, ExprT index, ref Token rb) { Exp target = cast(Exp)arr; Exp idx = cast(Exp)index; return new IndexExp(target, lb.location, idx, rb.location); } }