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@195: #include "../PoolAllocator.h" dvander@195: #include "../Vector.h" dvander@0: #include "Token.h" dvander@0: #include "NameBinding.h" dvander@195: #include "Symbols.h" dvander@0: dvander@59: namespace ke { dvander@0: dvander@195: class Scope; dvander@195: 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@187: _(SwitchStatement) \ dvander@195: _(ArrayLiteral) \ dvander@195: _(ImportStatement) 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@187: name *to##name() { assert(is##name()); return (name *)this; } \ dvander@187: name *as##name() { if (!is##name()) return NULL; return to##name(); } 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@195: #define DECLARE_NODE(type) \ dvander@195: Kind kind() const { \ dvander@195: return k##type; \ dvander@195: } \ dvander@195: void accept(AstVisitor *visitor) { \ dvander@195: visitor->visit##type(this); \ dvander@195: } dvander@195: dvander@0: class AstVisitor dvander@0: { dvander@0: public: dvander@195: #define _(name) virtual void visit##name(name *node) { assert(false); } 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@195: TypeQualifiers qual_; dvander@195: ScopedRoot name_; dvander@0: Expression *initialization_; dvander@209: ExpressionList *dims_; dvander@195: Expression *type_; dvander@195: VariableSymbol *sym_; dvander@0: dvander@0: public: dvander@195: VariableDeclaration(const SourcePosition &pos, TypeQualifiers qual, Handle name, dvander@209: Expression *type, ExpressionList *dims, Expression *initialization) dvander@25: : Statement(pos), dvander@195: qual_(qual), dvander@195: name_(name), dvander@28: initialization_(initialization), dvander@209: dims_(dims), dvander@145: type_(type), dvander@195: sym_(NULL) dvander@0: { dvander@0: } dvander@0: dvander@195: DECLARE_NODE(VariableDeclaration); dvander@195: dvander@0: Expression *initialization() const { dvander@0: return initialization_; dvander@0: } dvander@195: Handle name() { dvander@195: return name_; dvander@195: } dvander@195: Expression *declType() const { dvander@195: return type_; dvander@0: } dvander@195: void setSymbol(VariableSymbol *sym) { dvander@195: assert(!sym_); dvander@195: sym_ = sym; dvander@0: } dvander@195: VariableSymbol *sym() const { dvander@195: return sym_; dvander@195: } dvander@195: Expression *type() const { dvander@195: return type_; dvander@135: } dvander@209: ExpressionList *dims() const { dvander@209: return dims_; dvander@209: } dvander@0: }; dvander@0: dvander@14: class Parameter : public PoolObject dvander@14: { dvander@195: ScopedRoot name_; dvander@195: Expression *type_; dvander@14: bool reference_; dvander@67: bool const_; dvander@133: Expression *initializer_; dvander@195: VariableSymbol *sym_; dvander@195: SourcePosition pos_; dvander@220: ExpressionList *dims_; dvander@14: dvander@14: public: dvander@195: Parameter(Handle name, Expression *type, bool reference, bool isConst, dvander@220: ExpressionList *dims, Expression *initializer, const SourcePosition &pos) dvander@195: : name_(name), dvander@145: type_(type), dvander@66: reference_(reference), dvander@67: const_(isConst), dvander@195: initializer_(initializer), dvander@195: sym_(NULL), dvander@220: pos_(pos), dvander@220: dims_(dims) dvander@14: { dvander@14: } dvander@14: dvander@195: Expression *type() const { dvander@145: return type_; dvander@14: } dvander@195: Handle name() const { dvander@195: return name_; dvander@14: } dvander@14: bool reference() const { dvander@14: return reference_; dvander@14: } dvander@67: bool isConst() const { dvander@67: return const_; dvander@67: } dvander@220: ExpressionList *dims() const { dvander@220: return dims_; dvander@220: } dvander@133: Expression *initializer() const { dvander@133: return initializer_; dvander@133: } dvander@195: void setSymbol(VariableSymbol *sym) { dvander@195: assert(!sym_); dvander@195: sym_ = sym; dvander@195: } dvander@195: VariableSymbol *sym() const { dvander@195: return sym_; dvander@195: } dvander@195: const SourcePosition &pos() const { dvander@195: return pos_; dvander@195: } dvander@14: }; dvander@14: dvander@0: class NameProxy : public Expression dvander@0: { dvander@54: ScopedRoot name_; dvander@195: Symbol *binding_; dvander@0: dvander@0: public: dvander@195: NameProxy(const SourcePosition &pos, Handle name) dvander@25: : Expression(pos), dvander@25: name_(name), dvander@195: binding_(NULL) dvander@0: { dvander@0: } dvander@0: dvander@195: DECLARE_NODE(NameProxy); dvander@195: dvander@195: Handle name() const { dvander@0: return name_; dvander@0: } dvander@195: Symbol *sym() const { dvander@0: return binding_; dvander@0: } dvander@195: void bind(Symbol *sym) { dvander@195: binding_ = sym; 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@195: DECLARE_NODE(BooleanLiteral); dvander@143: TokenKind token() const { dvander@143: return token_; 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@195: DECLARE_NODE(IntegerLiteral); dvander@195: dvander@0: int value() const { dvander@0: return value_; 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@195: DECLARE_NODE(FloatLiteral); dvander@195: dvander@4: double value() const { dvander@4: return value_; dvander@4: } dvander@4: }; dvander@4: dvander@21: class StringLiteral : public Expression dvander@21: { dvander@234: ScopedRoot string_; dvander@21: dvander@21: public: dvander@234: StringLiteral(const SourcePosition &pos, String *string) dvander@25: : Expression(pos), dvander@234: string_(string) dvander@21: { dvander@21: } dvander@21: dvander@195: DECLARE_NODE(StringLiteral); dvander@195: dvander@234: String *string() const { dvander@21: return string_; dvander@21: } dvander@21: }; dvander@21: dvander@187: class ArrayLiteral : public Expression dvander@187: { dvander@187: TokenKind token_; dvander@187: ExpressionList *expressions_; dvander@187: dvander@187: public: dvander@187: ArrayLiteral(const SourcePosition &pos, TokenKind token, ExpressionList *expressions) dvander@187: : Expression(pos), dvander@187: token_(token), dvander@187: expressions_(expressions) dvander@187: { dvander@187: } dvander@187: dvander@195: DECLARE_NODE(ArrayLiteral); dvander@195: dvander@187: TokenKind token() const { dvander@187: return token_; dvander@187: } dvander@187: ExpressionList *expressions() const { dvander@187: return expressions_; dvander@187: } dvander@187: bool isFixed() const { dvander@187: return token_ == TOK_LBRACE; dvander@187: } dvander@187: }; dvander@187: dvander@78: class UnaryExpression : public Expression dvander@78: { dvander@78: Expression *expression_; dvander@78: TokenKind token_; dvander@195: NameProxy *tag_; dvander@78: dvander@78: public: dvander@78: UnaryExpression(const SourcePosition &pos, TokenKind token, Expression *expr) dvander@78: : Expression(pos), dvander@78: expression_(expr), dvander@195: token_(token), dvander@195: tag_(NULL) dvander@78: { dvander@78: } dvander@78: dvander@142: UnaryExpression(const SourcePosition &pos, TokenKind token, Expression *expr, dvander@195: NameProxy *tag) dvander@142: : Expression(pos), dvander@142: expression_(expr), dvander@142: token_(token), dvander@195: tag_(tag) dvander@142: { dvander@142: } dvander@142: dvander@195: DECLARE_NODE(UnaryExpression); dvander@195: dvander@78: Expression *expression() const { dvander@78: return expression_; dvander@78: } dvander@78: TokenKind token() const { dvander@78: return token_; dvander@78: } dvander@195: NameProxy *tag() const { dvander@195: return tag_; 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@195: DECLARE_NODE(BinaryExpression); dvander@195: 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: }; 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@195: DECLARE_NODE(TernaryExpression); dvander@195: 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: }; 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@195: DECLARE_NODE(IndexExpression); dvander@195: dvander@0: Expression *left() const { dvander@0: return left_; dvander@0: } dvander@0: Expression *right() const { dvander@0: return right_; 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@195: DECLARE_NODE(FieldExpression); dvander@195: 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: }; 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@195: DECLARE_NODE(CallExpression); dvander@195: dvander@0: Expression *callee() const { dvander@0: return callee_; dvander@0: } dvander@0: ExpressionList *arguments() const { dvander@0: return arguments_; dvander@0: } dvander@0: }; dvander@0: dvander@0: class ForStatement : public Statement dvander@0: { dvander@22: Statement *initialization_; dvander@0: Expression *condition_; dvander@0: Statement *update_; dvander@0: Statement *body_; dvander@195: Scope *scope_; dvander@0: dvander@0: public: dvander@195: ForStatement(const SourcePosition &pos, Statement *initialization, dvander@0: Expression *condition, Statement *update, Statement *body) dvander@25: : Statement(pos), dvander@22: initialization_(initialization), dvander@0: condition_(condition), dvander@0: update_(update), dvander@195: body_(body), dvander@195: scope_(NULL) dvander@0: { dvander@0: } dvander@0: dvander@195: DECLARE_NODE(ForStatement); dvander@195: dvander@22: Statement *initialization() const { dvander@22: return initialization_; 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@195: Scope *scope() const { dvander@195: return scope_; dvander@195: } dvander@195: void setScope(Scope *scope) { dvander@195: scope_ = scope; 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@195: DECLARE_NODE(WhileStatement); dvander@195: 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: }; 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@195: DECLARE_NODE(ReturnStatement); dvander@195: dvander@0: Expression *expression() const { dvander@0: return expression_; 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@195: DECLARE_NODE(BreakStatement); 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@195: DECLARE_NODE(ContinueStatement); 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@195: DECLARE_NODE(Assignment); dvander@195: 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: }; 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@195: DECLARE_NODE(ExpressionStatement); dvander@195: dvander@0: Expression *expression() const { dvander@0: return expression_; dvander@0: } dvander@0: }; dvander@0: dvander@0: class BlockStatement : public Statement dvander@0: { dvander@195: StatementList *statements_; dvander@0: Scope *scope_; dvander@0: dvander@0: public: dvander@195: BlockStatement(const SourcePosition &pos, StatementList *statements) dvander@25: : Statement(pos), dvander@195: statements_(statements), dvander@195: scope_(NULL) dvander@0: { dvander@0: } dvander@0: dvander@195: DECLARE_NODE(BlockStatement); dvander@195: dvander@195: StatementList *statements() const { dvander@195: return statements_; dvander@0: } dvander@0: Scope *scope() const { dvander@0: return scope_; dvander@0: } dvander@195: void setScope(Scope *scope) { dvander@195: scope_ = scope; dvander@0: } dvander@0: }; dvander@0: dvander@57: typedef PoolList ParameterList; dvander@14: dvander@174: class FunctionSignature dvander@174: { dvander@174: public: dvander@195: FunctionSignature(Expression *returnType, ParameterList *parameters, bool variadic) dvander@174: : returnType_(returnType), dvander@195: parameters_(parameters), dvander@195: variadic_(variadic) dvander@174: { dvander@174: } dvander@174: dvander@195: Expression *returnType() const { dvander@174: return returnType_; dvander@174: } dvander@174: ParameterList *parameters() const { dvander@174: return parameters_; dvander@174: } dvander@195: bool variadic() const { dvander@195: return variadic_; dvander@195: } dvander@174: dvander@174: private: dvander@195: Expression *returnType_; dvander@174: ParameterList *parameters_; dvander@195: bool variadic_; dvander@174: }; dvander@174: dvander@174: class FunctionTypeStatement : public Statement dvander@174: { dvander@174: public: dvander@195: FunctionTypeStatement(const SourcePosition &pos, Handle name, const FunctionSignature &signature) dvander@174: : Statement(pos), dvander@195: name_(name), dvander@174: signature_(signature) dvander@174: { dvander@174: } dvander@174: dvander@195: DECLARE_NODE(FunctionTypeStatement); dvander@195: dvander@195: Handle name() const { dvander@195: return name_; dvander@174: } dvander@174: const FunctionSignature &signature() const { dvander@174: return signature_; dvander@174: } dvander@174: dvander@174: private: dvander@195: ScopedRoot name_; dvander@174: FunctionSignature signature_; dvander@195: dvander@174: }; dvander@174: dvander@0: class FunctionStatement : public Statement dvander@0: { dvander@195: ScopedRoot name_; dvander@195: TokenKind kind_; dvander@0: Statement *body_; dvander@174: FunctionSignature signature_; dvander@71: bool explicitReturn_; dvander@195: FunctionSymbol *sym_; dvander@195: Scope *argScope_; dvander@195: Scope *varScope_; dvander@0: dvander@0: public: dvander@195: FunctionStatement(const SourcePosition &pos, Handle name, TokenKind kind, dvander@195: Statement *body, const FunctionSignature &signature, bool explicitReturn) dvander@25: : Statement(pos), dvander@195: name_(name), dvander@195: kind_(kind), dvander@14: body_(body), dvander@174: signature_(signature), dvander@195: explicitReturn_(explicitReturn), dvander@195: sym_(NULL), dvander@195: argScope_(NULL), dvander@195: varScope_(NULL) dvander@0: { dvander@0: } dvander@0: dvander@195: DECLARE_NODE(FunctionStatement); dvander@195: dvander@195: Handle name() const { dvander@195: return name_; 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@71: bool hasExplicitReturn() const { dvander@71: return explicitReturn_; dvander@71: } dvander@195: TokenKind token() const { dvander@195: return kind_; dvander@195: } dvander@195: void setSymbol(FunctionSymbol *sym) { dvander@195: assert(!sym_); dvander@195: sym_ = sym; dvander@195: } dvander@195: FunctionSymbol *sym() const { dvander@195: return sym_; dvander@195: } dvander@195: void setScopes(Scope *argScope, Scope *varScope) { dvander@195: argScope_ = argScope; dvander@195: varScope_ = varScope; dvander@195: } dvander@195: Scope *argScope() const { dvander@195: return argScope_; dvander@195: } dvander@195: Scope *varScope() const { dvander@195: return varScope_; dvander@195: } 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@195: DECLARE_NODE(IfStatement); dvander@195: 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: }; dvander@0: dvander@2: class EnumStatement : public Statement dvander@2: { dvander@54: ScopedRoot name_; dvander@195: TypeSymbol *sym_; dvander@2: dvander@2: public: dvander@2: struct Entry { dvander@195: ScopedRoot name; dvander@2: Expression *expr; dvander@233: SourcePosition pos; dvander@2: dvander@233: Entry(Handle name, Expression *expr, const SourcePosition &pos) dvander@2: : name(name), dvander@233: expr(expr), dvander@233: pos(pos) dvander@2: { dvander@2: } dvander@2: }; dvander@2: dvander@57: typedef PoolList EntryList; dvander@2: dvander@2: public: dvander@195: EnumStatement(const SourcePosition &pos, Handle name, EntryList *entries) dvander@25: : Statement(pos), dvander@25: name_(name), dvander@196: sym_(NULL), dvander@196: entries_(entries) dvander@2: { dvander@2: } dvander@2: dvander@195: DECLARE_NODE(EnumStatement); dvander@195: dvander@54: String *name() const { dvander@2: return name_; dvander@2: } dvander@2: EntryList *entries() const { dvander@2: return entries_; dvander@2: } dvander@195: void setSymbol(TypeSymbol *sym) { dvander@195: assert(!sym_); dvander@195: sym_ = sym; dvander@145: } dvander@195: TypeSymbol *sym() const { dvander@195: return sym_; 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@195: DECLARE_NODE(IncDecExpression); dvander@195: 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: }; 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@195: DECLARE_NODE(SwitchStatement); dvander@195: 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: 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@195: Expression *type_; dvander@146: ScopedRoot name_; dvander@146: dvander@146: public: dvander@146: Field(const SourcePosition &pos, dvander@195: Expression *type, dvander@195: Handle name) dvander@146: : pos_(pos), dvander@146: type_(type), dvander@195: name_(name) dvander@146: { dvander@146: } dvander@146: dvander@146: const SourcePosition &pos() const { dvander@146: return pos_; dvander@146: } dvander@195: Handle name() const { dvander@146: return name_; dvander@146: } dvander@195: Expression *type() const { dvander@195: return type_; dvander@146: } dvander@146: }; dvander@146: dvander@146: typedef PoolList FieldList; dvander@146: dvander@146: public: dvander@195: StructureStatement(const SourcePosition &pos, Handle name, FieldList *fields) dvander@146: : Statement(pos), dvander@195: name_(name), dvander@195: fields_(fields), dvander@195: sym_(NULL) dvander@146: { dvander@146: } dvander@146: dvander@195: DECLARE_NODE(StructureStatement); dvander@195: dvander@146: FieldList *fields() const { dvander@146: return fields_; dvander@146: } dvander@195: Handle name() const { dvander@195: return name_; dvander@146: } dvander@195: void setSymbol(TypeSymbol *sym) { dvander@195: assert(!sym_); dvander@195: sym_ = sym; dvander@195: } dvander@195: TypeSymbol *sym() const { dvander@195: return sym_; dvander@146: } dvander@146: dvander@146: private: dvander@195: ScopedRoot name_; dvander@146: FieldList *fields_; dvander@195: TypeSymbol *sym_; dvander@195: }; dvander@195: dvander@195: typedef PoolList *> NameList; dvander@195: dvander@195: class ImportStatement : public Statement dvander@195: { dvander@195: public: dvander@195: ImportStatement(const SourcePosition &pos, NameList *names, TokenKind suffix) dvander@195: : Statement(pos), dvander@195: names_(names), dvander@195: suffix_(suffix), dvander@195: source_(NULL) dvander@195: { dvander@195: } dvander@195: dvander@195: DECLARE_NODE(ImportStatement); dvander@195: dvander@195: NameList *path() const { dvander@195: return names_; dvander@195: } dvander@195: void setImportSource(TranslationUnit *unit) { dvander@195: source_ = unit; dvander@195: } dvander@195: TranslationUnit *source() const { dvander@195: return source_; dvander@195: } dvander@195: TokenKind suffix() const { dvander@195: return suffix_; dvander@195: } dvander@195: Handle name() const { dvander@195: assert(suffix() != TOK_STAR); dvander@195: return *names_->at(names_->length() - 1); dvander@195: } dvander@195: dvander@195: private: dvander@195: NameList *names_; dvander@195: TokenKind suffix_; dvander@195: TranslationUnit *source_; dvander@146: }; dvander@146: dvander@146: typedef StructureStatement::FieldList FieldList; dvander@195: typedef PoolList NameProxyList; dvander@146: dvander@195: #undef DECLARE_NODE dvander@0: dvander@0: class ParseTree : public PoolObject dvander@0: { dvander@0: StatementList *statements_; dvander@0: NameProxyList *unbound_; dvander@195: PoolList *imports_; dvander@0: dvander@0: public: dvander@195: ParseTree(StatementList *statements, NameProxyList *unbound, PoolList *imports) dvander@0: : statements_(statements), dvander@195: unbound_(unbound), dvander@195: imports_(imports) 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: NameProxyList *unbound() const { dvander@0: return unbound_; dvander@0: } dvander@195: PoolList *imports() const { dvander@195: return imports_; dvander@195: } dvander@0: }; dvander@0: dvander@0: } dvander@0: dvander@168: #endif // _include_sourcepawn_ast_h_