void If::doSemanticCheck() { Node* condition = children_[0]; Node* thenClause = children_[1]; Node* elseClause = children_[2]; // The resulting type is Void type_ = Void::get(context_->evalMode()); // Semantic check the condition condition->semanticCheck(); // Check that the type of the condition is 'Testable' if ( !isTestable(condition) ) REP_ERROR(condition->location(), "The condition of the if is not Testable"); // Dereference the condition as much as possible while ( condition->type() && condition->type()->noReferences() > 0 ) { condition = mkMemLoad(condition->location(), condition); condition->setContext(childrenContext()); condition->semanticCheck(); } children_[0] = condition; // TODO (if): Remove this dereference from here if ( nodeEvalMode(this) == modeCt ) { if ( !isCt(condition) ) REP_ERROR(condition->location(), "The condition of the ct if should be available at compile-time (%1%)") % condition->type(); // Get the CT value from the condition, and select an active branch Node* c = theCompiler().ctEval(condition); Node* selectedBranch = getBoolCtValue(c) ? thenClause : elseClause; // Expand only the selected branch if ( selectedBranch ) setExplanation(selectedBranch); else setExplanation(mkNop(location_)); return; } // Semantic check the clauses if ( thenClause ) thenClause->semanticCheck(); if ( elseClause ) elseClause->semanticCheck(); }
//! Given an import module name, add the corresponding source code to the compiler //! Returns the created SourceCode object Nest_SourceCode* addImportedSourceCode( const Nest_SourceCode* curSourceCode, NodeHandle moduleName) { Literal modNameLit = moduleName.kindCast<Literal>(); if (modNameLit) { if (!modNameLit.isString()) REP_INTERNAL(moduleName.location(), "Invalid import name found %1%") % Nest_toStringEx(moduleName); return checkAddSourceCode(moduleName.location(), curSourceCode, modNameLit.dataStr()); } else { QidVec qid; interpretQualifiedId(moduleName, qid); if (qid.empty()) REP_ERROR(moduleName.location(), "Nothing to import"); // Transform qid into filename/dirname string filename; for (const auto& part : qid) { if (!filename.empty()) filename += "/"; filename += part.first.begin; } return checkAddSourceCode( moduleName.location(), curSourceCode, StringRef(filename + ".spr")); } }
//! Add the given filename to the compiler, and return its sourcecode //! Check for errors Nest_SourceCode* checkAddSourceCode( const Location& loc, const Nest_SourceCode* curSourceCode, StringRef filename) { auto importedSc = Nest_addSourceCodeByFilename(curSourceCode, filename); if (!importedSc) REP_ERROR(loc, "Cannot import %1%") % filename; return importedSc; }