Support return tags on functions.
1 /* vim: set ts=4 sw=4 tw=99 et:
3 * Copyright (C) 2012 David Anderson
5 * This file is part of SourcePawn.
7 * SourcePawn is free software: you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License as published by the Free
9 * Software Foundation, either version 3 of the License, or (at your option)
12 * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with
17 * SourcePawn. If not, see http://www.gnu.org/licenses/.
19 #ifndef _include_jitcraft_ast_h_
20 #define _include_jitcraft_ast_h_
22 #include "PoolAllocator.h"
24 #include "NameBinding.h"
30 _(VariableDeclaration) \
40 _(ExpressionStatement) \
41 _(FunctionStatement) \
48 _(ContinueStatement) \
53 // Forward declarations.
54 #define _(name) class name;
60 // Interface for AST nodes.
61 class AstNode : public PoolObject
67 # define _(name) k##name,
73 AstNode(const SourcePosition &pos)
78 virtual Kind kind() const = 0;
80 #define _(name) bool is##name() { return kind() == k##name; } \
81 name *to##name() { assert(is##name()); return (name *)this; }
85 virtual void accept(AstVisitor *visitor) = 0;
87 const SourcePosition &pos() const {
95 #define _(name) virtual void visit(name *node) = 0;
107 static NameLocation Local(VariableDeclaration *decl) {
118 VariableDeclaration *local() const {
119 assert(kind() == LOCAL);
126 VariableDeclaration *decl;
130 class Statement : public AstNode
133 Statement(const SourcePosition &pos)
139 class Expression : public AstNode
141 ScopedRoot<Type> type_;
144 Expression(const SourcePosition &pos)
150 void setType(Type *type) {
158 typedef PoolList<Statement *> StatementList;
159 typedef PoolList<Expression *> ExpressionList;
161 class VariableDeclaration : public Statement
164 Expression *initialization_;
165 ExpressionList *postDimensions_;
166 ScopedRoot<String> tag_;
169 VariableDeclaration(const SourcePosition &pos, Variable *var, Handle<String> tag,
170 ExpressionList *postDimensions, Expression *initialization)
173 initialization_(initialization),
174 postDimensions_(postDimensions),
179 String *tag() const {
183 return kVariableDeclaration;
185 Variable *variable() const {
188 Expression *initialization() const {
189 return initialization_;
191 ExpressionList *postDimensions() const {
192 return postDimensions_;
194 void accept(AstVisitor *visitor) {
195 visitor->visit(this);
199 class Parameter : public PoolObject
202 ScopedRoot<String> tag_;
205 ExpressionList *dimensions_;
208 Parameter(Variable *var, Handle<String> tag, bool reference, bool isConst, ExpressionList *dimensions)
211 reference_(reference),
213 dimensions_(dimensions)
217 String *tag() const {
220 Variable *variable() const {
223 bool reference() const {
226 ExpressionList *dimensions() const {
229 bool isConst() const {
234 class NameProxy : public Expression
236 ScopedRoot<String> name_;
240 NameProxy(const SourcePosition &pos, Handle<String> name, BoundName *binding)
250 String *name() const {
253 void accept(AstVisitor *visitor) {
254 visitor->visit(this);
256 BoundName *binding() const {
259 void bind(BoundName *name) {
265 class IntegerLiteral : public Expression
270 IntegerLiteral(const SourcePosition &pos, int value)
277 return kIntegerLiteral;
282 void accept(AstVisitor *visitor) {
283 visitor->visit(this);
287 class FloatLiteral : public Expression
292 FloatLiteral(const SourcePosition &pos, double value)
299 return kFloatLiteral;
301 double value() const {
304 void accept(AstVisitor *visitor) {
305 visitor->visit(this);
309 class StringLiteral : public Expression
311 ScopedRoot<ByteArray> string_;
314 StringLiteral(const SourcePosition &pos, ByteArray *array)
321 return kStringLiteral;
323 ByteArray *string() const {
326 void accept(AstVisitor *visitor) {
327 visitor->visit(this);
331 class UnaryExpression : public Expression
333 Expression *expression_;
337 UnaryExpression(const SourcePosition &pos, TokenKind token, Expression *expr)
345 return kUnaryExpression;
347 Expression *expression() const {
350 TokenKind token() const {
353 void accept(AstVisitor *visitor) {
354 visitor->visit(this);
358 class BinaryExpression : public Expression
365 BinaryExpression(const SourcePosition &pos, TokenKind token, Expression *left, Expression *right)
374 return kBinaryExpression;
376 Expression *left() const {
379 Expression *right() const {
382 TokenKind token() const {
385 void accept(AstVisitor *visitor) {
386 visitor->visit(this);
390 class TernaryExpression : public Expression
392 Expression *condition_;
397 TernaryExpression(const SourcePosition &pos, Expression *condition, Expression *left, Expression *right)
399 condition_(condition),
406 return kTernaryExpression;
408 Expression *condition() const {
411 Expression *left() const {
414 Expression *right() const {
417 void accept(AstVisitor *visitor) {
418 visitor->visit(this);
422 class IndexExpression : public Expression
428 IndexExpression(const SourcePosition &pos, Expression *left, Expression *right)
436 return kIndexExpression;
438 Expression *left() const {
441 Expression *right() const {
444 void accept(AstVisitor *visitor) {
445 visitor->visit(this);
449 class CallExpression : public Expression
452 ExpressionList *arguments_;
455 CallExpression(const SourcePosition &pos, Expression *callee, ExpressionList *arguments)
458 arguments_(arguments)
463 return kCallExpression;
465 Expression *callee() const {
468 ExpressionList *arguments() const {
471 void accept(AstVisitor *visitor) {
472 visitor->visit(this);
476 class ForStatement : public Statement
479 Statement *initialization_;
480 Expression *condition_;
485 ForStatement(const SourcePosition &pos, Scope *scope, Statement *initialization,
486 Expression *condition, Statement *update, Statement *body)
489 initialization_(initialization),
490 condition_(condition),
497 return kForStatement;
499 Statement *initialization() const {
500 return initialization_;
502 Scope *scope() const {
505 Expression *condition() const {
508 Statement *update() const {
511 Statement *body() const {
514 void accept(AstVisitor *visitor) {
515 visitor->visit(this);
519 class WhileStatement : public Statement
522 Expression *condition_;
526 WhileStatement(const SourcePosition &pos, TokenKind kind, Expression *condition, Statement *body)
529 condition_(condition),
535 return kWhileStatement;
537 TokenKind token() const {
540 Expression *condition() const {
543 Statement *body() const {
546 void accept(AstVisitor *visitor) {
547 visitor->visit(this);
551 class ReturnStatement : public Statement
553 Expression *expression_;
556 ReturnStatement(const SourcePosition &pos, Expression *expression)
558 expression_(expression)
563 return kReturnStatement;
565 Expression *expression() const {
568 void accept(AstVisitor *visitor) {
569 visitor->visit(this);
573 class BreakStatement : public Statement
576 BreakStatement(const SourcePosition &pos)
582 return kBreakStatement;
584 void accept(AstVisitor *visitor) {
585 visitor->visit(this);
589 class ContinueStatement : public Statement
592 ContinueStatement(const SourcePosition &pos)
598 return kContinueStatement;
600 void accept(AstVisitor *visitor) {
601 visitor->visit(this);
605 class Assignment : public Expression
609 Expression *expression_;
612 Assignment(const SourcePosition &pos, TokenKind token, Expression *left, Expression *right)
623 TokenKind token() const {
626 Expression *lvalue() const {
629 Expression *expression() const {
632 void accept(AstVisitor *visitor) {
633 visitor->visit(this);
637 class ExpressionStatement : public Statement
639 Expression *expression_;
642 ExpressionStatement(Expression *expression)
643 : Statement(expression->pos()),
644 expression_(expression)
649 return kExpressionStatement;
651 Expression *expression() const {
654 void accept(AstVisitor *visitor) {
655 visitor->visit(this);
659 class BlockStatement : public Statement
662 StatementList *statements_;
665 BlockStatement(const SourcePosition &pos, Scope *scope, StatementList *statements)
668 statements_(statements)
673 return kBlockStatement;
675 Scope *scope() const {
678 StatementList *statements() const {
681 void accept(AstVisitor *visitor) {
682 visitor->visit(this);
686 typedef PoolList<Parameter *> ParameterList;
688 class FunctionStatement : public Statement
693 ParameterList *parameters_;
694 bool explicitReturn_;
695 ScopedRoot<String> tag_;
698 FunctionStatement(const SourcePosition &pos, Scope *scope, NamedFunction *fun, Statement *body,
699 ParameterList *parameters, Handle<String> returnTag, bool explicitReturn)
704 parameters_(parameters),
705 explicitReturn_(explicitReturn)
710 return kFunctionStatement;
712 Scope *scope() const {
715 NamedFunction *fun() const {
718 Statement *body() const {
721 ParameterList *parameters() const {
724 void accept(AstVisitor *visitor) {
725 visitor->visit(this);
727 bool hasExplicitReturn() const {
728 return explicitReturn_;
730 String *returnTag() const {
735 class IfStatement : public Statement
737 Expression *condition_;
742 IfStatement(const SourcePosition &pos, Expression *condition, Statement *ifTrue)
744 condition_(condition),
753 Expression *condition() const {
756 Statement *ifTrue() const {
759 Statement *ifFalse() const {
762 void setIfFalse(Statement *ifFalse) {
765 void accept(AstVisitor *visitor) {
766 visitor->visit(this);
770 class EnumStatement : public Statement
772 ScopedRoot<String> name_;
779 Entry(NamedConstant *name, Expression *expr)
786 typedef PoolList<Entry> EntryList;
789 EnumStatement(const SourcePosition &pos, Handle<String> name, EntryList *entries)
797 return kEnumStatement;
799 String *name() const {
802 EntryList *entries() const {
805 void accept(AstVisitor *visitor) {
806 visitor->visit(this);
813 class IncDecExpression : public Expression
816 Expression *expression_;
820 IncDecExpression(const SourcePosition &pos, TokenKind token, Expression *expression, bool postfix)
823 expression_(expression),
829 return kIncDecExpression;
831 TokenKind token() const {
834 Expression *expression() const {
837 bool postfix() const {
840 void accept(AstVisitor *visitor) {
841 visitor->visit(this);
847 typedef PoolList<NameProxy *> NameProxyList;
849 class ParseTree : public PoolObject
851 StatementList *statements_;
853 NameProxyList *unbound_;
856 ParseTree(Scope *scope, StatementList *statements, NameProxyList *unbound)
857 : statements_(statements),
865 StatementList *statements() const {
868 Scope *scope() const {
871 NameProxyList *unbound() const {
878 #endif // _include_jitcraft_ast_h_