Add support for array reference semantics.
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_sourcepawn_ast_h_
20 #define _include_sourcepawn_ast_h_
22 #include "PoolAllocator.h"
24 #include "NameBinding.h"
30 _(VariableDeclaration) \
40 _(ExpressionStatement) \
41 _(FunctionStatement) \
49 _(ContinueStatement) \
50 _(FunctionTypeStatement) \
53 _(TernaryExpression) \
55 _(StructureStatement) \
58 // Forward declarations.
59 #define _(name) class name;
65 // Interface for AST nodes.
66 class AstNode : public PoolObject
72 # define _(name) k##name,
78 AstNode(const SourcePosition &pos)
83 virtual Kind kind() const = 0;
85 #define _(name) bool is##name() { return kind() == k##name; } \
86 name *to##name() { assert(is##name()); return (name *)this; }
90 virtual void accept(AstVisitor *visitor) = 0;
92 const SourcePosition &pos() const {
100 #define _(name) virtual void visit(name *node) = 0;
105 class Statement : public AstNode
108 Statement(const SourcePosition &pos)
114 class Expression : public AstNode
116 ScopedRoot<Type> type_;
119 Expression(const SourcePosition &pos)
125 void setType(Type *type) {
133 typedef PoolList<Statement *> StatementList;
134 typedef PoolList<Expression *> ExpressionList;
136 class VariableDeclaration : public Statement
139 Expression *initialization_;
140 ExpressionList *postDimensions_;
142 TokenKind declarator_;
145 VariableDeclaration(const SourcePosition &pos, TokenKind declarator, Variable *var,
146 BoundName *type, ExpressionList *postDimensions,
147 Expression *initialization)
150 initialization_(initialization),
151 postDimensions_(postDimensions),
153 declarator_(declarator)
157 BoundName *type() const {
161 return kVariableDeclaration;
163 Variable *variable() const {
166 Expression *initialization() const {
167 return initialization_;
169 ExpressionList *postDimensions() const {
170 return postDimensions_;
172 void accept(AstVisitor *visitor) {
173 visitor->visit(this);
175 TokenKind declarator() const {
180 class Parameter : public PoolObject
186 ExpressionList *dimensions_;
187 Expression *initializer_;
190 Parameter(Variable *var, BoundName *type, bool reference, bool isConst,
191 ExpressionList *dimensions, Expression *initializer)
194 reference_(reference),
196 dimensions_(dimensions),
197 initializer_(initializer)
201 BoundName *type() const {
204 Variable *variable() const {
207 bool reference() const {
210 ExpressionList *dimensions() const {
213 bool isConst() const {
216 Expression *initializer() const {
221 class NameProxy : public Expression
223 ScopedRoot<String> name_;
227 NameProxy(const SourcePosition &pos, Handle<String> name, BoundName *binding)
237 String *name() const {
240 void accept(AstVisitor *visitor) {
241 visitor->visit(this);
243 BoundName *binding() const {
246 void bind(BoundName *name) {
252 class BooleanLiteral : public Expression
257 BooleanLiteral(const SourcePosition &pos, TokenKind token)
264 return kBooleanLiteral;
266 TokenKind token() const {
269 void accept(AstVisitor *visitor) {
270 visitor->visit(this);
274 class IntegerLiteral : public Expression
279 IntegerLiteral(const SourcePosition &pos, int value)
286 return kIntegerLiteral;
291 void accept(AstVisitor *visitor) {
292 visitor->visit(this);
296 class FloatLiteral : public Expression
301 FloatLiteral(const SourcePosition &pos, double value)
308 return kFloatLiteral;
310 double value() const {
313 void accept(AstVisitor *visitor) {
314 visitor->visit(this);
318 class StringLiteral : public Expression
320 ScopedRoot<ByteArray> string_;
323 StringLiteral(const SourcePosition &pos, ByteArray *array)
330 return kStringLiteral;
332 ByteArray *string() const {
335 void accept(AstVisitor *visitor) {
336 visitor->visit(this);
340 class UnaryExpression : public Expression
342 Expression *expression_;
347 UnaryExpression(const SourcePosition &pos, TokenKind token, Expression *expr)
354 UnaryExpression(const SourcePosition &pos, TokenKind token, Expression *expr,
364 return kUnaryExpression;
366 Expression *expression() const {
369 TokenKind token() const {
372 BoundName *type() const {
375 void accept(AstVisitor *visitor) {
376 visitor->visit(this);
380 class BinaryExpression : public Expression
387 BinaryExpression(const SourcePosition &pos, TokenKind token, Expression *left, Expression *right)
396 return kBinaryExpression;
398 Expression *left() const {
401 Expression *right() const {
404 TokenKind token() const {
407 void accept(AstVisitor *visitor) {
408 visitor->visit(this);
412 class TernaryExpression : public Expression
414 Expression *condition_;
419 TernaryExpression(const SourcePosition &pos, Expression *condition, Expression *left, Expression *right)
421 condition_(condition),
428 return kTernaryExpression;
430 Expression *condition() const {
433 Expression *left() const {
436 Expression *right() const {
439 void accept(AstVisitor *visitor) {
440 visitor->visit(this);
444 class IndexExpression : public Expression
450 IndexExpression(const SourcePosition &pos, Expression *left, Expression *right)
458 return kIndexExpression;
460 Expression *left() const {
463 Expression *right() const {
466 void accept(AstVisitor *visitor) {
467 visitor->visit(this);
471 class FieldExpression : public Expression
474 ScopedRoot<String> field_;
475 unsigned fieldIndex_;
478 FieldExpression(const SourcePosition &pos, Expression *left, Handle<String> field)
482 fieldIndex_(unsigned(-1))
487 return kFieldExpression;
489 Expression *left() const {
492 String *field() const {
495 void setFieldIndex(unsigned index) {
496 assert(fieldIndex_ == unsigned(-1));
499 unsigned fieldIndex() const {
500 assert(fieldIndex_ != unsigned(-1));
503 void accept(AstVisitor *visitor) {
504 visitor->visit(this);
508 class CallExpression : public Expression
511 ExpressionList *arguments_;
514 CallExpression(const SourcePosition &pos, Expression *callee, ExpressionList *arguments)
517 arguments_(arguments)
522 return kCallExpression;
524 Expression *callee() const {
527 ExpressionList *arguments() const {
530 void accept(AstVisitor *visitor) {
531 visitor->visit(this);
535 class ForStatement : public Statement
538 Statement *initialization_;
539 Expression *condition_;
544 ForStatement(const SourcePosition &pos, Scope *scope, Statement *initialization,
545 Expression *condition, Statement *update, Statement *body)
548 initialization_(initialization),
549 condition_(condition),
556 return kForStatement;
558 Statement *initialization() const {
559 return initialization_;
561 Scope *scope() const {
564 Expression *condition() const {
567 Statement *update() const {
570 Statement *body() const {
573 void accept(AstVisitor *visitor) {
574 visitor->visit(this);
578 class WhileStatement : public Statement
581 Expression *condition_;
585 WhileStatement(const SourcePosition &pos, TokenKind kind, Expression *condition, Statement *body)
588 condition_(condition),
594 return kWhileStatement;
596 TokenKind token() const {
599 Expression *condition() const {
602 Statement *body() const {
605 void accept(AstVisitor *visitor) {
606 visitor->visit(this);
610 class ReturnStatement : public Statement
612 Expression *expression_;
615 ReturnStatement(const SourcePosition &pos, Expression *expression)
617 expression_(expression)
622 return kReturnStatement;
624 Expression *expression() const {
627 void accept(AstVisitor *visitor) {
628 visitor->visit(this);
632 class BreakStatement : public Statement
635 BreakStatement(const SourcePosition &pos)
641 return kBreakStatement;
643 void accept(AstVisitor *visitor) {
644 visitor->visit(this);
648 class ContinueStatement : public Statement
651 ContinueStatement(const SourcePosition &pos)
657 return kContinueStatement;
659 void accept(AstVisitor *visitor) {
660 visitor->visit(this);
664 class Assignment : public Expression
668 Expression *expression_;
671 Assignment(const SourcePosition &pos, TokenKind token, Expression *left, Expression *right)
682 TokenKind token() const {
685 Expression *lvalue() const {
688 Expression *expression() const {
691 void accept(AstVisitor *visitor) {
692 visitor->visit(this);
696 class ExpressionStatement : public Statement
698 Expression *expression_;
701 ExpressionStatement(Expression *expression)
702 : Statement(expression->pos()),
703 expression_(expression)
708 return kExpressionStatement;
710 Expression *expression() const {
713 void accept(AstVisitor *visitor) {
714 visitor->visit(this);
718 class BlockStatement : public Statement
721 StatementList *statements_;
724 BlockStatement(const SourcePosition &pos, Scope *scope, StatementList *statements)
727 statements_(statements)
732 return kBlockStatement;
734 Scope *scope() const {
737 StatementList *statements() const {
740 void accept(AstVisitor *visitor) {
741 visitor->visit(this);
745 typedef PoolList<Parameter *> ParameterList;
747 class FunctionSignature
750 FunctionSignature(BoundName *returnType, ParameterList *parameters)
751 : returnType_(returnType),
752 parameters_(parameters)
756 BoundName *returnType() const {
759 ParameterList *parameters() const {
764 BoundName *returnType_;
765 ParameterList *parameters_;
768 class FunctionTypeStatement : public Statement
771 FunctionTypeStatement(const SourcePosition &pos, NamedType *type, const FunctionSignature &signature)
774 signature_(signature)
779 return kFunctionTypeStatement;
781 NamedType *decl() const {
784 const FunctionSignature &signature() const {
787 void accept(AstVisitor *visitor) {
788 visitor->visit(this);
793 FunctionSignature signature_;
796 class FunctionStatement : public Statement
801 FunctionSignature signature_;
802 bool explicitReturn_;
805 FunctionStatement(const SourcePosition &pos, Scope *scope, NamedFunction *fun, Statement *body,
806 const FunctionSignature &signature, bool explicitReturn)
811 signature_(signature),
812 explicitReturn_(explicitReturn)
817 return kFunctionStatement;
819 Scope *scope() const {
822 NamedFunction *fun() const {
825 Statement *body() const {
828 const FunctionSignature &signature() {
831 void accept(AstVisitor *visitor) {
832 visitor->visit(this);
834 bool hasExplicitReturn() const {
835 return explicitReturn_;
839 class IfStatement : public Statement
841 Expression *condition_;
846 IfStatement(const SourcePosition &pos, Expression *condition, Statement *ifTrue)
848 condition_(condition),
857 Expression *condition() const {
860 Statement *ifTrue() const {
863 Statement *ifFalse() const {
866 void setIfFalse(Statement *ifFalse) {
869 void accept(AstVisitor *visitor) {
870 visitor->visit(this);
874 class EnumStatement : public Statement
876 ScopedRoot<String> name_;
884 Entry(NamedConstant *name, Expression *expr)
891 typedef PoolList<Entry> EntryList;
894 EnumStatement(const SourcePosition &pos, NamedType *type, Handle<String> name, EntryList *entries)
903 return kEnumStatement;
905 String *name() const {
908 EntryList *entries() const {
911 NamedType *decl() const {
914 void accept(AstVisitor *visitor) {
915 visitor->visit(this);
922 class IncDecExpression : public Expression
925 Expression *expression_;
929 IncDecExpression(const SourcePosition &pos, TokenKind token, Expression *expression, bool postfix)
932 expression_(expression),
938 return kIncDecExpression;
940 TokenKind token() const {
943 Expression *expression() const {
946 bool postfix() const {
949 void accept(AstVisitor *visitor) {
950 visitor->visit(this);
954 class Case : public PoolObject
957 Case(Expression *expression, ExpressionList *others, Statement *statement)
958 : expression_(expression),
960 statement_(statement)
964 Expression *expression() const {
967 PoolList<Expression *> *others() const {
970 Statement *statement() const {
975 Expression *expression_;
976 PoolList <Expression *> *others_;
977 Statement *statement_;
985 CaseValue(size_t statement)
986 : statement(statement)
991 typedef PoolList<CaseValue> CaseValueList;
993 class SwitchStatement : public Statement
996 SwitchStatement(const SourcePosition &pos, Expression *expression, PoolList<Case *> *cases,
999 expression_(expression),
1007 return kSwitchStatement;
1009 Expression *expression() const {
1012 PoolList<Case *> *cases() const {
1015 Statement *defaultCase() const {
1018 void setCaseValueList(CaseValueList *list) {
1021 CaseValueList *caseValueList() const {
1024 void accept(AstVisitor *visitor) {
1025 visitor->visit(this);
1029 Expression *expression_;
1030 PoolList<Case *> *cases_;
1031 Statement *default_;
1032 CaseValueList *table_;
1035 class StructureStatement : public Statement
1038 class Field : public PoolObject
1040 SourcePosition pos_;
1042 ScopedRoot<String> name_;
1043 ExpressionList *dimensions_;
1046 Field(const SourcePosition &pos,
1048 Handle<String> name,
1049 ExpressionList *dimensions)
1053 dimensions_(dimensions)
1057 const SourcePosition &pos() const {
1060 BoundName *type() const {
1063 String *name() const {
1066 ExpressionList *dimensions() const {
1071 typedef PoolList<StructureStatement::Field *> FieldList;
1074 StructureStatement(const SourcePosition &pos, NamedType *decl, FieldList *fields)
1082 return kStructureStatement;
1084 FieldList *fields() const {
1087 NamedType *decl() const {
1090 void accept(AstVisitor *visitor) {
1091 visitor->visit(this);
1099 typedef StructureStatement::FieldList FieldList;
1103 typedef PoolList<NameProxy *> NameProxyList;
1105 class ParseTree : public PoolObject
1107 StatementList *statements_;
1109 NameProxyList *unbound_;
1112 ParseTree(Scope *scope, StatementList *statements, NameProxyList *unbound)
1113 : statements_(statements),
1119 void dump(FILE *fp);
1121 StatementList *statements() const {
1124 Scope *scope() const {
1127 NameProxyList *unbound() const {
1134 #endif // _include_sourcepawn_ast_h_