#ifndef _IV_AST_FACTORY_H_ #define _IV_AST_FACTORY_H_ #include #include "functor.h" #include "location.h" #include "ast.h" #include "alloc.h" #include "static_assert.h" #include "ustringpiece.h" namespace iv { namespace core { namespace ast { template class BasicAstFactory { public: typedef BasicAstFactory this_type; #define V(AST) typedef typename ast::AST AST; AST_NODE_LIST(V) #undef V #define V(X, XS) typedef typename SpaceVector::type XS; AST_LIST_LIST(V) #undef V #define V(S) typedef typename SpaceUString::type S; AST_STRING(V) #undef V BasicAstFactory() : undefined_instance_( new(static_cast(this))Undefined()), empty_statement_instance_( new(static_cast(this))EmptyStatement()), debugger_statement_instance_( new(static_cast(this))DebuggerStatement()), this_instance_( new(static_cast(this))ThisLiteral()), null_instance_( new(static_cast(this))NullLiteral()), true_instance_( new(static_cast(this))TrueLiteral()), false_instance_( new(static_cast(this))FalseLiteral()) { typedef std::tr1::is_convertible is_convertible_to_this; typedef std::tr1::is_base_of is_base_of_factory; IV_STATIC_ASSERT(is_convertible_to_this::value || is_base_of_factory::value); } template Identifier* NewIdentifier(const Range& range) { return new (static_cast(this)) Identifier(range, static_cast(this)); } NumberLiteral* NewNumberLiteral(const double& val) { return new (static_cast(this)) NumberLiteral(val); } StringLiteral* NewStringLiteral(const std::vector& buffer) { return new (static_cast(this)) StringLiteral(buffer, static_cast(this)); } Directivable* NewDirectivable(const std::vector& buffer) { return new (static_cast(this)) Directivable(buffer, static_cast(this)); } RegExpLiteral* NewRegExpLiteral(const std::vector& content, const std::vector& flags) { return new (static_cast(this)) RegExpLiteral(content, flags, static_cast(this)); } FunctionLiteral* NewFunctionLiteral(typename FunctionLiteral::DeclType type) { return new (static_cast(this)) FunctionLiteral(type, static_cast(this)); } ArrayLiteral* NewArrayLiteral() { return new (static_cast(this)) ArrayLiteral(static_cast(this)); } ObjectLiteral* NewObjectLiteral() { return new (static_cast(this)) ObjectLiteral(static_cast(this)); } template T** NewPtr() { return new (static_cast(this)->New(sizeof(T*))) T*(NULL); } Identifiers* NewLabels() { void* place = static_cast(this)->New(sizeof(Identifiers)); return new (place) Identifiers( typename Identifiers::allocator_type(static_cast(this))); } NullLiteral* NewNullLiteral() { return null_instance_; } EmptyStatement* NewEmptyStatement() { return empty_statement_instance_; } DebuggerStatement* NewDebuggerStatement() { return debugger_statement_instance_; } ThisLiteral* NewThisLiteral() { return this_instance_; } Undefined* NewUndefined() { return undefined_instance_; } TrueLiteral* NewTrueLiteral() { return true_instance_; } FalseLiteral* NewFalseLiteral() { return false_instance_; } FunctionStatement* NewFunctionStatement(FunctionLiteral* func) { return new (static_cast(this)) FunctionStatement(func); } FunctionDeclaration* NewFunctionDeclaration(FunctionLiteral* func) { return new (static_cast(this)) FunctionDeclaration(func); } Block* NewBlock() { return new (static_cast(this)) Block(static_cast(this)); } VariableStatement* NewVariableStatement(Token::Type token) { return new (static_cast(this)) VariableStatement(token, static_cast(this)); } Declaration* NewDeclaration(Identifier* name, Expression* expr) { return new (static_cast(this)) Declaration(name, expr); } IfStatement* NewIfStatement(Expression* cond, Statement* then_statement, Statement* else_statement) { return new (static_cast(this)) IfStatement(cond, then_statement, else_statement); } DoWhileStatement* NewDoWhileStatement(Statement* body, Expression* cond) { return new (static_cast(this)) DoWhileStatement(body, cond); } WhileStatement* NewWhileStatement(Statement* body, Expression* cond) { return new (static_cast(this)) WhileStatement(body, cond); } ForInStatement* NewForInStatement(Statement* body, Statement* each, Expression* enumerable) { return new (static_cast(this)) ForInStatement(body, each, enumerable); } ExpressionStatement* NewExpressionStatement(Expression* expr) { return new (static_cast(this)) ExpressionStatement(expr); } ForStatement* NewForStatement(Statement* body, Statement* init, Expression* cond, Statement* next) { return new (static_cast(this)) ForStatement(body, init, cond, next); } ContinueStatement* NewContinueStatement(Identifier* label, IterationStatement** target) { return new (static_cast(this)) ContinueStatement(label, target); } BreakStatement* NewBreakStatement(Identifier* label, BreakableStatement** target) { return new (static_cast(this)) BreakStatement(label, target); } ReturnStatement* NewReturnStatement( Expression* expr) { return new (static_cast(this)) ReturnStatement(expr); } WithStatement* NewWithStatement( Expression* expr, Statement* stmt) { return new (static_cast(this)) WithStatement(expr, stmt); } SwitchStatement* NewSwitchStatement(Expression* expr) { return new (static_cast(this)) SwitchStatement(expr, static_cast(this)); } CaseClause* NewCaseClause(bool is_default, Expression* expr) { return new (static_cast(this)) CaseClause(is_default, expr, static_cast(this)); } ThrowStatement* NewThrowStatement(Expression* expr) { return new (static_cast(this)) ThrowStatement(expr); } TryStatement* NewTryStatement(Block* try_block, Identifier* catch_name, Block* catch_block, Block* finally_block) { return new (static_cast(this)) TryStatement(try_block, catch_name, catch_block, finally_block); } LabelledStatement* NewLabelledStatement( Expression* expr, Statement* stmt) { return new (static_cast(this)) LabelledStatement(expr, stmt); } BinaryOperation* NewBinaryOperation(Token::Type op, Expression* result, Expression* right) { return new (static_cast(this)) BinaryOperation(op, result, right); } Assignment* NewAssignment(Token::Type op, Expression* left, Expression* right) { return new (static_cast(this)) Assignment(op, left, right); } ConditionalExpression* NewConditionalExpression(Expression* cond, Expression* left, Expression* right) { return new (static_cast(this)) ConditionalExpression(cond, left, right); } UnaryOperation* NewUnaryOperation(Token::Type op, Expression* expr) { return new (static_cast(this)) UnaryOperation(op, expr); } PostfixExpression* NewPostfixExpression( Token::Type op, Expression* expr) { return new (static_cast(this)) PostfixExpression(op, expr); } FunctionCall* NewFunctionCall(Expression* expr) { return new (static_cast(this)) FunctionCall(expr, static_cast(this)); } ConstructorCall* NewConstructorCall(Expression* target) { return new (static_cast(this)) ConstructorCall(target, static_cast(this)); } IndexAccess* NewIndexAccess(Expression* expr, Expression* index) { return new (static_cast(this)) IndexAccess(expr, index); } IdentifierAccess* NewIdentifierAccess(Expression* expr, Identifier* ident) { return new (static_cast(this)) IdentifierAccess(expr, ident); } private: Undefined* undefined_instance_; EmptyStatement* empty_statement_instance_; DebuggerStatement* debugger_statement_instance_; ThisLiteral* this_instance_; NullLiteral* null_instance_; TrueLiteral* true_instance_; FalseLiteral* false_instance_; }; } } } // namespace iv::core::ast #endif // _IV_AST_FACTORY_H_