Mercurial > projects > dang
view src/parser/Action.d @ 209:42e663451371
Renamed some of the actions. Declarations now have it's own action.
author | Anders Johnsen <skabet@gmail.com> |
---|---|
date | Tue, 12 Aug 2008 19:05:17 +0200 |
parents | e0551773a005 |
children |
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 PointerTypeId : Id { public static PointerTypeId opCall(Id id) { auto p = new PointerTypeId(); p.id = id; return p; } Id id; } class StaticArrayTypeId : Id { public static StaticArrayTypeId opCall(Id id, Object number) { auto a = new StaticArrayTypeId(); a.id = id; a.number = number; return a; } Id id; Object number; } class FunctionTypeId : Id { public static FunctionTypeId opCall(Id id, DeclT[] decls) { auto f = new FunctionTypeId(); f.id = id; f.decls = decls; return f; } Id id; DeclT[] decls; } /** 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; } } /** 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 /** 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 { // -- 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) { } /** Called when an simple variable had been parsed. */ DeclT actOnVarDecl(ref Id type, ref Id name, ExprT initializer, Attribute att) { return null; } /** Called when a struct has been parsed. actOnStructMember will be called for all members */ DeclT actOnStructDecl(ref Id name, Attribute att) { return null; } /** Called when a class has been parsed. actOnClassMember will be called for all members actOnClassBaseClass will be called for all base classes */ DeclT actOnClassDecl(ref Id name, Attribute att) { return null; } /** Called when a interface has been parsed. actOnInterfaceMember will be called for all members actOnInterfaceBaseClass will be called for all base classes */ DeclT actOnInterfaceDecl(ref Id name, Attribute att) { return null; } DeclT actOnAliasDecl(DeclT decl, 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 actOnIndexExpr(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; } /** New expression. */ ExprT actOnNewExpr(ref Id type, ExprT[] a_args, ExprT[] c_args) { return null; } /** Array Literal expression. */ ExprT actOnArrayLiteralExpr(ExprT[] exps, SLoc start, SLoc end) { return null; } /** Null expression. */ ExprT actOnNullExpr(SLoc pos) { return null; } } /** Doesn't do anything at all - can be used for benchmarking the parser. */ class NullAction : Action { }