Mercurial > projects > dang
view parser/Action.d @ 153:ee202c72cd30
Merge
author | Anders Halager <halager@gmail.com> |
---|---|
date | Mon, 21 Jul 2008 21:32:20 +0200 |
parents | 6c5a3c0bb4fb 393a1f47a6d2 |
children | 57b0b4464a0b |
line wrap: on
line source
module parser.Action; import lexer.Token; import basic.Attribute; /** Used to indicate what type of operator is used in a given binary expression (and unary expressions?) */ public enum Operator { Assign, AddAssign, SubAssign, MulAssign, DivAssign, ModAssign, Eq, Ne, Lt, Le, Gt, Ge, Add, Sub, Mul, Div, Mod, LeftShift, RightShift, UnsignedRightShift, } class Id { public static Id opCall(Token tok) { auto id = new Id(); id.tok = tok; return id; } Token tok; } class PointerId : Id { public static PointerId opCall(Id id) { auto p = new PointerId(); p.id = id; return p; } Id id; } class StaticArrayId : Id { public static StaticArrayId opCall(Id id, Object number) { auto a = new StaticArrayId(); a.id = id; a.number = number; return a; } Id id; Object number; } /** Represents a fully qualified name, with some packages and a final identifier. The identifier should always be set, but packages may have length 0. **/ struct ModuleName { Id id; Id[] packages; /// Get the full ranged spanned by packages and identifier SourceRange asRange() { SourceRange r = id.tok.asRange(); foreach (identifier; packages) r = r + identifier.tok.asRange(); return r; } } /** All methods are optional. Warning: Interface is not stable yet. Use the `override` keyword in all classes inheriting from this to get warning if the interface changes. */ abstract class Action { /** A few aliases to indicate what methods should be dealing with the same types. Not typesafe, and not using typedef because users would need a lot of casts (and base type would be void*, so no possibility to synchronize, print etc.) */ alias Object ExprT; alias Object StmtT; /// ditto alias Object DeclT; /// ditto alias Object ModuleT; /// ditto // -- Modules -- ModuleT actOnModule(ref Token _module, char[] name) { return null; } /** This action is called when a file does not start with a module declaration - in which case there is no Token available. Instead a SLoc to the start of the file is given. */ ModuleT actOnImplicitModule(SourceLocation fileStart, char[] name) { return null; } void actOnModuleDecl(ModuleT m, DeclT d) { } // -- Declarations -- /** Called for an import statement, that may be renamed. Id name is null, there is no rename. If there are selective imports, its handled in add */ DeclT actOnImport(ref Token _import, ref ModuleName target, Id* name) { return null; } /** */ void addSelectiveImport(DeclT _import, ref Id target, Id* name) { } /** Either we should have one case that handles a lot of things, or we should have a lot of separate cases. As an example, this method could handle the params in `int f(int, int)` as well as handling `int x` at both top-level, in classes and in methods. The other solution is an addParamToFunc or similar. */ DeclT actOnDeclarator(ref Id type, ref Id name, ExprT init, Attribute att) { return null; } /** Add a struct member to a struct. */ void actOnStructMember(DeclT st_decl, DeclT m_decl) { return null; } /** Add a class member to a struct. */ void actOnClassMember(DeclT cl_decl, DeclT m_decl) { return null; } /** Add a class member to a struct. */ void actOnClassBaseClass(DeclT cl_decl, ref Id name) { return null; } /** Add a class member to a struct. */ void actOnInterfaceMember(DeclT if_decl, DeclT m_decl) { return null; } /** Add a class member to a struct. */ void actOnInterfaceBaseClass(DeclT if_decl, ref Id name) { return null; } /** Add an initialization expression to a previously created decl. Used for default values on function params and for values to local variables. */ void addInitToDeclarator(DeclT decl, ExprT exp) { } /** Called at the start of a function, doesn't get a lot of info - that is added later on, through addFuncArg and actOnEndOfFunction. */ DeclT actOnStartOfFunctionDef(ref Id type, ref Id name, Attribute att) { return null; } /** Add a new parameter to the function func. */ void addFuncArg(DeclT func, Id type, Id name) { } /** Finish off the function, by giving it the body (a single statement, so you probably want some sort of compound statement) */ DeclT actOnEndOfFunction(DeclT func, StmtT stmts) { return func; } // -- Statements -- /** Called after parsing a function/while/for/whatever body. Note that stmts is to be considered temporary, it might point into the stack and needs to be copied before saving. */ StmtT actOnCompoundStmt(ref Token left, ref Token right, StmtT[] stmts) { return null; } /** An expression was used as a statement - this includes assignments, function calls. Additionally the D spec dictates that expressions with no effect are not legal as statements, but the parser can't test for this so it has to be done in the later stages. */ StmtT actOnExprStmt(ExprT exp) { return null; } /** Called after parsing return statements. loc is the return token. */ StmtT actOnReturnStmt(ref Token loc, ExprT exp) { return null; } /** */ StmtT actOnIfStmt(ref Token ifTok, ExprT cond, StmtT thenBody, ref Token elseTok, StmtT elseBody) { return null; } /** */ StmtT actOnWhileStmt(ref Token whileTok, ExprT cond, StmtT whileBody) { return null; } /** */ StmtT actOnForStmt(ref Token forTok, StmtT init, ExprT cond, ExprT incre, StmtT forBody) { return null; } /** */ StmtT actOnDeclStmt(DeclT decl) { return null; } StmtT actOnStartOfSwitchStmt(Token _switch, ExprT exp) { return null; } void actOnCaseStmt(StmtT stmt, Token _case, ExprT[] exps, StmtT[] stmts) { } void actOnDefaultStmt(StmtT stmt, Token _default, StmtT[] stmts) { } StmtT actOnFinishSwitchStmt(StmtT sw) { return sw; } // -- Expressions -- /** A single numerical constant -- this can be absolutely any kind of number. Integers, floats, hex, octal, binary, imaginary and so on. */ ExprT actOnNumericConstant(Token op) { return null; } /** This is called when identifiers are used in expressions. */ ExprT actOnIdentifierExp(Id id) { return null; } /** This is called when strings are used in expression */ ExprT actOnStringExp(Token t) { return null; } /** Unary operator. */ ExprT actOnUnaryOp(Token op, ExprT operand) { return null; } /** Binary operator. */ ExprT actOnBinaryOp(SLoc op_loc, Operator op, ExprT l, ExprT r) { return null; } /** Called when using the 'dot' operator. The left hand side can be any expression, but its only possible to look up an identifier. */ ExprT actOnMemberReference(ExprT lhs, SourceLocation op, Id member) { return null; } /** Called when function calls are encountered. Note that args is temporary and might point into the stack. Remember to copy before saving a reference to it. */ ExprT actOnCallExpr(ExprT func, ref Token left_paren, ExprT[] args, ref Token right_paren) { return null; } /** Called when function calls are encountered. */ ExprT actOnIndexEpr(ExprT array, ref Token left_bracket, ExprT index, ref Token right_bracket) { return null; } /** Cast expression. */ ExprT actOnCastExpr(ref Token _cast, Id type, ExprT exp) { return null; } } /** Doesn't do anything at all - can be used for benchmarking the parser. */ class NullAction : Action { }