diff -r 82b1f8bc93a9 -r 0998a43cc155 src/compiler/CompileContext.cpp --- a/src/compiler/CompileContext.cpp Sat Dec 29 00:12:27 2012 -0800 +++ b/src/compiler/CompileContext.cpp Sat Dec 29 00:55:38 2012 -0800 @@ -30,15 +30,15 @@ CompileContext::CompileContext(Zone *zone, const char *file) : zone_(zone), - failures_(0), - file_(file) + file_(file), + active_(NULL) { } CompileContext::~CompileContext() { - if (failures_) - zone_->endCompilationErrors(); + for (size_t i = 0; i < units_.length(); i++) + delete units_[i]; } bool @@ -94,6 +94,8 @@ bool CompileContext::parse(TranslationUnit *unit) { + AutoEnterCompileContext enter(*this, unit); + assert(!unit->tree_); size_t length; @@ -108,11 +110,11 @@ return true; } -bool +void CompileContext::evaluateImports(TranslationUnit *unit) { if (units_.length() > 1) - return true; + return; #if 0 // For now we hardcode this... @@ -128,8 +130,6 @@ if (!addTranslationUnit(u2)) return false; #endif - - return true; } bool @@ -148,7 +148,7 @@ if (other->failed()) continue; - other->failed_ = true; + other->setDependencyFailed(); if (!worklist.append(other)) return false; } @@ -166,10 +166,9 @@ TranslationUnit *unit = unparsed_.popCopy(); if (!parse(unit)) - unit->failed_ = true; + continue; - if (!evaluateImports(unit)) - unit->failed_ = true; + evaluateImports(unit); } // Phase 2. Create scopes and symbol tables for every lexical region with @@ -179,8 +178,7 @@ if (unit->failed()) continue; - if (!PopulateNamesAndTypes(zone_, *this, unit)) - unit->failed_ = true; + PopulateNamesAndTypes(zone_, *this, unit); } // Phase 3. Complete imports and bind all names. @@ -189,8 +187,7 @@ if (unit->failed()) continue; - if (!BindNamesAndTypes(zone_, *this, unit)) - unit->failed_ = true; + BindNamesAndTypes(zone_, *this, unit); } // Phase 4. Assign types to every public name in the module. @@ -206,62 +203,77 @@ if (!propagateFailure()) return false; - // Phase 4. Perform full semantic analysis on each module. + // Phase 4. Now we can finally perform SemA+bytecode compilation. for (size_t i = 0; i < units_.length(); i++) { TranslationUnit *unit = units_[i]; if (unit->failed()) continue; - - } - - // Intermediate phase. Propagate failure from semantic analysis. - if (!propagateFailure()) - return false; - - // Phase 5. Now we can finally perform bytecode compilation. - for (size_t i = 0; i < units_.length(); i++) { - TranslationUnit *unit = units_[i]; - if (unit->failed()) - continue; - + AutoEnterCompileContext enter(*this, unit); SemanticAnalysis sema(zone_, *this, unit); sema.analyze(); } - // Phase 6. Run modules. + // Phase 5. Run modules. for (size_t i = 0; i < units_.length(); i++) { TranslationUnit *unit = units_[i]; if (unit->failed()) - continue; + break; InvokeArgs args; if (!zone_->stack().pushModuleFrame(unit->module_, args)) assert(false); - if (failures_) - return false; - ke::LocalSlot slot; if (!Interpret(zone_, NULL, &slot)) assert(false); } - if (failures_) - return false; + if (Ke::IMessageReporter *reporter = zone_->errorReporter()) { + for (size_t i = 0; i < units_.length(); i++) { + TranslationUnit *unit = units_[i]; + + // We don't explicitly report errors for dependency failures or OOM + // (OOM is reported separately (:TODO:) and dep failures are redundant. + if (!unit->errors()->length()) + continue; - return true; + reporter->beginCompilationErrors(unit->path_); + for (size_t j = 0; j < unit->errors()->length(); j++) { + const CompileError &error = unit->errors()->at(j); + reporter->reportCompilationError(error.message, error.line, error.col); + } + reporter->endCompilationErrors(); + } + } + + return !units_[0]->failed(); +} + +void +CompileContext::enter(TranslationUnit *unit) +{ + assert(!active_); + active_ = unit; +} + +void +CompileContext::leave() +{ + assert(active_); + active_ = NULL; } void CompileContext::reportErrorVa(const SourcePosition &pos, Message msg, va_list ap) { - if (!failures_) - zone_->beginCompilationErrors(file_); + const char *report = BuildErrorMessage(Messages[msg].format, ap); + if (!report) { + active_->setOutOfMemory(); + return; + } - zone_->reportCompilationError(msg, pos.line, pos.col, ap); - - failures_++; + active_->appendError(report, pos.line, pos.col); } void @@ -272,3 +284,9 @@ reportErrorVa(pos, msg, ap); va_end(ap); } + +TranslationUnit::~TranslationUnit() +{ + for (size_t i = 0; i < errors_.length(); i++) + FreeErrorMessage(errors_[i].message); +}