asherkin@263: /* asherkin@263: * Copyright (C) 2012 David Anderson asherkin@263: * asherkin@263: * This file is part of SourcePawn. asherkin@263: * asherkin@263: * SourcePawn is free software: you can redistribute it and/or modify it under asherkin@263: * the terms of the GNU General Public License as published by the Free asherkin@263: * Software Foundation, either version 3 of the License, or (at your option) asherkin@263: * any later version. asherkin@263: * asherkin@263: * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY asherkin@263: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS asherkin@263: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. asherkin@263: * asherkin@263: * You should have received a copy of the GNU General Public License along with asherkin@263: * SourcePawn. If not, see http://www.gnu.org/licenses/. asherkin@263: */ asherkin@263: #ifndef _include_jitcraft_compile_context_h_ asherkin@263: #define _include_jitcraft_compile_context_h_ asherkin@263: asherkin@263: #include asherkin@263: #include asherkin@263: #include "../Messages.h" asherkin@263: #include "../PoolAllocator.h" asherkin@263: #include "../Handles.h" asherkin@263: #include "../Modules.h" asherkin@263: #include "../Packages.h" asherkin@263: asherkin@263: namespace ke { asherkin@263: asherkin@263: class Zone; asherkin@263: class ParseTree; asherkin@263: class String; asherkin@263: class ImportScope; asherkin@263: class GlobalScope; asherkin@263: struct SourcePosition; asherkin@263: struct TranslationUnit; asherkin@263: class ImportStatement; asherkin@263: asherkin@263: struct CompileError asherkin@263: { asherkin@263: CompileError() asherkin@263: : message(NULL) asherkin@263: { asherkin@263: } asherkin@263: CompileError(unsigned line, unsigned col, const char *message) asherkin@263: : line(line), asherkin@263: col(col), asherkin@263: message(message) asherkin@263: { asherkin@263: } asherkin@263: asherkin@263: unsigned line; asherkin@263: unsigned col; asherkin@263: const char *message; asherkin@263: }; asherkin@263: asherkin@263: struct TranslationUnit : public PoolObject asherkin@263: { asherkin@263: TranslationUnit(Handle module) asherkin@263: : tree_(NULL), asherkin@263: importScope_(NULL), asherkin@263: globalScope_(NULL), asherkin@263: module_(module), asherkin@263: enoughMemory_(true), asherkin@263: dependencyFailed_(false) asherkin@263: { asherkin@263: } asherkin@263: asherkin@263: void destroy(); asherkin@263: asherkin@263: ParseTree *tree_; asherkin@263: PoolList dependents_; asherkin@263: ImportScope *importScope_; asherkin@263: GlobalScope *globalScope_; asherkin@263: ScopedRoot module_; asherkin@263: asherkin@263: ParseTree *tree() const { asherkin@263: return tree_; asherkin@263: } asherkin@263: PoolList &dependents() { asherkin@263: return dependents_; asherkin@263: } asherkin@263: bool failed() const { asherkin@263: return errors_.length() || asherkin@263: !enoughMemory_ || asherkin@263: dependencyFailed_; asherkin@263: } asherkin@263: void setImportScope(ImportScope *scope) { asherkin@263: assert(!importScope_); asherkin@263: importScope_ = scope; asherkin@263: } asherkin@263: void setGlobalScope(GlobalScope *scope) { asherkin@263: assert(!globalScope_); asherkin@263: globalScope_ = scope; asherkin@263: } asherkin@263: ImportScope *importScope() const { asherkin@263: return importScope_; asherkin@263: } asherkin@263: GlobalScope *globalScope() const { asherkin@263: return globalScope_; asherkin@263: } asherkin@263: Handle module() { asherkin@263: return module_; asherkin@263: } asherkin@263: asherkin@263: void setDependencyFailed() { asherkin@263: dependencyFailed_ = true; asherkin@263: } asherkin@263: void setOutOfMemory() { asherkin@263: enoughMemory_ = false; asherkin@263: } asherkin@263: void appendError(const char *report, unsigned line, unsigned col) { asherkin@263: enoughMemory_ |= errors_.append(CompileError(line, col, report)); asherkin@263: } asherkin@263: const Vector *errors() { asherkin@263: return &errors_; asherkin@263: } asherkin@263: asherkin@263: private: asherkin@263: bool enoughMemory_; asherkin@263: bool dependencyFailed_; asherkin@263: Vector errors_; asherkin@263: }; asherkin@263: asherkin@263: class CompileContext asherkin@263: { asherkin@263: Zone *zone_; asherkin@263: Vector units_; asherkin@263: Vector unparsed_; asherkin@263: TranslationUnit *active_; asherkin@263: asherkin@263: private: asherkin@263: char *loadSource(Handle module, size_t *length); asherkin@263: bool parse(TranslationUnit *unit); asherkin@263: bool evaluateImports(TranslationUnit *unit); asherkin@263: bool propagateFailure(); asherkin@263: bool add(Handle module); asherkin@263: asherkin@263: public: asherkin@263: CompileContext(Zone *zone); asherkin@263: ~CompileContext(); asherkin@263: asherkin@263: bool initialize(Handle package, const char *name); asherkin@263: bool compile(); asherkin@263: void enter(TranslationUnit *unit); asherkin@263: void leave(); asherkin@263: asherkin@263: void reportErrorVa(const SourcePosition &pos, Message msg, va_list ap); asherkin@263: void reportError(const SourcePosition &pos, Message msg, ...); asherkin@263: }; asherkin@263: asherkin@263: class AutoEnterCompileContext asherkin@263: { asherkin@263: CompileContext &cc_; asherkin@263: asherkin@263: public: asherkin@263: AutoEnterCompileContext(CompileContext &cc, TranslationUnit *unit) asherkin@263: : cc_(cc) asherkin@263: { asherkin@263: cc_.enter(unit); asherkin@263: } asherkin@263: ~AutoEnterCompileContext() { asherkin@263: cc_.leave(); asherkin@263: } asherkin@263: }; asherkin@263: asherkin@263: } // namespace ke asherkin@263: asherkin@263: #endif // _include_jitcraft_compile_context_h_