1.1 --- a/src/compiler/CompileContext.cpp Sat Dec 29 00:12:27 2012 -0800
1.2 +++ b/src/compiler/CompileContext.cpp Sat Dec 29 00:55:38 2012 -0800
1.3 @@ -30,15 +30,15 @@
1.4
1.5 CompileContext::CompileContext(Zone *zone, const char *file)
1.6 : zone_(zone),
1.7 - failures_(0),
1.8 - file_(file)
1.9 + file_(file),
1.10 + active_(NULL)
1.11 {
1.12 }
1.13
1.14 CompileContext::~CompileContext()
1.15 {
1.16 - if (failures_)
1.17 - zone_->endCompilationErrors();
1.18 + for (size_t i = 0; i < units_.length(); i++)
1.19 + delete units_[i];
1.20 }
1.21
1.22 bool
1.23 @@ -94,6 +94,8 @@
1.24 bool
1.25 CompileContext::parse(TranslationUnit *unit)
1.26 {
1.27 + AutoEnterCompileContext enter(*this, unit);
1.28 +
1.29 assert(!unit->tree_);
1.30
1.31 size_t length;
1.32 @@ -108,11 +110,11 @@
1.33 return true;
1.34 }
1.35
1.36 -bool
1.37 +void
1.38 CompileContext::evaluateImports(TranslationUnit *unit)
1.39 {
1.40 if (units_.length() > 1)
1.41 - return true;
1.42 + return;
1.43
1.44 #if 0
1.45 // For now we hardcode this...
1.46 @@ -128,8 +130,6 @@
1.47 if (!addTranslationUnit(u2))
1.48 return false;
1.49 #endif
1.50 -
1.51 - return true;
1.52 }
1.53
1.54 bool
1.55 @@ -148,7 +148,7 @@
1.56 if (other->failed())
1.57 continue;
1.58
1.59 - other->failed_ = true;
1.60 + other->setDependencyFailed();
1.61 if (!worklist.append(other))
1.62 return false;
1.63 }
1.64 @@ -166,10 +166,9 @@
1.65 TranslationUnit *unit = unparsed_.popCopy();
1.66
1.67 if (!parse(unit))
1.68 - unit->failed_ = true;
1.69 + continue;
1.70
1.71 - if (!evaluateImports(unit))
1.72 - unit->failed_ = true;
1.73 + evaluateImports(unit);
1.74 }
1.75
1.76 // Phase 2. Create scopes and symbol tables for every lexical region with
1.77 @@ -179,8 +178,7 @@
1.78 if (unit->failed())
1.79 continue;
1.80
1.81 - if (!PopulateNamesAndTypes(zone_, *this, unit))
1.82 - unit->failed_ = true;
1.83 + PopulateNamesAndTypes(zone_, *this, unit);
1.84 }
1.85
1.86 // Phase 3. Complete imports and bind all names.
1.87 @@ -189,8 +187,7 @@
1.88 if (unit->failed())
1.89 continue;
1.90
1.91 - if (!BindNamesAndTypes(zone_, *this, unit))
1.92 - unit->failed_ = true;
1.93 + BindNamesAndTypes(zone_, *this, unit);
1.94 }
1.95
1.96 // Phase 4. Assign types to every public name in the module.
1.97 @@ -206,62 +203,77 @@
1.98 if (!propagateFailure())
1.99 return false;
1.100
1.101 - // Phase 4. Perform full semantic analysis on each module.
1.102 + // Phase 4. Now we can finally perform SemA+bytecode compilation.
1.103 for (size_t i = 0; i < units_.length(); i++) {
1.104 TranslationUnit *unit = units_[i];
1.105 if (unit->failed())
1.106 continue;
1.107
1.108 -
1.109 - }
1.110 -
1.111 - // Intermediate phase. Propagate failure from semantic analysis.
1.112 - if (!propagateFailure())
1.113 - return false;
1.114 -
1.115 - // Phase 5. Now we can finally perform bytecode compilation.
1.116 - for (size_t i = 0; i < units_.length(); i++) {
1.117 - TranslationUnit *unit = units_[i];
1.118 - if (unit->failed())
1.119 - continue;
1.120 -
1.121 + AutoEnterCompileContext enter(*this, unit);
1.122 SemanticAnalysis sema(zone_, *this, unit);
1.123 sema.analyze();
1.124 }
1.125
1.126 - // Phase 6. Run modules.
1.127 + // Phase 5. Run modules.
1.128 for (size_t i = 0; i < units_.length(); i++) {
1.129 TranslationUnit *unit = units_[i];
1.130 if (unit->failed())
1.131 - continue;
1.132 + break;
1.133
1.134 InvokeArgs args;
1.135 if (!zone_->stack().pushModuleFrame(unit->module_, args))
1.136 assert(false);
1.137
1.138 - if (failures_)
1.139 - return false;
1.140 -
1.141 ke::LocalSlot slot;
1.142 if (!Interpret(zone_, NULL, &slot))
1.143 assert(false);
1.144 }
1.145
1.146 - if (failures_)
1.147 - return false;
1.148 + if (Ke::IMessageReporter *reporter = zone_->errorReporter()) {
1.149 + for (size_t i = 0; i < units_.length(); i++) {
1.150 + TranslationUnit *unit = units_[i];
1.151 +
1.152 + // We don't explicitly report errors for dependency failures or OOM
1.153 + // (OOM is reported separately (:TODO:) and dep failures are redundant.
1.154 + if (!unit->errors()->length())
1.155 + continue;
1.156
1.157 - return true;
1.158 + reporter->beginCompilationErrors(unit->path_);
1.159 + for (size_t j = 0; j < unit->errors()->length(); j++) {
1.160 + const CompileError &error = unit->errors()->at(j);
1.161 + reporter->reportCompilationError(error.message, error.line, error.col);
1.162 + }
1.163 + reporter->endCompilationErrors();
1.164 + }
1.165 + }
1.166 +
1.167 + return !units_[0]->failed();
1.168 +}
1.169 +
1.170 +void
1.171 +CompileContext::enter(TranslationUnit *unit)
1.172 +{
1.173 + assert(!active_);
1.174 + active_ = unit;
1.175 +}
1.176 +
1.177 +void
1.178 +CompileContext::leave()
1.179 +{
1.180 + assert(active_);
1.181 + active_ = NULL;
1.182 }
1.183
1.184 void
1.185 CompileContext::reportErrorVa(const SourcePosition &pos, Message msg, va_list ap)
1.186 {
1.187 - if (!failures_)
1.188 - zone_->beginCompilationErrors(file_);
1.189 + const char *report = BuildErrorMessage(Messages[msg].format, ap);
1.190 + if (!report) {
1.191 + active_->setOutOfMemory();
1.192 + return;
1.193 + }
1.194
1.195 - zone_->reportCompilationError(msg, pos.line, pos.col, ap);
1.196 -
1.197 - failures_++;
1.198 + active_->appendError(report, pos.line, pos.col);
1.199 }
1.200
1.201 void
1.202 @@ -272,3 +284,9 @@
1.203 reportErrorVa(pos, msg, ap);
1.204 va_end(ap);
1.205 }
1.206 +
1.207 +TranslationUnit::~TranslationUnit()
1.208 +{
1.209 + for (size_t i = 0; i < errors_.length(); i++)
1.210 + FreeErrorMessage(errors_[i].message);
1.211 +}