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