Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
20 kB · 643 lines
C++
at develop
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/* * Main authors: * Guido Tack <guido.tack@monash.edu> */
/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
namespace MiniZinc {
inline bool Expression::equal(const Expression* e0, const Expression* e1) { if (e0 == e1) return true; if (e0 == NULL || e1 == NULL) return false; if (e0->isUnboxedInt() || e1->isUnboxedInt()) return false; if (e0->isUnboxedFloatVal() || e1->isUnboxedFloatVal()) { if (e0->isUnboxedFloatVal() && e1->isUnboxedFloatVal()) { return e0->unboxedFloatToFloatVal() == e1->unboxedFloatToFloatVal(); } return false; } if (e0->_id != e1->_id) return false; if (e0->type() != e1->type()) return false; if (e0->hash() != e1->hash()) return false; return equal_internal(e0, e1);}
inline void Expression::type(const Type& t) { if (isUnboxedVal()) { assert(!isUnboxedInt() || t == Type::parint()); assert(!isUnboxedFloatVal() || t == Type::parfloat()); return; } if (eid() == E_VARDECL) { this->cast<VarDecl>()->id()->_type = t; } else if (eid() == E_ID && this->cast<Id>()->decl()) { assert(_type.bt() == Type::BT_UNKNOWN || _type.dim() == t.dim() || t.dim() != -1); this->cast<Id>()->decl()->_type = t; } _type = t;}
inline IntLit::IntLit(const Location& loc, IntVal v) : Expression(loc, E_INTLIT, Type::parint()), _v(v) { rehash();}
inline IntLit* IntLit::a(MiniZinc::IntVal v) { if (v.isFinite()) { IntLit* ret = intToUnboxedInt(v.toInt()); if (ret) { return ret; } }
std::unordered_map<IntVal, WeakRef>::iterator it = constants().integerMap.find(v); if (it == constants().integerMap.end() || it->second() == NULL) { IntLit* il = new IntLit(Location().introduce(), v); if (it == constants().integerMap.end()) { constants().integerMap.insert(std::make_pair(v, il)); } else { it->second = il; } return il; } else { return it->second()->cast<IntLit>(); }}
inline IntLit* IntLit::aEnum(IntVal v, unsigned int enumId) { if (enumId == 0) return a(v); IntLit* il = new IntLit(Location().introduce(), v); Type tt(il->type()); tt.enumId(enumId); il->type(tt); return il;}
inline ASTString Location::LocVec::filename(void) const { return static_cast<ASTStringO*>(_data[0]);}inline unsigned int Location::LocVec::first_line(void) const { if (_size == 2) { static const unsigned int pointerBits = sizeof(IntLit*) * 8; IntLit* il = static_cast<IntLit*>(_data[1]); long long unsigned int mask = pointerBits <= 32 ? 0xFF : 0xFFFFF; union { long long int i; unsigned long long int u; } ui; ui.i = il->v().toInt(); return static_cast<unsigned int>(ui.u & mask); } else { IntLit* il = static_cast<IntLit*>(_data[1]); return il->v().toInt(); }}inline unsigned int Location::LocVec::last_line(void) const { if (_size == 2) { static const unsigned int pointerBits = sizeof(IntLit*) * 8; IntLit* il = static_cast<IntLit*>(_data[1]); long long unsigned int first_line_size = pointerBits <= 32 ? 8 : 20; long long unsigned int mask = pointerBits <= 32 ? 0xFF : 0xFFFFF; long long unsigned int offsetmask = pointerBits <= 32 ? 0x7F : 0xFFFFF; union { long long int i; unsigned long long int u; } ui; ui.i = il->v().toInt(); // return first line (8 bit) + offset (7 bit) return static_cast<unsigned int>((ui.u & mask) + ((ui.u >> first_line_size) & offsetmask)); } else { IntLit* il = static_cast<IntLit*>(_data[2]); return il->v().toInt(); }}inline unsigned int Location::LocVec::first_column(void) const { if (_size == 2) { static const unsigned int pointerBits = sizeof(IntLit*) * 8; IntLit* il = static_cast<IntLit*>(_data[1]); long long unsigned int first_col_offset = pointerBits <= 32 ? 8 + 7 : 20 + 20; long long unsigned int mask = pointerBits <= 32 ? 0x3F : 0x3FF; union { long long int i; unsigned long long int u; } ui; ui.i = il->v().toInt(); // return first line (8 bit) + offset (7 bit) return static_cast<unsigned int>((ui.u >> first_col_offset) & mask); } else { IntLit* il = static_cast<IntLit*>(_data[3]); return il->v().toInt(); }}inline unsigned int Location::LocVec::last_column(void) const { if (_size == 2) { static const unsigned int pointerBits = sizeof(IntLit*) * 8; IntLit* il = static_cast<IntLit*>(_data[1]); long long unsigned int last_col_offset = pointerBits <= 32 ? 8 + 7 + 6 : 20 + 20 + 10; long long unsigned int mask = pointerBits <= 32 ? 0x7F : 0x3FF; union { long long int i; unsigned long long int u; } ui; ui.i = il->v().toInt(); // return first line (8 bit) + offset (7 bit) return static_cast<unsigned int>((ui.u >> last_col_offset) & mask); } else { IntLit* il = static_cast<IntLit*>(_data[4]); return il->v().toInt(); }}
inline FloatLit::FloatLit(const Location& loc, FloatVal v) : Expression(loc, E_FLOATLIT, Type::parfloat()), _v(v) { rehash();}
inline FloatLit* FloatLit::a(MiniZinc::FloatVal v) { if (sizeof(double) <= sizeof(FloatLit*) && v.isFinite()) { FloatLit* ret = Expression::doubleToUnboxedFloatVal(v.toDouble()); if (ret) { return ret; } }
std::unordered_map<FloatVal, WeakRef>::iterator it = constants().floatMap.find(v); if (it == constants().floatMap.end() || it->second() == NULL) { FloatLit* fl = new FloatLit(Location().introduce(), v); if (it == constants().floatMap.end()) { constants().floatMap.insert(std::make_pair(v, fl)); } else { it->second = fl; } return fl; } else { return it->second()->cast<FloatLit>(); }}
inline SetLit::SetLit(const Location& loc, const std::vector<Expression*>& v) : Expression(loc, E_SETLIT, Type()), _v(ASTExprVec<Expression>(v)) { _u.isv = NULL; rehash();}
inline SetLit::SetLit(const Location& loc, ASTExprVec<Expression> v) : Expression(loc, E_SETLIT, Type()), _v(v) { _u.isv = NULL; rehash();}
inline SetLit::SetLit(const Location& loc, IntSetVal* isv) : Expression(loc, E_SETLIT, Type()) { _type = Type::parsetint(); _u.isv = isv; rehash();}
inline SetLit::SetLit(const Location& loc, FloatSetVal* fsv) : Expression(loc, E_SETLIT, Type()) { _type = Type::parsetfloat(); _u.fsv = fsv; rehash();}
inline BoolLit::BoolLit(const Location& loc, bool v) : Expression(loc, E_BOOLLIT, Type::parbool()), _v(v) { rehash();}
inline StringLit::StringLit(const Location& loc, const std::string& v) : Expression(loc, E_STRINGLIT, Type::parstring()), _v(ASTString(v)) { rehash();}
inline StringLit::StringLit(const Location& loc, const ASTString& v) : Expression(loc, E_STRINGLIT, Type::parstring()), _v(v) { rehash();}
inline Id::Id(const Location& loc, const std::string& v0, VarDecl* decl) : Expression(loc, E_ID, Type()), _decl(decl) { v(v0); rehash();}
inline Id::Id(const Location& loc, const ASTString& v0, VarDecl* decl) : Expression(loc, E_ID, Type()), _decl(decl) { v(v0); rehash();}
inline Id::Id(const Location& loc, long long int idn0, VarDecl* decl) : Expression(loc, E_ID, Type()), _decl(decl) { idn(idn0); rehash();}
inline void Id::decl(VarDecl* d) { _decl = d; }
inline ASTString Id::v(void) const { if (_decl && _decl->isa<Id>()) { Expression* d = _decl; while (d && d->isa<Id>()) { d = d->cast<Id>()->_decl; } return d->cast<VarDecl>()->id()->v(); } else { assert((reinterpret_cast<ptrdiff_t>(_v_or_idn) & static_cast<ptrdiff_t>(1)) == 0); return ASTString(reinterpret_cast<ASTStringO*>(_v_or_idn)); }}
inline long long int Id::idn(void) const { if (_decl && _decl->isa<Id>()) { Expression* d = _decl; while (d && d->isa<Id>()) { d = d->cast<Id>()->_decl; } return d->cast<VarDecl>()->id()->idn(); } else { if ((reinterpret_cast<ptrdiff_t>(_v_or_idn) & static_cast<ptrdiff_t>(1)) == 0) return -1; long long int i = reinterpret_cast<ptrdiff_t>(_v_or_idn) & ~static_cast<ptrdiff_t>(1); return i >> 1; }}
inline TIId::TIId(const Location& loc, const std::string& v) : Expression(loc, E_TIID, Type()), _v(ASTString(v)) { rehash();}
inline AnonVar::AnonVar(const Location& loc) : Expression(loc, E_ANON, Type()) { rehash(); }
inline ArrayLit::ArrayLit(const Location& loc, ArrayLit& v, const std::vector<std::pair<int, int> >& dims) : Expression(loc, E_ARRAYLIT, Type()) { _flag_1 = false; _flag_2 = v._flag_2; if (_flag_2) { _u._al = v._u._al; std::vector<int> d(dims.size() * 2 + v._dims.size() - v.dims() * 2); for (unsigned int i = static_cast<unsigned int>(dims.size()); i--;) { d[i * 2] = dims[i].first; d[i * 2 + 1] = dims[i].second; } int sliceOffset = static_cast<int>(dims.size()) * 2; int origSliceOffset = v.dims() * 2; for (int i = 0; i < _u._al->dims() * 2; i++) { d[sliceOffset + i] = v._dims[origSliceOffset + i]; } _dims = ASTIntVec(d); } else { std::vector<int> d(dims.size() * 2); for (unsigned int i = static_cast<unsigned int>(dims.size()); i--;) { d[i * 2] = dims[i].first; d[i * 2 + 1] = dims[i].second; } if (v._u._v->flag() || d.size() != 2 || d[0] != 1) { // only allocate dims vector if it is not a 1d array indexed from 1 _dims = ASTIntVec(d); } _u._v = v._u._v; } rehash();}
inline ArrayLit::ArrayLit(const Location& loc, ArrayLit& v) : Expression(loc, E_ARRAYLIT, Type()) { _flag_1 = false; _flag_2 = v._flag_2; if (_flag_2) { _u._al = v._u._al; std::vector<int> d(2 + v._dims.size() - v.dims() * 2); d[0] = 1; d[1] = v.size(); int sliceOffset = 2; int origSliceOffset = v.dims() * 2; for (int i = 0; i < _u._al->dims() * 2; i++) { d[sliceOffset + i] = v._dims[origSliceOffset + i]; } _dims = ASTIntVec(d); } else { _u._v = v._u._v; if (_u._v->flag()) { std::vector<int> d(2); d[0] = 1; d[1] = v.length(); _dims = ASTIntVec(d); } else { // don't allocate dims vector since this is a 1d array indexed from 1 } } rehash();}
inline ArrayLit::ArrayLit(const Location& loc, const std::vector<Expression*>& v) : Expression(loc, E_ARRAYLIT, Type()) { _flag_1 = false; _flag_2 = false; std::vector<int> d(2); d[0] = 1; d[1] = static_cast<int>(v.size()); compress(v, d); rehash();}
inline ArrayLit::ArrayLit(const Location& loc, const std::vector<KeepAlive>& v) : Expression(loc, E_ARRAYLIT, Type()) { _flag_1 = false; _flag_2 = false; std::vector<int> d(2); d[0] = 1; d[1] = static_cast<int>(v.size()); std::vector<Expression*> vv(v.size()); for (unsigned int i = 0; i < v.size(); i++) { vv[i] = v[i](); } compress(vv, d); rehash();}
inline ArrayLit::ArrayLit(const Location& loc, const std::vector<std::vector<Expression*> >& v) : Expression(loc, E_ARRAYLIT, Type()) { _flag_1 = false; _flag_2 = false; std::vector<int> dims(4); dims[0] = 1; dims[1] = static_cast<int>(v.size()); dims[2] = 1; dims[3] = v.size() > 0 ? static_cast<int>(v[0].size()) : 0; std::vector<Expression*> vv; for (unsigned int i = 0; i < v.size(); i++) for (unsigned int j = 0; j < v[i].size(); j++) vv.push_back(v[i][j]); compress(vv, dims); rehash();}
inline ArrayAccess::ArrayAccess(const Location& loc, Expression* v, const std::vector<Expression*>& idx) : Expression(loc, E_ARRAYACCESS, Type()) { _v = v; _idx = ASTExprVec<Expression>(idx); rehash();}
inline ArrayAccess::ArrayAccess(const Location& loc, Expression* v, ASTExprVec<Expression> idx) : Expression(loc, E_ARRAYACCESS, Type()) { _v = v; _idx = idx; rehash();}
inline void Comprehension::init(Expression* e, Generators& g) { _e = e; std::vector<Expression*> es; std::vector<int> idx; for (unsigned int i = 0; i < g._g.size(); i++) { idx.push_back(static_cast<int>(es.size())); es.push_back(g._g[i]._in); es.push_back(g._g[i]._where); for (unsigned int j = 0; j < g._g[i]._v.size(); j++) { es.push_back(g._g[i]._v[j]); } } idx.push_back(static_cast<int>(es.size())); _g = ASTExprVec<Expression>(es); _g_idx = ASTIntVec(idx); rehash();}inline Comprehension::Comprehension(const Location& loc, Expression* e, Generators& g, bool set) : Expression(loc, E_COMP, Type()) { _flag_1 = set; init(e, g);}inline void ITE::init(const std::vector<Expression*>& e_if_then, Expression* e_else) { _e_if_then = ASTExprVec<Expression>(e_if_then); _e_else = e_else; rehash();}inline ITE::ITE(const Location& loc, const std::vector<Expression*>& e_if_then, Expression* e_else) : Expression(loc, E_ITE, Type()) { init(e_if_then, e_else);}
inline BinOp::BinOp(const Location& loc, Expression* e0, BinOpType op, Expression* e1) : Expression(loc, E_BINOP, Type()), _e0(e0), _e1(e1), _decl(NULL) { _sec_id = op; rehash();}
inline UnOp::UnOp(const Location& loc, UnOpType op, Expression* e) : Expression(loc, E_UNOP, Type()), _e0(e), _decl(NULL) { _sec_id = op; rehash();}
inline bool Call::hasId(void) const { return (reinterpret_cast<ptrdiff_t>(_u_id._decl) & static_cast<ptrdiff_t>(1)) == 0;}
inline ASTString Call::id(void) const { return hasId() ? _u_id._id : decl()->id(); }
inline void Call::id(const ASTString& i) { _u_id._id = i.aststr(); assert(hasId()); assert(decl() == NULL);}
inline FunctionI* Call::decl(void) const { return hasId() ? NULL : reinterpret_cast<FunctionI*>(reinterpret_cast<ptrdiff_t>(_u_id._decl) & ~static_cast<ptrdiff_t>(1));}
inline void Call::decl(FunctionI* f) { assert(f != NULL); _u_id._decl = reinterpret_cast<FunctionI*>(reinterpret_cast<ptrdiff_t>(f) | static_cast<ptrdiff_t>(1));}
inline Call::Call(const Location& loc, const std::string& id0, const std::vector<Expression*>& args) : Expression(loc, E_CALL, Type()) { id(ASTString(id0)); if (args.size() == 1) { _u._oneArg = args[0]->isUnboxedVal() ? args[0] : args[0]->tag(); } else { _u._args = ASTExprVec<Expression>(args).vec(); } rehash(); assert(hasId()); assert(decl() == NULL);}
inline Call::Call(const Location& loc, const ASTString& id0, const std::vector<Expression*>& args) : Expression(loc, E_CALL, Type()) { id(ASTString(id0)); if (args.size() == 1) { _u._oneArg = args[0]->isUnboxedVal() ? args[0] : args[0]->tag(); } else { _u._args = ASTExprVec<Expression>(args).vec(); } rehash(); assert(hasId()); assert(decl() == NULL);}
inline VarDecl::VarDecl(const Location& loc, TypeInst* ti, const ASTString& id, Expression* e) : Expression(loc, E_VARDECL, ti ? ti->type() : Type()), _id(NULL), _flat(NULL) { _id = new Id(loc, id, this); _flag_1 = true; _flag_2 = false; _ti = ti; _e = e; _id->type(type()); _payload = 0; rehash();}
inline VarDecl::VarDecl(const Location& loc, TypeInst* ti, long long int idn, Expression* e) : Expression(loc, E_VARDECL, ti ? ti->type() : Type()), _id(NULL), _flat(NULL) { _id = new Id(loc, idn, this); _flag_1 = true; _flag_2 = false; _ti = ti; _e = e; _id->type(type()); _payload = 0; rehash();}
inline VarDecl::VarDecl(const Location& loc, TypeInst* ti, const std::string& id, Expression* e) : Expression(loc, E_VARDECL, ti->type()), _id(NULL), _flat(NULL) { _id = new Id(loc, ASTString(id), this); _flag_1 = true; _flag_2 = false; _ti = ti; _e = e; _id->type(type()); _payload = 0; rehash();}
inline VarDecl::VarDecl(const Location& loc, TypeInst* ti, Id* id, Expression* e) : Expression(loc, E_VARDECL, ti->type()), _id(NULL), _flat(NULL) { if (id->idn() == -1) _id = new Id(loc, id->v(), this); else _id = new Id(loc, id->idn(), this); _flag_1 = true; _flag_2 = false; _ti = ti; _e = e; _id->type(type()); _payload = 0; rehash();}
inline Expression* VarDecl::e(void) const { return (_e == nullptr || _e->isUnboxedVal()) ? _e : _e->untag();}
inline void VarDecl::e(Expression* rhs) { assert(rhs == NULL || !rhs->isa<Id>() || rhs->cast<Id>() != _id); _e = rhs;}
inline bool VarDecl::toplevel(void) const { return _flag_1; }inline void VarDecl::toplevel(bool t) { _flag_1 = t; }inline bool VarDecl::introduced(void) const { return _flag_2; }inline void VarDecl::introduced(bool t) { _flag_2 = t; }inline bool VarDecl::evaluated(void) const { return _e->isUnboxedVal() || _e->isTagged(); }inline void VarDecl::evaluated(bool t) { if (!_e->isUnboxedVal()) { if (t) _e = _e->tag(); else _e = _e->untag(); }}inline void VarDecl::flat(VarDecl* vd) { _flat = WeakRef(vd); }
inline TypeInst::TypeInst(const Location& loc, const Type& type, ASTExprVec<TypeInst> ranges, Expression* domain) : Expression(loc, E_TI, type), _ranges(ranges), _domain(domain) { _flag_1 = false; _flag_2 = false; rehash();}
inline TypeInst::TypeInst(const Location& loc, const Type& type, Expression* domain) : Expression(loc, E_TI, type), _domain(domain) { _flag_1 = false; _flag_2 = false; rehash();}
inline IncludeI::IncludeI(const Location& loc, const ASTString& f) : Item(loc, II_INC), _f(f), _m(NULL) {}
inline VarDeclI::VarDeclI(const Location& loc, VarDecl* e) : Item(loc, II_VD), _e(e) {}
inline AssignI::AssignI(const Location& loc, const std::string& id, Expression* e) : Item(loc, II_ASN), _id(ASTString(id)), _e(e), _decl(NULL) {}
inline ConstraintI::ConstraintI(const Location& loc, Expression* e) : Item(loc, II_CON), _e(e) {}
inline SolveI::SolveI(const Location& loc, Expression* e) : Item(loc, II_SOL), _e(e) {}inline SolveI* SolveI::sat(const Location& loc) { SolveI* si = new SolveI(loc, NULL); si->_sec_id = ST_SAT; return si;}inline SolveI* SolveI::min(const Location& loc, Expression* e) { SolveI* si = new SolveI(loc, e); si->_sec_id = ST_MIN; return si;}inline SolveI* SolveI::max(const Location& loc, Expression* e) { SolveI* si = new SolveI(loc, e); si->_sec_id = ST_MAX; return si;}inline SolveI::SolveType SolveI::st(void) const { return static_cast<SolveType>(_sec_id); }inline void SolveI::st(SolveI::SolveType s) { _sec_id = s; }
inline OutputI::OutputI(const Location& loc, Expression* e) : Item(loc, II_OUT), _e(e) {}
inline FunctionI::FunctionI(const Location& loc, const std::string& id, TypeInst* ti, const std::vector<VarDecl*>& params, Expression* e) : Item(loc, II_FUN), _id(ASTString(id)), _ti(ti), _params(ASTExprVec<VarDecl>(params)), _e(e) { _builtins.e = NULL; _builtins.b = NULL; _builtins.f = NULL; _builtins.i = NULL; _builtins.s = NULL; _builtins.str = NULL; _from_stdlib = (loc.filename() == "builtins.mzn" || loc.filename().endsWith("/builtins.mzn") || loc.filename() == "stdlib.mzn" || loc.filename().endsWith("/stdlib.mzn") || loc.filename() == "mzncc_builtins.mzn" || loc.filename().endsWith("/mzncc_builtins.mzn") || loc.filename() == "flatzinc_builtins.mzn" || loc.filename().endsWith("/flatzinc_builtins.mzn"));}
inline FunctionI::FunctionI(const Location& loc, const ASTString& id, TypeInst* ti, const ASTExprVec<VarDecl>& params, Expression* e) : Item(loc, II_FUN), _id(id), _ti(ti), _params(params), _e(e) { _builtins.e = NULL; _builtins.b = NULL; _builtins.f = NULL; _builtins.i = NULL; _builtins.s = NULL; _builtins.str = NULL; _from_stdlib = (loc.filename() == "builtins.mzn" || loc.filename().endsWith("/builtins.mzn") || loc.filename() == "stdlib.mzn" || loc.filename().endsWith("/stdlib.mzn") || loc.filename() == "mzncc_builtins.mzn" || loc.filename().endsWith("/mzncc_builtins.mzn") || loc.filename() == "flatzinc_builtins.mzn" || loc.filename().endsWith("/flatzinc_builtins.mzn"));}
} // namespace MiniZinc