this repo has no description
at develop 5.7 kB view raw
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2 3/* 4 * Main authors: 5 * Kevin Leo <kevin.leo@monash.edu> 6 */ 7 8/* This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 11 12#include <minizinc/MIPdomains.hh> 13#include <minizinc/astexception.hh> 14#include <minizinc/astiterator.hh> 15#include <minizinc/builtins.hh> 16#include <minizinc/copy.hh> 17#include <minizinc/eval_par.hh> 18#include <minizinc/flatten.hh> 19#include <minizinc/flatten_internal.hh> 20#include <minizinc/hash.hh> 21#include <minizinc/optimize.hh> 22#include <minizinc/parser.hh> 23#include <minizinc/passes/compile_pass.hh> 24#include <minizinc/timer.hh> 25#include <minizinc/typecheck.hh> 26 27#include <fstream> 28 29namespace MiniZinc { 30 31using std::string; 32using std::vector; 33 34Env* changeLibrary(Env& e, vector<string>& includePaths, string globals_dir, 35 CompilePassFlags& compflags, bool verbose = false) { 36 GCLock lock; 37 CopyMap cm; 38 Model* m = e.envi().orig_model ? e.envi().orig_model : e.envi().model; 39 Model* new_mod = new Model(); 40 new_mod->setFilename(m->filename().str()); 41 new_mod->setFilepath(m->filepath().str()); 42 43 vector<string> new_includePaths; 44 45 if (std::find(includePaths.begin(), includePaths.end(), globals_dir) == includePaths.end()) 46 new_includePaths.push_back(globals_dir); 47 new_includePaths.insert(new_includePaths.end(), includePaths.begin(), includePaths.end()); 48 49 // Collect include items 50 vector<string> include_names; 51 for (Item* item : *m) { 52 if (IncludeI* inc = item->dyn_cast<IncludeI>()) { 53 include_names.push_back(inc->f().str()); 54 } else { 55 new_mod->addItem(copy(e.envi(), cm, item)); 56 } 57 } 58 59 std::stringstream ss; 60 for (auto& name : include_names) ss << "include \"" << name << "\";"; 61 62 vector<SyntaxError> syntax_errors; 63 Env* fenv = new Env(new_mod); 64 // Model* inc_mod = parse(*fenv, include_names, {}, new_includePaths, true, true, verbose, 65 // std::cerr); 66 Model* inc_mod = parseFromString(*fenv, ss.str(), m->filepath().str() + "_Dummy.mzn", 67 new_includePaths, true, true, verbose, std::cerr, syntax_errors); 68 if (inc_mod == nullptr) { 69 for (const SyntaxError& se : syntax_errors) { 70 std::cerr << std::endl; 71 std::cerr << se.what() << ": " << se.msg() << std::endl; 72 std::cerr << se.loc() << std::endl; 73 } 74 return nullptr; 75 } 76 IncludeI* new_inc = new IncludeI(Location().introduce(), string("MultiPassDummy.mzn")); 77 new_inc->m(inc_mod); 78 inc_mod->setParent(new_mod); 79 new_mod->addItem(new_inc); 80 81 return fenv; 82} 83 84CompilePass::CompilePass(Env* e, FlatteningOptions& opts, CompilePassFlags& cflags, 85 string globals_library, vector<string> include_paths, bool change_lib, 86 bool ignore_unknown) 87 : env(e), 88 fopts(opts), 89 compflags(cflags), 90 library(globals_library), 91 includePaths(include_paths), 92 change_library(change_lib), 93 ignore_unknown_ids(ignore_unknown) {} 94 95Env* CompilePass::run(Env* store, std::ostream& log) { 96 Timer lasttime; 97 if (compflags.verbose) log << "\n\tCompilePass: Flatten with \'" << library << "\' library ...\n"; 98 99 Env* new_env; 100 if (change_library) { 101 new_env = changeLibrary(*env, includePaths, library, compflags, compflags.verbose); 102 if (new_env == nullptr) return nullptr; 103 new_env->envi().copyPathMapsAndState(store->envi()); 104 } else { 105 new_env = env; 106 } 107 new_env->envi().ignoreUnknownIds = ignore_unknown_ids; 108 109 vector<TypeError> typeErrors; 110 MiniZinc::typecheck(*new_env, new_env->model(), typeErrors, 111 compflags.model_check_only || compflags.model_interface_only, 112 compflags.allow_multi_assign); 113 if (typeErrors.size() > 0) { 114 std::ostringstream errstream; 115 for (unsigned int i = 0; i < typeErrors.size(); i++) { 116 errstream << typeErrors[i].what() << ": " << typeErrors[i].msg() << std::endl; 117 errstream << typeErrors[i].loc() << std::endl; 118 } 119 throw Error(errstream.str()); 120 } 121 122 registerBuiltins(*new_env); 123 124 try { 125 flatten(*new_env, fopts); 126 } catch (LocationException& e) { 127 if (compflags.verbose) log << std::endl; 128 std::ostringstream errstream; 129 errstream << e.what() << ": " << std::endl; 130 new_env->dumpErrorStack(errstream); 131 errstream << " " << e.msg() << std::endl; 132 throw Error(errstream.str()); 133 } 134 135 if (!compflags.noMIPdomains) { 136 if (compflags.verbose) log << "MIP domains ..."; 137 MIPdomains(*new_env, compflags.statistics); 138 if (compflags.verbose) log << " done (" << lasttime.stoptime() << ")" << std::endl; 139 } 140 141 if (compflags.optimize) { 142 if (compflags.verbose) log << "Optimizing ..."; 143 optimize(*new_env, compflags.chain_compression); 144 if (compflags.verbose) log << " done (" << lasttime.stoptime() << ")" << std::endl; 145 } 146 147 for (unsigned int i = 0; i < new_env->warnings().size(); i++) { 148 log << (compflags.werror ? "\n ERROR: " : "\n WARNING: ") << new_env->warnings()[i]; 149 } 150 if (compflags.werror && new_env->warnings().size() > 0) { 151 throw Error("errors encountered"); 152 } 153 new_env->clearWarnings(); 154 155 if (!compflags.newfzn) { 156 if (compflags.verbose) log << "Converting to old FlatZinc ..."; 157 oldflatzinc(*new_env); 158 if (compflags.verbose) log << " done (" << lasttime.stoptime() << ")" << std::endl; 159 } else { 160 new_env->flat()->compact(); 161 new_env->output()->compact(); 162 } 163 164 if (compflags.verbose) log << " done (" << lasttime.stoptime() << ")" << std::endl; 165 166 return new_env; 167} 168 169CompilePass::~CompilePass(){}; 170 171} // namespace MiniZinc