dvander@0: /* dvander@0: * Copyright (C) 2012 David Anderson dvander@0: * dvander@0: * This file is part of JITCraft. dvander@0: * dvander@0: * JITCraft 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@0: * Foobar 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@0: * JITCraft. If not, see http://www.gnu.org/licenses/. dvander@0: */ dvander@0: #ifndef _include_jitcraft_ast_h_ dvander@0: #define _include_jitcraft_ast_h_ dvander@0: dvander@0: #include "PoolAllocator.h" dvander@0: #include "Token.h" dvander@0: #include "StringPool.h" dvander@0: #include "NameBinding.h" dvander@0: dvander@0: namespace jc { 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@9: _(EnumStatement) \ dvander@10: _(WhileStatement) \ dvander@10: _(BreakStatement) \ dvander@10: _(ContinueStatement) 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@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@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@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 NameLocation dvander@0: { dvander@0: public: dvander@0: enum Kind { dvander@0: LOCAL dvander@0: }; dvander@0: dvander@0: static NameLocation Local(VariableDeclaration *decl) { dvander@0: NameLocation loc; dvander@0: loc.kind_ = LOCAL; dvander@0: loc.u_.decl = decl; dvander@0: return loc; dvander@0: } dvander@0: dvander@0: Kind kind() const { dvander@0: return kind_; dvander@0: } dvander@0: dvander@0: VariableDeclaration *local() const { dvander@0: assert(kind() == LOCAL); dvander@0: return u_.decl; dvander@0: } dvander@0: dvander@0: private: dvander@0: Kind kind_; dvander@0: union { dvander@0: VariableDeclaration *decl; dvander@0: } u_; dvander@0: }; dvander@0: dvander@0: class Statement : public AstNode dvander@0: { dvander@0: }; dvander@0: dvander@0: class Expression : public AstNode dvander@0: { dvander@0: Type *type_; dvander@0: dvander@0: public: dvander@0: Expression() dvander@0: : 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: class Declaration : public Statement dvander@0: { dvander@0: }; dvander@0: dvander@0: typedef PoolList StatementList; dvander@0: typedef std::vector ExpressionList; dvander@0: dvander@0: class VariableDeclaration : public Declaration dvander@0: { dvander@0: Variable *variable_; dvander@0: Expression *initialization_; dvander@0: ExpressionList *postDimensions_; dvander@4: Name *tag_; dvander@0: dvander@0: public: dvander@4: VariableDeclaration(Variable *var, Name *tag, ExpressionList *postDimensions, Expression *initialization) dvander@0: : variable_(var), dvander@0: postDimensions_(postDimensions), dvander@4: initialization_(initialization), dvander@4: tag_(tag) dvander@0: { dvander@0: } dvander@0: dvander@4: Name *tag() const { dvander@4: return tag_; 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@0: }; dvander@0: dvander@14: class Parameter : public PoolObject dvander@14: { dvander@14: Variable *variable_; dvander@14: Name *tag_; dvander@14: bool reference_; dvander@14: dvander@14: public: dvander@14: Parameter(Variable *var, Name *tag, bool reference) dvander@14: : variable_(var), dvander@14: tag_(tag), dvander@14: reference_(reference) dvander@14: { dvander@14: } dvander@14: dvander@14: Name *tag() const { dvander@14: return tag_; 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@14: }; dvander@14: dvander@0: class NameProxy : public Expression dvander@0: { dvander@0: Name *name_; dvander@0: BoundName *binding_; dvander@0: dvander@0: public: dvander@0: NameProxy(Name *name, BoundName *binding) dvander@0: : name_(name), dvander@0: binding_(binding) dvander@0: { dvander@0: } dvander@0: dvander@0: Kind kind() const { dvander@0: return kNameProxy; dvander@0: } dvander@0: Name *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@4: class IntegerLiteral : public Expression dvander@0: { dvander@0: int value_; dvander@0: dvander@0: public: dvander@4: IntegerLiteral(int value) dvander@0: : 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@4: FloatLiteral(double value) dvander@4: : 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@21: ByteArray *string_; dvander@21: dvander@21: public: dvander@21: StringLiteral(ByteArray *array) dvander@21: : 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@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@0: BinaryExpression(TokenKind token, Expression *left, Expression *right) dvander@0: : token_(token), dvander@0: left_(left), dvander@0: right_(right) 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@0: class IndexExpression : public Expression dvander@0: { dvander@0: Expression *left_; dvander@0: Expression *right_; dvander@0: dvander@0: public: dvander@0: IndexExpression(Expression *left, Expression *right) dvander@0: : 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@0: class CallExpression : public Expression dvander@0: { dvander@0: Expression *callee_; dvander@0: ExpressionList *arguments_; dvander@0: dvander@0: public: dvander@0: CallExpression(Expression *callee, ExpressionList *arguments) dvander@0: : 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@22: ForStatement(Scope *scope, Statement *initialization, dvander@0: Expression *condition, Statement *update, Statement *body) dvander@0: : 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@9: WhileStatement(TokenKind kind, Expression *condition, Statement *body) dvander@9: : 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@0: ReturnStatement(Expression *expression) dvander@0: : 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@10: BreakStatement() 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@10: ContinueStatement() 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@22: Assignment(TokenKind token, Expression *left, Expression *right) dvander@22: : 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@0: : 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@0: BlockStatement(Scope *scope, StatementList *statements) dvander@0: : 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@14: typedef std::vector ParameterList; dvander@14: dvander@0: class FunctionStatement : public Statement dvander@0: { dvander@0: Scope *scope_; dvander@0: NamedFunction *fun_; dvander@0: Statement *body_; dvander@14: ParameterList *parameters_; dvander@0: dvander@0: public: dvander@14: FunctionStatement(Scope *scope, NamedFunction *fun, Statement *body, ParameterList *parameters) dvander@0: : scope_(scope), dvander@0: fun_(fun), dvander@14: body_(body), dvander@14: parameters_(parameters) 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@14: ParameterList *parameters() const { dvander@14: return parameters_; dvander@14: } dvander@0: void accept(AstVisitor *visitor) { dvander@0: visitor->visit(this); dvander@0: } 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@0: IfStatement(Expression *condition, Statement *ifTrue) dvander@0: : 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@2: Name *name_; 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@2: typedef std::vector EntryList; dvander@2: dvander@2: public: dvander@2: EnumStatement(Name *name, EntryList *entries) dvander@2: : name_(name), dvander@2: entries_(entries) dvander@2: { dvander@2: } dvander@2: dvander@2: Kind kind() const { dvander@2: return kEnumStatement; dvander@2: } dvander@2: Name *name() const { dvander@2: return name_; dvander@2: } dvander@2: EntryList *entries() const { dvander@2: return entries_; dvander@2: } 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@0: class Scope; dvander@0: dvander@0: typedef std::vector 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@0: #endif // _include_jitcraft_ast_h_