Refactor compilation process around the new concept of packages.
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);
67 void visitStringLiteral(StringLiteral *node);
68 void visitUnaryExpression(UnaryExpression *node);
69 void visitBooleanLiteral(BooleanLiteral *node);
71 void visitFunctionTypeStatement(FunctionTypeStatement *node);
72 void visitImportStatement(ImportStatement *node);
73 void visitStructureStatement(StructureStatement *node);
74 void visitSwitchStatement(SwitchStatement *node);
76 void visitTernaryExpression(TernaryExpression *node);
77 void visitFieldExpression(FieldExpression *node);
78 void visitArrayLiteral(ArrayLiteral *node);
82 bool checkArgumentCount(Handle<FunctionType> type, unsigned actual);
92 // For a given control flow path, whether it returns.
100 // For a given control flow path, whether it terminates,
101 // and if it terminates, whether it returns.
105 ReturnStatus returns_;
111 ControlStatus(bool terminates, ReturnStatus returns)
112 : terminates_(terminates),
117 bool terminates() const {
120 ReturnStatus returns() const {
127 ReturnStatus returns_;
128 ControlScope **prevp_;
133 ControlScope(ControlScope **prevp)
134 : returns_(Returns_Never),
144 ControlStatus status() {
145 return ControlStatus(terminates_, returns_);
148 void returns(ReturnStatus status) {
149 // We allow multiple terminates, but only the first one takes
150 // effect. For example, |break; continue;| is legal, but the
151 // continue is unreachable.
154 if (status > returns_)
157 void terminate(ReturnStatus status) {
163 void merge(const ControlStatus &left, const ControlStatus &right);
164 void inherit(const ControlStatus &other);
168 void requireLifoStack();
169 ControlStatus visitForControl(Statement *statement);
170 ControlStatus visitLoopBody(Statement *stmt);
171 void visitForTest(Expression *expr,
172 BytecodeEmitter::Label *trueBranch,
173 BytecodeEmitter::Label *falseBranch,
174 BytecodeEmitter::Label *fallthrough);
175 void set(VariableSymbol *sym);
176 HIR *eval(Expression *expr);
177 HIR *binary(AstNode *node, TokenKind token, HIR *left, HIR *right);
178 HIR *coerce(HIR *from, Handle<Type> to, CoercionKind kind);
179 Type *coercionType(TokenKind token, HIR *left, HIR *right);
180 HLValue *lvalue(Expression *expr);
181 void discharge(HIR *hir);
182 HIR *typeFailure(const SourcePosition &pos, Handle<Type> from, Handle<Type> to);
184 HIR *typeCheckArray(const SourcePosition &pos,
186 Handle<ArrayType> argActual,
190 // Used to target break/catch statements.
194 BytecodeEmitter::Label *bk_;
195 BytecodeEmitter::Label *ct_;
202 LoopScope(Scope *scope, BytecodeEmitter::Label *bk, BytecodeEmitter::Label *ct,
209 usesLifoStack_(false),
220 BytecodeEmitter::Label *break_() {
223 BytecodeEmitter::Label *continue_() {
229 void setUsesLifoStack() {
230 usesLifoStack_ = true;
232 bool usesLifoStack() const {
233 return usesLifoStack_;
238 bool breaks() const {
245 PoolAllocator &pool_;
247 TranslationUnit *unit_;
250 BytecodeEmitter emitter_;
251 ScopedRoot<FunctionType> fun_;
253 ControlScope *control_;
258 #endif // _include_sp2_sema_h_