Re-add enum support.
2 * Copyright (C) 2012 David Anderson
4 * This file is part of SourcePawn.
6 * SourcePawn is free software: you can redistribute it and/or modify it under
7 * the terms of the GNU General Public License as published by the Free
8 * Software Foundation, either version 3 of the License, or (at your option)
11 * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along with
16 * SourcePawn. If not, see http://www.gnu.org/licenses/.
18 #ifndef _include_sp2_sema_h_
19 #define _include_sp2_sema_h_
24 #include "BytecodeEmitter.h"
28 // Semantic analysis occurs after all names and types have been bound. It
29 // performs the important task of validating the semantics and type safety
32 // The semantic analysis phase also produces bytecode. This occurs on a
33 // statement-by-statement basis. The result of analyzing an expression is a
34 // tree of operations which is then flattened.
35 class SemanticAnalysis : public AstVisitor
38 SemanticAnalysis(Zone *zone, CompileContext &cc, TranslationUnit *unit);
43 SemanticAnalysis(SemanticAnalysis *parent, Handle<FunctionType> fun);
44 Function *compile(FunctionStatement *stmt);
47 void visitFunctionStatement(FunctionStatement *node);
48 void visitBlockStatement(BlockStatement *node);
49 void visitExpressionStatement(ExpressionStatement *node);
50 void visitReturnStatement(ReturnStatement *node);
51 void visitEnumStatement(EnumStatement *node);
53 void visitCallExpression(CallExpression *node);
54 void visitNameProxy(NameProxy *name);
55 void visitIntegerLiteral(IntegerLiteral *node);
56 void visitFloatLiteral(FloatLiteral *node);
57 void visitVariableDeclaration(VariableDeclaration *node);
58 void visitForStatement(ForStatement *node);
59 void visitWhileStatement(WhileStatement *node);
60 void visitAssignment(Assignment *node);
61 void visitBinaryExpression(BinaryExpression *node);
62 void visitBreakStatement(BreakStatement *node);
63 void visitContinueStatement(ContinueStatement *node);
64 void visitIfStatement(IfStatement *node);
65 void visitIndexExpression(IndexExpression *node);
66 void visitIncDecExpression(IncDecExpression *node);
68 void visitFunctionTypeStatement(FunctionTypeStatement *node);
69 void visitImportStatement(ImportStatement *node);
70 void visitStructureStatement(StructureStatement *node);
71 void visitSwitchStatement(SwitchStatement *node);
73 void visitStringLiteral(StringLiteral *node);
74 void visitUnaryExpression(UnaryExpression *node);
75 void visitTernaryExpression(TernaryExpression *node);
76 void visitBooleanLiteral(BooleanLiteral *node);
77 void visitFieldExpression(FieldExpression *node);
78 void visitArrayLiteral(ArrayLiteral *node);
82 bool checkArgumentCount(Handle<FunctionType> type, unsigned actual);
91 // For a given control flow path, whether it returns.
99 // For a given control flow path, whether it terminates,
100 // and if it terminates, whether it returns.
104 ReturnStatus returns_;
110 ControlStatus(bool terminates, ReturnStatus returns)
111 : terminates_(terminates),
116 bool terminates() const {
119 ReturnStatus returns() const {
126 ReturnStatus returns_;
127 ControlScope **prevp_;
132 ControlScope(ControlScope **prevp)
133 : returns_(Returns_Never),
143 ControlStatus status() {
144 return ControlStatus(terminates_, returns_);
147 void returns(ReturnStatus status) {
148 // We allow multiple terminates, but only the first one takes
149 // effect. For example, |break; continue;| is legal, but the
150 // continue is unreachable.
153 if (status > returns_)
156 void terminate(ReturnStatus status) {
162 void merge(const ControlStatus &left, const ControlStatus &right);
163 void inherit(const ControlStatus &other);
167 void requireLifoStack();
168 ControlStatus visitForControl(Statement *statement);
169 ControlStatus visitLoopBody(Statement *stmt);
170 void visitForTest(Expression *expr,
171 BytecodeEmitter::Label *trueBranch,
172 BytecodeEmitter::Label *falseBranch,
173 BytecodeEmitter::Label *fallthrough);
174 void set(VariableSymbol *sym);
175 HIR *eval(Expression *expr);
176 HIR *binary(AstNode *node, TokenKind token, HIR *left, HIR *right);
177 HIR *coerce(HIR *from, Handle<Type> to, CoercionKind kind);
178 Type *coercionType(TokenKind token, HIR *left, HIR *right);
179 HLValue *lvalue(Expression *expr);
180 void discharge(HIR *hir);
181 HIR *typeFailure(const SourcePosition &pos, Handle<Type> from, Handle<Type> to);
183 bool typeCheckArray(const SourcePosition &pos,
184 Handle<Type> argGiven,
185 Handle<Type> argActual,
189 // Used to target break/catch statements.
193 BytecodeEmitter::Label *bk_;
194 BytecodeEmitter::Label *ct_;
201 LoopScope(Scope *scope, BytecodeEmitter::Label *bk, BytecodeEmitter::Label *ct,
208 usesLifoStack_(false),
219 BytecodeEmitter::Label *break_() {
222 BytecodeEmitter::Label *continue_() {
228 void setUsesLifoStack() {
229 usesLifoStack_ = true;
231 bool usesLifoStack() const {
232 return usesLifoStack_;
237 bool breaks() const {
244 PoolAllocator &pool_;
246 TranslationUnit *unit_;
249 BytecodeEmitter emitter_;
250 ScopedRoot<Module> module_;
251 ScopedRoot<FunctionType> fun_;
253 ControlScope *control_;
258 #endif // _include_sp2_sema_h_