Fixed type checking for multidimensional arrays.
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"
23 #include "../Vector.h"
25 #include "NameBinding.h"
35 _(VariableDeclaration) \
45 _(ExpressionStatement) \
46 _(FunctionStatement) \
54 _(ContinueStatement) \
55 _(FunctionTypeStatement) \
58 _(TernaryExpression) \
60 _(StructureStatement) \
65 // Forward declarations.
66 #define _(name) class name;
72 // Interface for AST nodes.
73 class AstNode : public PoolObject
79 # define _(name) k##name,
85 AstNode(const SourcePosition &pos)
90 virtual Kind kind() const = 0;
92 #define _(name) bool is##name() { return kind() == k##name; } \
93 name *to##name() { assert(is##name()); return (name *)this; } \
94 name *as##name() { if (!is##name()) return NULL; return to##name(); }
98 virtual void accept(AstVisitor *visitor) = 0;
100 const SourcePosition &pos() const {
105 #define DECLARE_NODE(type) \
106 Kind kind() const { \
109 void accept(AstVisitor *visitor) { \
110 visitor->visit##type(this); \
116 #define _(name) virtual void visit##name(name *node) { assert(false); }
121 class Statement : public AstNode
124 Statement(const SourcePosition &pos)
130 class Expression : public AstNode
133 Expression(const SourcePosition &pos)
139 typedef PoolList<Statement *> StatementList;
140 typedef PoolList<Expression *> ExpressionList;
142 class VariableDeclaration : public Statement
144 TypeQualifiers qual_;
145 ScopedRoot<String> name_;
146 Expression *initialization_;
147 ExpressionList *dims_;
149 VariableSymbol *sym_;
152 VariableDeclaration(const SourcePosition &pos, TypeQualifiers qual, Handle<String> name,
153 Expression *type, ExpressionList *dims, Expression *initialization)
157 initialization_(initialization),
164 DECLARE_NODE(VariableDeclaration);
166 Expression *initialization() const {
167 return initialization_;
169 Handle<String> name() {
172 Expression *declType() const {
175 void setSymbol(VariableSymbol *sym) {
179 VariableSymbol *sym() const {
182 Expression *type() const {
185 ExpressionList *dims() const {
188 TypeQualifiers quals() const {
193 class Parameter : public PoolObject
195 ScopedRoot<String> name_;
198 Expression *initializer_;
199 VariableSymbol *sym_;
201 ExpressionList *dims_;
202 TypeQualifiers quals_;
205 Parameter(Handle<String> name, Expression *type, bool reference, TypeQualifiers quals,
206 ExpressionList *dims, Expression *initializer, const SourcePosition &pos)
209 reference_(reference),
210 initializer_(initializer),
218 Expression *type() const {
221 Handle<String> name() const {
224 bool reference() const {
227 TypeQualifiers quals() const {
230 ExpressionList *dims() const {
233 Expression *initializer() const {
236 void setSymbol(VariableSymbol *sym) {
240 VariableSymbol *sym() const {
243 const SourcePosition &pos() const {
248 class NameProxy : public Expression
250 ScopedRoot<String> name_;
254 NameProxy(const SourcePosition &pos, Handle<String> name)
261 DECLARE_NODE(NameProxy);
263 Handle<String> name() const {
266 Symbol *sym() const {
269 void bind(Symbol *sym) {
274 class BooleanLiteral : public Expression
279 BooleanLiteral(const SourcePosition &pos, TokenKind token)
285 DECLARE_NODE(BooleanLiteral);
286 TokenKind token() const {
291 class IntegerLiteral : public Expression
296 IntegerLiteral(const SourcePosition &pos, int value)
302 DECLARE_NODE(IntegerLiteral);
309 class FloatLiteral : public Expression
314 FloatLiteral(const SourcePosition &pos, double value)
320 DECLARE_NODE(FloatLiteral);
322 double value() const {
327 class StringLiteral : public Expression
329 ScopedRoot<String> string_;
332 StringLiteral(const SourcePosition &pos, String *string)
338 DECLARE_NODE(StringLiteral);
340 String *string() const {
345 class ArrayLiteral : public Expression
348 ExpressionList *expressions_;
351 ArrayLiteral(const SourcePosition &pos, TokenKind token, ExpressionList *expressions)
354 expressions_(expressions)
358 DECLARE_NODE(ArrayLiteral);
360 TokenKind token() const {
363 ExpressionList *expressions() const {
366 bool isFixed() const {
367 return token_ == TOK_LBRACE;
371 class UnaryExpression : public Expression
373 Expression *expression_;
378 UnaryExpression(const SourcePosition &pos, TokenKind token, Expression *expr)
386 UnaryExpression(const SourcePosition &pos, TokenKind token, Expression *expr,
395 DECLARE_NODE(UnaryExpression);
397 Expression *expression() const {
400 TokenKind token() const {
403 NameProxy *tag() const {
408 class BinaryExpression : public Expression
415 BinaryExpression(const SourcePosition &pos, TokenKind token, Expression *left, Expression *right)
423 DECLARE_NODE(BinaryExpression);
425 Expression *left() const {
428 Expression *right() const {
431 TokenKind token() const {
436 class TernaryExpression : public Expression
438 Expression *condition_;
443 TernaryExpression(const SourcePosition &pos, Expression *condition, Expression *left, Expression *right)
445 condition_(condition),
451 DECLARE_NODE(TernaryExpression);
453 Expression *condition() const {
456 Expression *left() const {
459 Expression *right() const {
464 class IndexExpression : public Expression
470 IndexExpression(const SourcePosition &pos, Expression *left, Expression *right)
477 DECLARE_NODE(IndexExpression);
479 Expression *left() const {
482 Expression *right() const {
487 class FieldExpression : public Expression
490 ScopedRoot<String> field_;
493 FieldExpression(const SourcePosition &pos, Expression *left, Handle<String> field)
500 DECLARE_NODE(FieldExpression);
502 Expression *left() const {
505 Handle<String> field() const {
510 class CallExpression : public Expression
513 ExpressionList *arguments_;
516 CallExpression(const SourcePosition &pos, Expression *callee, ExpressionList *arguments)
519 arguments_(arguments)
523 DECLARE_NODE(CallExpression);
525 Expression *callee() const {
528 ExpressionList *arguments() const {
533 class ForStatement : public Statement
535 Statement *initialization_;
536 Expression *condition_;
542 ForStatement(const SourcePosition &pos, Statement *initialization,
543 Expression *condition, Statement *update, Statement *body)
545 initialization_(initialization),
546 condition_(condition),
553 DECLARE_NODE(ForStatement);
555 Statement *initialization() const {
556 return initialization_;
558 Expression *condition() const {
561 Statement *update() const {
564 Statement *body() const {
567 Scope *scope() const {
570 void setScope(Scope *scope) {
575 class WhileStatement : public Statement
578 Expression *condition_;
582 WhileStatement(const SourcePosition &pos, TokenKind kind, Expression *condition, Statement *body)
585 condition_(condition),
590 DECLARE_NODE(WhileStatement);
592 TokenKind token() const {
595 Expression *condition() const {
598 Statement *body() const {
603 class ReturnStatement : public Statement
605 Expression *expression_;
608 ReturnStatement(const SourcePosition &pos, Expression *expression)
610 expression_(expression)
614 DECLARE_NODE(ReturnStatement);
616 Expression *expression() const {
621 class BreakStatement : public Statement
624 BreakStatement(const SourcePosition &pos)
629 DECLARE_NODE(BreakStatement);
632 class ContinueStatement : public Statement
635 ContinueStatement(const SourcePosition &pos)
640 DECLARE_NODE(ContinueStatement);
643 class Assignment : public Expression
647 Expression *expression_;
650 Assignment(const SourcePosition &pos, TokenKind token, Expression *left, Expression *right)
658 DECLARE_NODE(Assignment);
660 TokenKind token() const {
663 Expression *lvalue() const {
666 Expression *expression() const {
671 class ExpressionStatement : public Statement
673 Expression *expression_;
676 ExpressionStatement(Expression *expression)
677 : Statement(expression->pos()),
678 expression_(expression)
682 DECLARE_NODE(ExpressionStatement);
684 Expression *expression() const {
689 class BlockStatement : public Statement
691 StatementList *statements_;
696 BlockStatement(const SourcePosition &pos, StatementList *statements, TokenKind kind)
698 statements_(statements),
704 DECLARE_NODE(BlockStatement);
706 StatementList *statements() const {
709 Scope *scope() const {
712 void setScope(Scope *scope) {
715 TokenKind type() const {
720 typedef PoolList<Parameter *> ParameterList;
722 class FunctionSignature
725 FunctionSignature(Expression *returnType, ParameterList *parameters, bool variadic)
726 : returnType_(returnType),
727 parameters_(parameters),
732 Expression *returnType() const {
735 ParameterList *parameters() const {
738 bool variadic() const {
743 Expression *returnType_;
744 ParameterList *parameters_;
748 class FunctionTypeStatement : public Statement
751 FunctionTypeStatement(const SourcePosition &pos, Handle<String> name, const FunctionSignature &signature)
754 signature_(signature)
758 DECLARE_NODE(FunctionTypeStatement);
760 Handle<String> name() const {
763 const FunctionSignature &signature() const {
768 ScopedRoot<String> name_;
769 FunctionSignature signature_;
773 class FunctionStatement : public Statement
775 ScopedRoot<String> name_;
778 FunctionSignature signature_;
779 bool explicitReturn_;
780 FunctionSymbol *sym_;
785 FunctionStatement(const SourcePosition &pos, Handle<String> name, TokenKind kind,
786 Statement *body, const FunctionSignature &signature, bool explicitReturn)
791 signature_(signature),
792 explicitReturn_(explicitReturn),
799 DECLARE_NODE(FunctionStatement);
801 Handle<String> name() const {
804 Statement *body() const {
807 const FunctionSignature &signature() {
810 bool hasExplicitReturn() const {
811 return explicitReturn_;
813 TokenKind token() const {
816 void setSymbol(FunctionSymbol *sym) {
820 FunctionSymbol *sym() const {
823 void setScopes(Scope *argScope, Scope *varScope) {
824 argScope_ = argScope;
825 varScope_ = varScope;
827 Scope *argScope() const {
830 Scope *varScope() const {
835 class IfStatement : public Statement
837 Expression *condition_;
842 IfStatement(const SourcePosition &pos, Expression *condition, Statement *ifTrue)
844 condition_(condition),
850 DECLARE_NODE(IfStatement);
852 Expression *condition() const {
855 Statement *ifTrue() const {
858 Statement *ifFalse() const {
861 void setIfFalse(Statement *ifFalse) {
866 class EnumStatement : public Statement
868 ScopedRoot<String> name_;
873 ScopedRoot<String> name;
878 Entry(Handle<String> name, Expression *expr, const SourcePosition &pos)
887 typedef PoolList<Entry> EntryList;
890 EnumStatement(const SourcePosition &pos, TokenKind visibility, Handle<String> name, EntryList *entries)
895 visibility_(visibility)
899 DECLARE_NODE(EnumStatement);
901 Handle<String> name() const {
904 EntryList *entries() const {
907 void setSymbol(TypeSymbol *sym) {
911 TypeSymbol *sym() const {
914 TokenKind visibility() const {
920 TokenKind visibility_;
923 class IncDecExpression : public Expression
926 Expression *expression_;
930 IncDecExpression(const SourcePosition &pos, TokenKind token, Expression *expression, bool postfix)
933 expression_(expression),
938 DECLARE_NODE(IncDecExpression);
940 TokenKind token() const {
943 Expression *expression() const {
946 bool postfix() const {
951 class Case : public PoolObject
954 Case(Expression *expression, ExpressionList *others, Statement *statement)
955 : expression_(expression),
957 statement_(statement)
961 Expression *expression() const {
964 PoolList<Expression *> *others() const {
967 Statement *statement() const {
972 Expression *expression_;
973 PoolList <Expression *> *others_;
974 Statement *statement_;
982 CaseValue(size_t statement)
983 : statement(statement)
988 typedef PoolList<CaseValue> CaseValueList;
990 class SwitchStatement : public Statement
993 SwitchStatement(const SourcePosition &pos, Expression *expression, PoolList<Case *> *cases,
996 expression_(expression),
1003 DECLARE_NODE(SwitchStatement);
1005 Expression *expression() const {
1008 PoolList<Case *> *cases() const {
1011 Statement *defaultCase() const {
1014 void setCaseValueList(CaseValueList *list) {
1017 CaseValueList *caseValueList() const {
1022 Expression *expression_;
1023 PoolList<Case *> *cases_;
1024 Statement *default_;
1025 CaseValueList *table_;
1028 class StructureStatement : public Statement
1031 class Field : public PoolObject
1033 SourcePosition pos_;
1035 ScopedRoot<String> name_;
1038 Field(const SourcePosition &pos,
1040 Handle<String> name)
1047 const SourcePosition &pos() const {
1050 Handle<String> name() const {
1053 Expression *type() const {
1058 typedef PoolList<StructureStatement::Field *> FieldList;
1061 StructureStatement(const SourcePosition &pos, Handle<String> name, FieldList *fields)
1069 DECLARE_NODE(StructureStatement);
1071 FieldList *fields() const {
1074 Handle<String> name() const {
1077 void setSymbol(TypeSymbol *sym) {
1081 TypeSymbol *sym() const {
1086 ScopedRoot<String> name_;
1091 typedef PoolList<ScopedRoot<String> *> NameList;
1093 class ImportStatement : public Statement
1096 ImportStatement(const SourcePosition &pos, PathComponent *path, NameList *names)
1103 DECLARE_NODE(ImportStatement);
1105 PathComponent *path() const {
1108 void setSource(Importable *source) {
1111 Handle<Importable> source() {
1114 unsigned importIndex() const {
1115 return importIndex_;
1117 void setImportIndex(unsigned index) {
1118 importIndex_ = index;
1120 NameList *names() const {
1124 bool importAllNames() const {
1125 return names_ && names_->empty();
1129 PathComponent *path_;
1130 ScopedRoot<Importable> source_;
1131 unsigned importIndex_;
1135 typedef StructureStatement::FieldList FieldList;
1136 typedef PoolList<NameProxy *> NameProxyList;
1140 class ParseTree : public PoolObject
1142 StatementList *statements_;
1143 NameProxyList *unbound_;
1144 PoolList<ImportStatement *> *imports_;
1147 ParseTree(StatementList *statements, NameProxyList *unbound, PoolList<ImportStatement *> *imports)
1148 : statements_(statements),
1154 void dump(FILE *fp);
1156 StatementList *statements() const {
1159 NameProxyList *unbound() const {
1162 PoolList<ImportStatement *> *imports() const {
1169 #endif // _include_sourcepawn_ast_h_