dvander@132: /* vim: set ts=4 sw=4 tw=99 et: dvander@132: * dvander@0: * Copyright (C) 2012 David Anderson dvander@0: * dvander@132: * This file is part of SourcePawn. dvander@0: * dvander@132: * SourcePawn is free software: you can redistribute it and/or modify it under dvander@0: * the terms of the GNU General Public License as published by the Free dvander@0: * Software Foundation, either version 3 of the License, or (at your option) dvander@0: * any later version. dvander@0: * dvander@132: * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY dvander@0: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS dvander@0: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. dvander@0: * dvander@0: * You should have received a copy of the GNU General Public License along with dvander@132: * SourcePawn. If not, see http://www.gnu.org/licenses/. dvander@0: */ dvander@168: #ifndef _include_sourcepawn_ast_h_ dvander@168: #define _include_sourcepawn_ast_h_ dvander@0: dvander@0: #include "PoolAllocator.h" dvander@0: #include "Token.h" dvander@0: #include "NameBinding.h" dvander@55: #include "Vector.h" dvander@0: dvander@59: namespace ke { dvander@0: dvander@0: #define ASTKINDS(_) \ dvander@0: _(VariableDeclaration) \ dvander@0: _(ForStatement) \ dvander@0: _(ReturnStatement) \ dvander@4: _(IntegerLiteral) \ dvander@4: _(FloatLiteral) \ dvander@21: _(StringLiteral) \ dvander@0: _(BinaryExpression) \ dvander@0: _(BlockStatement) \ dvander@0: _(Assignment) \ dvander@0: _(NameProxy) \ dvander@0: _(ExpressionStatement) \ dvander@0: _(FunctionStatement) \ dvander@0: _(CallExpression) \ dvander@0: _(IfStatement) \ dvander@2: _(IndexExpression) \ dvander@148: _(FieldExpression) \ dvander@9: _(EnumStatement) \ dvander@10: _(WhileStatement) \ dvander@10: _(BreakStatement) \ dvander@23: _(ContinueStatement) \ dvander@174: _(FunctionTypeStatement) \ dvander@78: _(IncDecExpression) \ dvander@83: _(UnaryExpression) \ dvander@143: _(TernaryExpression) \ dvander@146: _(BooleanLiteral) \ dvander@172: _(StructureStatement) \ dvander@172: _(SwitchStatement) dvander@0: dvander@0: // Forward declarations. dvander@0: #define _(name) class name; dvander@0: ASTKINDS(_) dvander@0: #undef _ dvander@0: dvander@0: class AstVisitor; dvander@0: dvander@0: // Interface for AST nodes. dvander@0: class AstNode : public PoolObject dvander@0: { dvander@25: SourcePosition pos_; dvander@25: dvander@0: public: dvander@0: enum Kind { dvander@0: # define _(name) k##name, dvander@0: ASTKINDS(_) dvander@0: # undef _ dvander@0: AstKind_Invalid dvander@0: }; dvander@25: dvander@25: AstNode(const SourcePosition &pos) dvander@25: : pos_(pos) dvander@25: { dvander@25: } dvander@0: dvander@0: virtual Kind kind() const = 0; dvander@0: dvander@0: #define _(name) bool is##name() { return kind() == k##name; } \ dvander@0: name *to##name() { assert(is##name()); return (name *)this; } dvander@0: ASTKINDS(_) dvander@0: #undef _ dvander@0: dvander@0: virtual void accept(AstVisitor *visitor) = 0; dvander@25: dvander@25: const SourcePosition &pos() const { dvander@25: return pos_; dvander@25: } dvander@0: }; dvander@0: dvander@0: class AstVisitor dvander@0: { dvander@0: public: dvander@0: #define _(name) virtual void visit(name *node) = 0; dvander@0: ASTKINDS(_) dvander@0: #undef _ dvander@0: }; dvander@0: dvander@0: class Statement : public AstNode dvander@0: { dvander@25: public: dvander@25: Statement(const SourcePosition &pos) dvander@25: : AstNode(pos) dvander@25: { dvander@25: } dvander@0: }; dvander@0: dvander@0: class Expression : public AstNode dvander@0: { dvander@29: ScopedRoot type_; dvander@0: dvander@0: public: dvander@25: Expression(const SourcePosition &pos) dvander@25: : AstNode(pos), dvander@25: type_(NULL) dvander@0: { dvander@0: } dvander@0: dvander@0: void setType(Type *type) { dvander@0: type_ = type; dvander@0: } dvander@0: Type *type() const { dvander@0: return type_; dvander@0: } dvander@0: }; dvander@0: dvander@0: typedef PoolList StatementList; dvander@56: typedef PoolList ExpressionList; dvander@0: dvander@25: class VariableDeclaration : public Statement dvander@0: { dvander@0: Variable *variable_; dvander@0: Expression *initialization_; dvander@0: ExpressionList *postDimensions_; dvander@145: BoundName *type_; dvander@135: TokenKind declarator_; dvander@0: dvander@0: public: dvander@135: VariableDeclaration(const SourcePosition &pos, TokenKind declarator, Variable *var, dvander@145: BoundName *type, ExpressionList *postDimensions, dvander@135: Expression *initialization) dvander@25: : Statement(pos), dvander@25: variable_(var), dvander@28: initialization_(initialization), dvander@0: postDimensions_(postDimensions), dvander@145: type_(type), dvander@145: declarator_(declarator) dvander@0: { dvander@0: } dvander@0: dvander@145: BoundName *type() const { dvander@145: return type_; dvander@4: } dvander@0: Kind kind() const { dvander@0: return kVariableDeclaration; dvander@0: } dvander@0: Variable *variable() const { dvander@0: return variable_; dvander@0: } dvander@0: Expression *initialization() const { dvander@0: return initialization_; dvander@0: } dvander@0: ExpressionList *postDimensions() const { dvander@0: return postDimensions_; dvander@0: } dvander@0: void accept(AstVisitor *visitor) { dvander@0: visitor->visit(this); dvander@0: } dvander@135: TokenKind declarator() const { dvander@135: return declarator_; dvander@135: } dvander@0: }; dvander@0: dvander@14: class Parameter : public PoolObject dvander@14: { dvander@14: Variable *variable_; dvander@145: BoundName *type_; dvander@14: bool reference_; dvander@67: bool const_; dvander@66: ExpressionList *dimensions_; dvander@133: Expression *initializer_; dvander@14: dvander@14: public: dvander@145: Parameter(Variable *var, BoundName *type, bool reference, bool isConst, dvander@133: ExpressionList *dimensions, Expression *initializer) dvander@14: : variable_(var), dvander@145: type_(type), dvander@66: reference_(reference), dvander@67: const_(isConst), dvander@133: dimensions_(dimensions), dvander@133: initializer_(initializer) dvander@14: { dvander@14: } dvander@14: dvander@145: BoundName *type() const { dvander@145: return type_; dvander@14: } dvander@14: Variable *variable() const { dvander@14: return variable_; dvander@14: } dvander@14: bool reference() const { dvander@14: return reference_; dvander@14: } dvander@66: ExpressionList *dimensions() const { dvander@66: return dimensions_; dvander@66: } dvander@67: bool isConst() const { dvander@67: return const_; dvander@67: } dvander@133: Expression *initializer() const { dvander@133: return initializer_; dvander@133: } dvander@14: }; dvander@14: dvander@0: class NameProxy : public Expression dvander@0: { dvander@54: ScopedRoot name_; dvander@0: BoundName *binding_; dvander@0: dvander@0: public: dvander@54: NameProxy(const SourcePosition &pos, Handle name, BoundName *binding) dvander@25: : Expression(pos), dvander@25: name_(name), dvander@0: binding_(binding) dvander@0: { dvander@0: } dvander@0: dvander@0: Kind kind() const { dvander@0: return kNameProxy; dvander@0: } dvander@54: String *name() const { dvander@0: return name_; dvander@0: } dvander@0: void accept(AstVisitor *visitor) { dvander@0: visitor->visit(this); dvander@0: } dvander@0: BoundName *binding() const { dvander@0: return binding_; dvander@0: } dvander@0: void bind(BoundName *name) { dvander@0: assert(!binding()); dvander@0: binding_ = name; dvander@0: } dvander@0: }; dvander@0: dvander@143: class BooleanLiteral : public Expression dvander@143: { dvander@143: TokenKind token_; dvander@143: dvander@143: public: dvander@143: BooleanLiteral(const SourcePosition &pos, TokenKind token) dvander@143: : Expression(pos), dvander@143: token_(token) dvander@143: { dvander@143: } dvander@143: dvander@143: Kind kind() const { dvander@143: return kBooleanLiteral; dvander@143: } dvander@143: TokenKind token() const { dvander@143: return token_; dvander@143: } dvander@143: void accept(AstVisitor *visitor) { dvander@143: visitor->visit(this); dvander@143: } dvander@143: }; dvander@143: dvander@4: class IntegerLiteral : public Expression dvander@0: { dvander@0: int value_; dvander@0: dvander@0: public: dvander@25: IntegerLiteral(const SourcePosition &pos, int value) dvander@25: : Expression(pos), dvander@25: value_(value) dvander@0: { dvander@0: } dvander@0: dvander@0: Kind kind() const { dvander@4: return kIntegerLiteral; dvander@0: } dvander@0: int value() const { dvander@0: return value_; dvander@0: } dvander@0: void accept(AstVisitor *visitor) { dvander@0: visitor->visit(this); dvander@0: } dvander@0: }; dvander@0: dvander@4: class FloatLiteral : public Expression dvander@4: { dvander@4: double value_; dvander@4: dvander@4: public: dvander@25: FloatLiteral(const SourcePosition &pos, double value) dvander@25: : Expression(pos), dvander@25: value_(value) dvander@4: { dvander@4: } dvander@4: dvander@4: Kind kind() const { dvander@4: return kFloatLiteral; dvander@4: } dvander@4: double value() const { dvander@4: return value_; dvander@4: } dvander@4: void accept(AstVisitor *visitor) { dvander@4: visitor->visit(this); dvander@4: } dvander@4: }; dvander@4: dvander@21: class StringLiteral : public Expression dvander@21: { dvander@29: ScopedRoot string_; dvander@21: dvander@21: public: dvander@25: StringLiteral(const SourcePosition &pos, ByteArray *array) dvander@25: : Expression(pos), dvander@25: string_(array) dvander@21: { dvander@21: } dvander@21: dvander@21: Kind kind() const { dvander@21: return kStringLiteral; dvander@21: } dvander@21: ByteArray *string() const { dvander@21: return string_; dvander@21: } dvander@21: void accept(AstVisitor *visitor) { dvander@21: visitor->visit(this); dvander@21: } dvander@21: }; dvander@21: dvander@78: class UnaryExpression : public Expression dvander@78: { dvander@78: Expression *expression_; dvander@78: TokenKind token_; dvander@145: BoundName *type_; dvander@78: dvander@78: public: dvander@78: UnaryExpression(const SourcePosition &pos, TokenKind token, Expression *expr) dvander@78: : Expression(pos), dvander@78: expression_(expr), dvander@78: token_(token) dvander@78: { dvander@78: } dvander@78: dvander@142: UnaryExpression(const SourcePosition &pos, TokenKind token, Expression *expr, dvander@145: BoundName *type) dvander@142: : Expression(pos), dvander@142: expression_(expr), dvander@142: token_(token), dvander@145: type_(type) dvander@142: { dvander@142: } dvander@142: dvander@78: Kind kind() const { dvander@79: return kUnaryExpression; dvander@78: } dvander@78: Expression *expression() const { dvander@78: return expression_; dvander@78: } dvander@78: TokenKind token() const { dvander@78: return token_; dvander@78: } dvander@145: BoundName *type() const { dvander@145: return type_; dvander@142: } dvander@78: void accept(AstVisitor *visitor) { dvander@78: visitor->visit(this); dvander@78: } dvander@78: }; dvander@78: dvander@0: class BinaryExpression : public Expression dvander@0: { dvander@0: Expression *left_; dvander@0: Expression *right_; dvander@0: TokenKind token_; dvander@0: dvander@0: public: dvander@25: BinaryExpression(const SourcePosition &pos, TokenKind token, Expression *left, Expression *right) dvander@25: : Expression(pos), dvander@0: left_(left), dvander@28: right_(right), dvander@28: token_(token) dvander@0: { dvander@0: } dvander@0: dvander@0: Kind kind() const { dvander@0: return kBinaryExpression; dvander@0: } dvander@0: Expression *left() const { dvander@0: return left_; dvander@0: } dvander@0: Expression *right() const { dvander@0: return right_; dvander@0: } dvander@0: TokenKind token() const { dvander@0: return token_; dvander@0: } dvander@0: void accept(AstVisitor *visitor) { dvander@0: visitor->visit(this); dvander@0: } dvander@0: }; dvander@0: dvander@83: class TernaryExpression : public Expression dvander@83: { dvander@83: Expression *condition_; dvander@83: Expression *left_; dvander@83: Expression *right_; dvander@83: dvander@83: public: dvander@83: TernaryExpression(const SourcePosition &pos, Expression *condition, Expression *left, Expression *right) dvander@83: : Expression(pos), dvander@83: condition_(condition), dvander@83: left_(left), dvander@83: right_(right) dvander@83: { dvander@83: } dvander@83: dvander@83: Kind kind() const { dvander@83: return kTernaryExpression; dvander@83: } dvander@83: Expression *condition() const { dvander@83: return condition_; dvander@83: } dvander@83: Expression *left() const { dvander@83: return left_; dvander@83: } dvander@83: Expression *right() const { dvander@83: return right_; dvander@83: } dvander@83: void accept(AstVisitor *visitor) { dvander@83: visitor->visit(this); dvander@83: } dvander@83: }; dvander@83: dvander@0: class IndexExpression : public Expression dvander@0: { dvander@0: Expression *left_; dvander@0: Expression *right_; dvander@0: dvander@0: public: dvander@25: IndexExpression(const SourcePosition &pos, Expression *left, Expression *right) dvander@25: : Expression(pos), dvander@25: left_(left), dvander@0: right_(right) dvander@0: { dvander@0: } dvander@0: dvander@0: Kind kind() const { dvander@0: return kIndexExpression; dvander@0: } dvander@0: Expression *left() const { dvander@0: return left_; dvander@0: } dvander@0: Expression *right() const { dvander@0: return right_; dvander@0: } dvander@0: void accept(AstVisitor *visitor) { dvander@0: visitor->visit(this); dvander@0: } dvander@0: }; dvander@0: dvander@148: class FieldExpression : public Expression dvander@148: { dvander@148: Expression *left_; dvander@148: ScopedRoot field_; dvander@148: unsigned fieldIndex_; dvander@148: dvander@148: public: dvander@148: FieldExpression(const SourcePosition &pos, Expression *left, Handle field) dvander@148: : Expression(pos), dvander@148: left_(left), dvander@148: field_(field), dvander@148: fieldIndex_(unsigned(-1)) dvander@148: { dvander@148: } dvander@148: dvander@148: Kind kind() const { dvander@148: return kFieldExpression; dvander@148: } dvander@148: Expression *left() const { dvander@148: return left_; dvander@148: } dvander@148: String *field() const { dvander@148: return field_; dvander@148: } dvander@148: void setFieldIndex(unsigned index) { dvander@148: assert(fieldIndex_ == unsigned(-1)); dvander@148: fieldIndex_ = index; dvander@148: } dvander@148: unsigned fieldIndex() const { dvander@148: assert(fieldIndex_ != unsigned(-1)); dvander@148: return fieldIndex_; dvander@148: } dvander@148: void accept(AstVisitor *visitor) { dvander@148: visitor->visit(this); dvander@148: } dvander@148: }; dvander@148: dvander@0: class CallExpression : public Expression dvander@0: { dvander@0: Expression *callee_; dvander@0: ExpressionList *arguments_; dvander@0: dvander@0: public: dvander@25: CallExpression(const SourcePosition &pos, Expression *callee, ExpressionList *arguments) dvander@25: : Expression(pos), dvander@25: callee_(callee), dvander@0: arguments_(arguments) dvander@0: { dvander@0: } dvander@0: dvander@0: Kind kind() const { dvander@0: return kCallExpression; dvander@0: } dvander@0: Expression *callee() const { dvander@0: return callee_; dvander@0: } dvander@0: ExpressionList *arguments() const { dvander@0: return arguments_; dvander@0: } dvander@0: void accept(AstVisitor *visitor) { dvander@0: visitor->visit(this); dvander@0: } dvander@0: }; dvander@0: dvander@0: class ForStatement : public Statement dvander@0: { dvander@0: Scope *scope_; dvander@22: Statement *initialization_; dvander@0: Expression *condition_; dvander@0: Statement *update_; dvander@0: Statement *body_; dvander@0: dvander@0: public: dvander@25: ForStatement(const SourcePosition &pos, Scope *scope, Statement *initialization, dvander@0: Expression *condition, Statement *update, Statement *body) dvander@25: : Statement(pos), dvander@25: scope_(scope), dvander@22: initialization_(initialization), dvander@0: condition_(condition), dvander@0: update_(update), dvander@0: body_(body) dvander@0: { dvander@0: } dvander@0: dvander@0: Kind kind() const { dvander@0: return kForStatement; dvander@0: } dvander@22: Statement *initialization() const { dvander@22: return initialization_; dvander@0: } dvander@0: Scope *scope() const { dvander@0: return scope_; dvander@0: } dvander@0: Expression *condition() const { dvander@0: return condition_; dvander@0: } dvander@0: Statement *update() const { dvander@0: return update_; dvander@0: } dvander@0: Statement *body() const { dvander@0: return body_; dvander@0: } dvander@0: void accept(AstVisitor *visitor) { dvander@0: visitor->visit(this); dvander@0: } dvander@0: }; dvander@0: dvander@9: class WhileStatement : public Statement dvander@9: { dvander@9: TokenKind token_; dvander@9: Expression *condition_; dvander@9: Statement *body_; dvander@9: dvander@9: public: dvander@25: WhileStatement(const SourcePosition &pos, TokenKind kind, Expression *condition, Statement *body) dvander@25: : Statement(pos), dvander@25: token_(kind), dvander@9: condition_(condition), dvander@9: body_(body) dvander@9: { dvander@9: } dvander@9: dvander@9: Kind kind() const { dvander@9: return kWhileStatement; dvander@9: } dvander@9: TokenKind token() const { dvander@9: return token_; dvander@9: } dvander@9: Expression *condition() const { dvander@9: return condition_; dvander@9: } dvander@9: Statement *body() const { dvander@9: return body_; dvander@9: } dvander@9: void accept(AstVisitor *visitor) { dvander@9: visitor->visit(this); dvander@9: } dvander@9: }; dvander@9: dvander@0: class ReturnStatement : public Statement dvander@0: { dvander@0: Expression *expression_; dvander@0: dvander@0: public: dvander@25: ReturnStatement(const SourcePosition &pos, Expression *expression) dvander@25: : Statement(pos), dvander@25: expression_(expression) dvander@0: { dvander@0: } dvander@0: dvander@0: Kind kind() const { dvander@0: return kReturnStatement; dvander@0: } dvander@0: Expression *expression() const { dvander@0: return expression_; dvander@0: } dvander@0: void accept(AstVisitor *visitor) { dvander@0: visitor->visit(this); dvander@0: } dvander@0: }; dvander@0: dvander@10: class BreakStatement : public Statement dvander@10: { dvander@10: public: dvander@25: BreakStatement(const SourcePosition &pos) dvander@25: : Statement(pos) dvander@10: { dvander@10: } dvander@10: dvander@10: Kind kind() const { dvander@10: return kBreakStatement; dvander@10: } dvander@10: void accept(AstVisitor *visitor) { dvander@10: visitor->visit(this); dvander@10: } dvander@10: }; dvander@10: dvander@10: class ContinueStatement : public Statement dvander@10: { dvander@10: public: dvander@25: ContinueStatement(const SourcePosition &pos) dvander@25: : Statement(pos) dvander@10: { dvander@10: } dvander@10: dvander@10: Kind kind() const { dvander@10: return kContinueStatement; dvander@10: } dvander@10: void accept(AstVisitor *visitor) { dvander@10: visitor->visit(this); dvander@10: } dvander@10: }; dvander@10: dvander@0: class Assignment : public Expression dvander@0: { dvander@22: TokenKind token_; dvander@0: Expression *lvalue_; dvander@0: Expression *expression_; dvander@0: dvander@0: public: dvander@25: Assignment(const SourcePosition &pos, TokenKind token, Expression *left, Expression *right) dvander@25: : Expression(pos), dvander@25: token_(token), dvander@22: lvalue_(left), dvander@0: expression_(right) dvander@0: { dvander@0: } dvander@0: dvander@0: Kind kind() const { dvander@0: return kAssignment; dvander@0: } dvander@22: TokenKind token() const { dvander@22: return token_; dvander@22: } dvander@0: Expression *lvalue() const { dvander@0: return lvalue_; dvander@0: } dvander@0: Expression *expression() const { dvander@0: return expression_; dvander@0: } dvander@0: void accept(AstVisitor *visitor) { dvander@0: visitor->visit(this); dvander@0: } dvander@0: }; dvander@0: dvander@0: class ExpressionStatement : public Statement dvander@0: { dvander@0: Expression *expression_; dvander@0: dvander@0: public: dvander@0: ExpressionStatement(Expression *expression) dvander@25: : Statement(expression->pos()), dvander@25: expression_(expression) dvander@0: { dvander@0: } dvander@0: dvander@0: Kind kind() const { dvander@0: return kExpressionStatement; dvander@0: } dvander@0: Expression *expression() const { dvander@0: return expression_; dvander@0: } dvander@0: void accept(AstVisitor *visitor) { dvander@0: visitor->visit(this); dvander@0: } dvander@0: }; dvander@0: dvander@0: class BlockStatement : public Statement dvander@0: { dvander@0: Scope *scope_; dvander@0: StatementList *statements_; dvander@0: dvander@0: public: dvander@25: BlockStatement(const SourcePosition &pos, Scope *scope, StatementList *statements) dvander@25: : Statement(pos), dvander@25: scope_(scope), dvander@0: statements_(statements) dvander@0: { dvander@0: } dvander@0: dvander@0: Kind kind() const { dvander@0: return kBlockStatement; dvander@0: } dvander@0: Scope *scope() const { dvander@0: return scope_; dvander@0: } dvander@0: StatementList *statements() const { dvander@0: return statements_; dvander@0: } dvander@0: void accept(AstVisitor *visitor) { dvander@0: visitor->visit(this); dvander@0: } dvander@0: }; dvander@0: dvander@57: typedef PoolList ParameterList; dvander@14: dvander@174: class FunctionSignature dvander@174: { dvander@174: public: dvander@174: FunctionSignature(BoundName *returnType, ParameterList *parameters) dvander@174: : returnType_(returnType), dvander@174: parameters_(parameters) dvander@174: { dvander@174: } dvander@174: dvander@174: BoundName *returnType() const { dvander@174: return returnType_; dvander@174: } dvander@174: ParameterList *parameters() const { dvander@174: return parameters_; dvander@174: } dvander@174: dvander@174: private: dvander@174: BoundName *returnType_; dvander@174: ParameterList *parameters_; dvander@174: }; dvander@174: dvander@174: class FunctionTypeStatement : public Statement dvander@174: { dvander@174: public: dvander@174: FunctionTypeStatement(const SourcePosition &pos, NamedType *type, const FunctionSignature &signature) dvander@174: : Statement(pos), dvander@174: type_(type), dvander@174: signature_(signature) dvander@174: { dvander@174: } dvander@174: dvander@174: Kind kind() const { dvander@174: return kFunctionTypeStatement; dvander@174: } dvander@174: NamedType *decl() const { dvander@174: return type_; dvander@174: } dvander@174: const FunctionSignature &signature() const { dvander@174: return signature_; dvander@174: } dvander@174: void accept(AstVisitor *visitor) { dvander@174: visitor->visit(this); dvander@174: } dvander@174: dvander@174: private: dvander@174: NamedType *type_; dvander@174: FunctionSignature signature_; dvander@174: }; dvander@174: dvander@0: class FunctionStatement : public Statement dvander@0: { dvander@0: Scope *scope_; dvander@0: NamedFunction *fun_; dvander@0: Statement *body_; dvander@174: FunctionSignature signature_; dvander@71: bool explicitReturn_; dvander@0: dvander@0: public: dvander@25: FunctionStatement(const SourcePosition &pos, Scope *scope, NamedFunction *fun, Statement *body, dvander@174: const FunctionSignature &signature, bool explicitReturn) dvander@25: : Statement(pos), dvander@25: scope_(scope), dvander@0: fun_(fun), dvander@14: body_(body), dvander@174: signature_(signature), dvander@174: explicitReturn_(explicitReturn) dvander@0: { dvander@0: } dvander@0: dvander@0: Kind kind() const { dvander@0: return kFunctionStatement; dvander@0: } dvander@0: Scope *scope() const { dvander@0: return scope_; dvander@0: } dvander@0: NamedFunction *fun() const { dvander@0: return fun_; dvander@0: } dvander@0: Statement *body() const { dvander@0: return body_; dvander@0: } dvander@174: const FunctionSignature &signature() { dvander@174: return signature_; dvander@14: } dvander@0: void accept(AstVisitor *visitor) { dvander@0: visitor->visit(this); dvander@0: } dvander@71: bool hasExplicitReturn() const { dvander@71: return explicitReturn_; dvander@71: } dvander@0: }; dvander@0: dvander@0: class IfStatement : public Statement dvander@0: { dvander@0: Expression *condition_; dvander@0: Statement *ifTrue_; dvander@0: Statement *ifFalse_; dvander@0: dvander@0: public: dvander@25: IfStatement(const SourcePosition &pos, Expression *condition, Statement *ifTrue) dvander@25: : Statement(pos), dvander@25: condition_(condition), dvander@0: ifTrue_(ifTrue), dvander@0: ifFalse_(NULL) dvander@0: { dvander@0: } dvander@0: dvander@0: Kind kind() const { dvander@0: return kIfStatement; dvander@0: } dvander@0: Expression *condition() const { dvander@0: return condition_; dvander@0: } dvander@0: Statement *ifTrue() const { dvander@0: return ifTrue_; dvander@0: } dvander@0: Statement *ifFalse() const { dvander@0: return ifFalse_; dvander@0: } dvander@0: void setIfFalse(Statement *ifFalse) { dvander@0: ifFalse_ = ifFalse; dvander@0: } dvander@0: void accept(AstVisitor *visitor) { dvander@0: visitor->visit(this); dvander@0: } dvander@0: }; dvander@0: dvander@2: class EnumStatement : public Statement dvander@2: { dvander@54: ScopedRoot name_; dvander@145: NamedType *type_; dvander@2: dvander@2: public: dvander@2: struct Entry { dvander@2: NamedConstant *name; dvander@2: Expression *expr; dvander@2: dvander@2: Entry(NamedConstant *name, Expression *expr) dvander@2: : name(name), dvander@2: expr(expr) dvander@2: { dvander@2: } dvander@2: }; dvander@2: dvander@57: typedef PoolList EntryList; dvander@2: dvander@2: public: dvander@145: EnumStatement(const SourcePosition &pos, NamedType *type, Handle name, EntryList *entries) dvander@25: : Statement(pos), dvander@25: name_(name), dvander@145: type_(type), dvander@2: entries_(entries) dvander@2: { dvander@2: } dvander@2: dvander@2: Kind kind() const { dvander@2: return kEnumStatement; dvander@2: } dvander@54: String *name() const { dvander@2: return name_; dvander@2: } dvander@2: EntryList *entries() const { dvander@2: return entries_; dvander@2: } dvander@145: NamedType *decl() const { dvander@145: return type_; dvander@145: } dvander@2: void accept(AstVisitor *visitor) { dvander@2: visitor->visit(this); dvander@2: } dvander@2: dvander@2: private: dvander@2: EntryList *entries_; dvander@2: }; dvander@2: dvander@23: class IncDecExpression : public Expression dvander@23: { dvander@23: TokenKind token_; dvander@23: Expression *expression_; dvander@23: bool postfix_; dvander@23: dvander@23: public: dvander@25: IncDecExpression(const SourcePosition &pos, TokenKind token, Expression *expression, bool postfix) dvander@25: : Expression(pos), dvander@25: token_(token), dvander@23: expression_(expression), dvander@23: postfix_(postfix) dvander@23: { dvander@23: } dvander@23: dvander@23: Kind kind() const { dvander@23: return kIncDecExpression; dvander@23: } dvander@23: TokenKind token() const { dvander@23: return token_; dvander@23: } dvander@23: Expression *expression() const { dvander@23: return expression_; dvander@23: } dvander@23: bool postfix() const { dvander@23: return postfix_; dvander@23: } dvander@23: void accept(AstVisitor *visitor) { dvander@23: visitor->visit(this); dvander@23: } dvander@23: }; dvander@23: dvander@172: class Case : public PoolObject dvander@172: { dvander@172: public: dvander@172: Case(Expression *expression, ExpressionList *others, Statement *statement) dvander@172: : expression_(expression), dvander@172: others_(others), dvander@172: statement_(statement) dvander@172: { dvander@172: } dvander@172: dvander@172: Expression *expression() const { dvander@172: return expression_; dvander@172: } dvander@172: PoolList *others() const { dvander@172: return others_; dvander@172: } dvander@172: Statement *statement() const { dvander@172: return statement_; dvander@172: } dvander@172: dvander@172: private: dvander@172: Expression *expression_; dvander@172: PoolList *others_; dvander@172: Statement *statement_; dvander@172: }; dvander@172: dvander@172: struct CaseValue dvander@172: { dvander@172: BoxedPrimitive box; dvander@172: size_t statement; dvander@172: dvander@172: CaseValue(size_t statement) dvander@172: : statement(statement) dvander@172: { dvander@172: } dvander@172: }; dvander@172: dvander@172: typedef PoolList CaseValueList; dvander@172: dvander@172: class SwitchStatement : public Statement dvander@172: { dvander@172: public: dvander@172: SwitchStatement(const SourcePosition &pos, Expression *expression, PoolList *cases, dvander@172: Statement *def) dvander@172: : Statement(pos), dvander@172: expression_(expression), dvander@172: cases_(cases), dvander@172: default_(def), dvander@172: table_(NULL) dvander@172: { dvander@172: } dvander@172: dvander@172: Kind kind() const { dvander@172: return kSwitchStatement; dvander@172: } dvander@172: Expression *expression() const { dvander@172: return expression_; dvander@172: } dvander@172: PoolList *cases() const { dvander@172: return cases_; dvander@172: } dvander@172: Statement *defaultCase() const { dvander@172: return default_; dvander@172: } dvander@172: void setCaseValueList(CaseValueList *list) { dvander@172: table_ = list; dvander@172: } dvander@172: CaseValueList *caseValueList() const { dvander@172: return table_; dvander@172: } dvander@172: void accept(AstVisitor *visitor) { dvander@172: visitor->visit(this); dvander@172: } dvander@172: dvander@172: private: dvander@172: Expression *expression_; dvander@172: PoolList *cases_; dvander@172: Statement *default_; dvander@172: CaseValueList *table_; dvander@172: }; dvander@172: dvander@146: class StructureStatement : public Statement dvander@146: { dvander@146: public: dvander@146: class Field : public PoolObject dvander@146: { dvander@146: SourcePosition pos_; dvander@146: BoundName *type_; dvander@146: ScopedRoot name_; dvander@146: ExpressionList *dimensions_; dvander@146: dvander@146: public: dvander@146: Field(const SourcePosition &pos, dvander@146: BoundName *type, dvander@146: Handle name, dvander@146: ExpressionList *dimensions) dvander@146: : pos_(pos), dvander@146: type_(type), dvander@146: name_(name), dvander@146: dimensions_(dimensions) dvander@146: { dvander@146: } dvander@146: dvander@146: const SourcePosition &pos() const { dvander@146: return pos_; dvander@146: } dvander@146: BoundName *type() const { dvander@146: return type_; dvander@146: } dvander@146: String *name() const { dvander@146: return name_; dvander@146: } dvander@146: ExpressionList *dimensions() const { dvander@146: return dimensions_; dvander@146: } dvander@146: }; dvander@146: dvander@146: typedef PoolList FieldList; dvander@146: dvander@146: public: dvander@146: StructureStatement(const SourcePosition &pos, NamedType *decl, FieldList *fields) dvander@146: : Statement(pos), dvander@146: decl_(decl), dvander@146: fields_(fields) dvander@146: { dvander@146: } dvander@146: dvander@146: Kind kind() const { dvander@146: return kStructureStatement; dvander@146: } dvander@146: FieldList *fields() const { dvander@146: return fields_; dvander@146: } dvander@146: NamedType *decl() const { dvander@146: return decl_; dvander@146: } dvander@146: void accept(AstVisitor *visitor) { dvander@146: visitor->visit(this); dvander@146: } dvander@146: dvander@146: private: dvander@146: NamedType *decl_; dvander@146: FieldList *fields_; dvander@146: }; dvander@146: dvander@146: typedef StructureStatement::FieldList FieldList; dvander@146: dvander@0: class Scope; dvander@0: dvander@57: typedef PoolList NameProxyList; dvander@0: dvander@0: class ParseTree : public PoolObject dvander@0: { dvander@0: StatementList *statements_; dvander@0: Scope *scope_; dvander@0: NameProxyList *unbound_; dvander@0: dvander@0: public: dvander@0: ParseTree(Scope *scope, StatementList *statements, NameProxyList *unbound) dvander@0: : statements_(statements), dvander@0: scope_(scope), dvander@0: unbound_(unbound) dvander@0: { dvander@0: } dvander@0: dvander@0: void dump(FILE *fp); dvander@0: dvander@0: StatementList *statements() const { dvander@0: return statements_; dvander@0: } dvander@0: Scope *scope() const { dvander@0: return scope_; dvander@0: } dvander@0: NameProxyList *unbound() const { dvander@0: return unbound_; dvander@0: } dvander@0: }; dvander@0: dvander@0: } dvander@0: dvander@168: #endif // _include_sourcepawn_ast_h_