1 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2
3 /*
4 * Main authors:
5 * Guido Tack <guido.tack@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 namespace MiniZinc {
13
equal(const Expression * e0,const Expression * e1)14 inline bool Expression::equal(const Expression* e0, const Expression* e1) {
15 if (e0 == e1) {
16 return true;
17 }
18 if (e0 == nullptr || e1 == nullptr) {
19 return false;
20 }
21 if (e0->isUnboxedInt() || e1->isUnboxedInt()) {
22 return false;
23 }
24 if (e0->isUnboxedFloatVal() || e1->isUnboxedFloatVal()) {
25 if (e0->isUnboxedFloatVal() && e1->isUnboxedFloatVal()) {
26 return e0->unboxedFloatToFloatVal() == e1->unboxedFloatToFloatVal();
27 }
28 return false;
29 }
30 if (static_cast<ExpressionId>(e0->_id) != static_cast<ExpressionId>(e1->_id)) {
31 return false;
32 }
33 if (e0->type() != e1->type()) {
34 return false;
35 }
36 if (e0->hash() != e1->hash()) {
37 return false;
38 }
39 return equalInternal(e0, e1);
40 }
41
type(const Type & t)42 inline void Expression::type(const Type& t) {
43 if (isUnboxedVal()) {
44 assert(!isUnboxedInt() || t == Type::parint());
45 assert(!isUnboxedFloatVal() || t == Type::parfloat());
46 return;
47 }
48 if (eid() == E_VARDECL) {
49 this->cast<VarDecl>()->id()->_type = t;
50 } else if (eid() == E_ID && (this->cast<Id>()->decl() != nullptr)) {
51 assert(_type.bt() == Type::BT_UNKNOWN || _type.dim() == t.dim() || t.dim() != -1);
52 this->cast<Id>()->decl()->_type = t;
53 }
54 _type = t;
55 }
56
IntLit(const Location & loc,IntVal v)57 inline IntLit::IntLit(const Location& loc, IntVal v)
58 : Expression(loc, E_INTLIT, Type::parint()), _v(v) {
59 rehash();
60 }
61
a(MiniZinc::IntVal v)62 inline IntLit* IntLit::a(MiniZinc::IntVal v) {
63 if (v.isFinite()) {
64 IntLit* ret = intToUnboxedInt(v.toInt());
65 if (ret != nullptr) {
66 return ret;
67 }
68 }
69
70 auto it = constants().integerMap.find(v);
71 if (it == constants().integerMap.end() || it->second() == nullptr) {
72 auto* il = new IntLit(Location().introduce(), v);
73 if (it == constants().integerMap.end()) {
74 constants().integerMap.insert(std::make_pair(v, il));
75 } else {
76 it->second = il;
77 }
78 return il;
79 }
80 return it->second()->cast<IntLit>();
81 }
82
aEnum(IntVal v,unsigned int enumId)83 inline IntLit* IntLit::aEnum(IntVal v, unsigned int enumId) {
84 if (enumId == 0) {
85 return a(v);
86 }
87 auto* il = new IntLit(Location().introduce(), v);
88 Type tt(il->type());
89 tt.enumId(enumId);
90 il->type(tt);
91 return il;
92 }
93
filename() const94 inline ASTString Location::LocVec::filename() const {
95 return static_cast<ASTStringData*>(_data[0]);
96 }
firstLine() const97 inline unsigned int Location::LocVec::firstLine() const {
98 if (_size == 2) {
99 static const unsigned int pointerBits = sizeof(void*) * 8;
100 auto* il = static_cast<IntLit*>(_data[1]);
101 long long unsigned int mask = pointerBits <= 32 ? 0xFF : 0xFFFFF;
102 union {
103 long long int i;
104 unsigned long long int u;
105 } ui;
106 ui.i = il->v().toInt();
107 return static_cast<unsigned int>(ui.u & mask);
108 }
109 auto* il = static_cast<IntLit*>(_data[1]);
110 return il->v().toInt();
111 }
lastLine() const112 inline unsigned int Location::LocVec::lastLine() const {
113 if (_size == 2) {
114 static const unsigned int pointerBits = sizeof(void*) * 8;
115 auto* il = static_cast<IntLit*>(_data[1]);
116 long long unsigned int first_line_size = pointerBits <= 32 ? 8 : 20;
117 long long unsigned int mask = pointerBits <= 32 ? 0xFF : 0xFFFFF;
118 long long unsigned int offsetmask = pointerBits <= 32 ? 0x7F : 0xFFFFF;
119 union {
120 long long int i;
121 unsigned long long int u;
122 } ui;
123 ui.i = il->v().toInt();
124 // return first line (8 bit) + offset (7 bit)
125 return static_cast<unsigned int>((ui.u & mask) + ((ui.u >> first_line_size) & offsetmask));
126 }
127 auto* il = static_cast<IntLit*>(_data[2]);
128 return il->v().toInt();
129 }
firstColumn() const130 inline unsigned int Location::LocVec::firstColumn() const {
131 if (_size == 2) {
132 static const unsigned int pointerBits = sizeof(void*) * 8;
133 auto* il = static_cast<IntLit*>(_data[1]);
134 long long unsigned int first_col_offset = pointerBits <= 32 ? 8 + 7 : 20 + 20;
135 long long unsigned int mask = pointerBits <= 32 ? 0x3F : 0x3FF;
136 union {
137 long long int i;
138 unsigned long long int u;
139 } ui;
140 ui.i = il->v().toInt();
141 // return first line (8 bit) + offset (7 bit)
142 return static_cast<unsigned int>((ui.u >> first_col_offset) & mask);
143 }
144 auto* il = static_cast<IntLit*>(_data[3]);
145 return il->v().toInt();
146 }
lastColumn() const147 inline unsigned int Location::LocVec::lastColumn() const {
148 if (_size == 2) {
149 static const unsigned int pointerBits = sizeof(void*) * 8;
150 auto* il = static_cast<IntLit*>(_data[1]);
151 long long unsigned int last_col_offset = pointerBits <= 32 ? 8 + 7 + 6 : 20 + 20 + 10;
152 long long unsigned int mask = pointerBits <= 32 ? 0x7F : 0x3FF;
153 union {
154 long long int i;
155 unsigned long long int u;
156 } ui;
157 ui.i = il->v().toInt();
158 // return first line (8 bit) + offset (7 bit)
159 return static_cast<unsigned int>((ui.u >> last_col_offset) & mask);
160 }
161 auto* il = static_cast<IntLit*>(_data[4]);
162 return il->v().toInt();
163 }
164
FloatLit(const Location & loc,FloatVal v)165 inline FloatLit::FloatLit(const Location& loc, FloatVal v)
166 : Expression(loc, E_FLOATLIT, Type::parfloat()), _v(v) {
167 rehash();
168 }
169
a(MiniZinc::FloatVal v)170 inline FloatLit* FloatLit::a(MiniZinc::FloatVal v) {
171 if (sizeof(double) <= sizeof(void*) && v.isFinite()) {
172 FloatLit* ret = Expression::doubleToUnboxedFloatVal(v.toDouble());
173 if (ret != nullptr) {
174 return ret;
175 }
176 }
177
178 auto it = constants().floatMap.find(v);
179 if (it == constants().floatMap.end() || it->second() == nullptr) {
180 auto* fl = new FloatLit(Location().introduce(), v);
181 if (it == constants().floatMap.end()) {
182 constants().floatMap.insert(std::make_pair(v, fl));
183 } else {
184 it->second = fl;
185 }
186 return fl;
187 }
188 return it->second()->cast<FloatLit>();
189 }
190
SetLit(const Location & loc,const std::vector<Expression * > & v)191 inline SetLit::SetLit(const Location& loc, const std::vector<Expression*>& v)
192 : Expression(loc, E_SETLIT, Type()), _v(ASTExprVec<Expression>(v)) {
193 _u.isv = nullptr;
194 rehash();
195 }
196
SetLit(const Location & loc,const ASTExprVec<Expression> & v)197 inline SetLit::SetLit(const Location& loc, const ASTExprVec<Expression>& v)
198 : Expression(loc, E_SETLIT, Type()), _v(v) {
199 _u.isv = nullptr;
200 rehash();
201 }
202
SetLit(const Location & loc,IntSetVal * isv)203 inline SetLit::SetLit(const Location& loc, IntSetVal* isv) : Expression(loc, E_SETLIT, Type()) {
204 _type = Type::parsetint();
205 _u.isv = isv;
206 rehash();
207 }
208
SetLit(const Location & loc,FloatSetVal * fsv)209 inline SetLit::SetLit(const Location& loc, FloatSetVal* fsv) : Expression(loc, E_SETLIT, Type()) {
210 _type = Type::parsetfloat();
211 _u.fsv = fsv;
212 rehash();
213 }
214
BoolLit(const Location & loc,bool v)215 inline BoolLit::BoolLit(const Location& loc, bool v)
216 : Expression(loc, E_BOOLLIT, Type::parbool()), _v(v) {
217 rehash();
218 }
219
StringLit(const Location & loc,const std::string & v)220 inline StringLit::StringLit(const Location& loc, const std::string& v)
221 : Expression(loc, E_STRINGLIT, Type::parstring()), _v(ASTString(v)) {
222 rehash();
223 }
224
StringLit(const Location & loc,const ASTString & v)225 inline StringLit::StringLit(const Location& loc, const ASTString& v)
226 : Expression(loc, E_STRINGLIT, Type::parstring()), _v(v) {
227 rehash();
228 }
229
Id(const Location & loc,const std::string & v0,VarDecl * decl)230 inline Id::Id(const Location& loc, const std::string& v0, VarDecl* decl)
231 : Expression(loc, E_ID, Type()), _decl(decl) {
232 v(v0);
233 rehash();
234 }
235
Id(const Location & loc,const ASTString & v0,VarDecl * decl)236 inline Id::Id(const Location& loc, const ASTString& v0, VarDecl* decl)
237 : Expression(loc, E_ID, Type()), _decl(decl) {
238 v(v0);
239 rehash();
240 }
241
Id(const Location & loc,long long int idn0,VarDecl * decl)242 inline Id::Id(const Location& loc, long long int idn0, VarDecl* decl)
243 : Expression(loc, E_ID, Type()), _decl(decl) {
244 idn(idn0);
245 rehash();
246 }
247
decl(VarDecl * d)248 inline void Id::decl(VarDecl* d) { _decl = d; }
249
v() const250 inline ASTString Id::v() const {
251 if ((_decl != nullptr) && _decl->isa<Id>()) {
252 Expression* d = _decl;
253 while ((d != nullptr) && d->isa<Id>()) {
254 d = d->cast<Id>()->_decl;
255 }
256 return d->cast<VarDecl>()->id()->v();
257 }
258 assert(hasStr());
259 return _vOrIdn.val;
260 }
261
idn() const262 inline long long int Id::idn() const {
263 if ((_decl != nullptr) && _decl->isa<Id>()) {
264 Expression* d = _decl;
265 while ((d != nullptr) && d->isa<Id>()) {
266 d = d->cast<Id>()->_decl;
267 }
268 return d->cast<VarDecl>()->id()->idn();
269 }
270 if (hasStr()) {
271 return -1;
272 }
273 long long int i = reinterpret_cast<ptrdiff_t>(_vOrIdn.idn) & ~static_cast<ptrdiff_t>(1);
274 return i >> 1;
275 }
276
TIId(const Location & loc,const std::string & v)277 inline TIId::TIId(const Location& loc, const std::string& v)
278 : Expression(loc, E_TIID, Type()), _v(ASTString(v)) {
279 rehash();
280 }
281
TIId(const Location & loc,const ASTString & v)282 inline TIId::TIId(const Location& loc, const ASTString& v)
283 : Expression(loc, E_TIID, Type()), _v(v) {
284 rehash();
285 }
286
AnonVar(const Location & loc)287 inline AnonVar::AnonVar(const Location& loc) : Expression(loc, E_ANON, Type()) { rehash(); }
288
ArrayLit(const Location & loc,ArrayLit & v,const std::vector<std::pair<int,int>> & dims)289 inline ArrayLit::ArrayLit(const Location& loc, ArrayLit& v,
290 const std::vector<std::pair<int, int> >& dims)
291 : Expression(loc, E_ARRAYLIT, Type()) {
292 _flag1 = false;
293 _flag2 = v._flag2;
294 if (_flag2) {
295 _u.al = v._u.al;
296 std::vector<int> d(dims.size() * 2 + v._dims.size() - v.dims() * 2);
297 for (auto i = static_cast<unsigned int>(dims.size()); (i--) != 0U;) {
298 d[i * 2] = dims[i].first;
299 d[i * 2 + 1] = dims[i].second;
300 }
301 int sliceOffset = static_cast<int>(dims.size()) * 2;
302 unsigned int origSliceOffset = v.dims() * 2;
303 for (int i = 0; i < _u.al->dims() * 2; i++) {
304 d[sliceOffset + i] = v._dims[origSliceOffset + i];
305 }
306 _dims = ASTIntVec(d);
307 } else {
308 std::vector<int> d(dims.size() * 2);
309 for (auto i = static_cast<unsigned int>(dims.size()); (i--) != 0U;) {
310 d[i * 2] = dims[i].first;
311 d[i * 2 + 1] = dims[i].second;
312 }
313 if (v._u.v->flag() || d.size() != 2 || d[0] != 1) {
314 // only allocate dims vector if it is not a 1d array indexed from 1
315 _dims = ASTIntVec(d);
316 }
317 _u.v = v._u.v;
318 }
319 rehash();
320 }
321
ArrayLit(const Location & loc,ArrayLit & v)322 inline ArrayLit::ArrayLit(const Location& loc, ArrayLit& v) : Expression(loc, E_ARRAYLIT, Type()) {
323 _flag1 = false;
324 _flag2 = v._flag2;
325 if (_flag2) {
326 _u.al = v._u.al;
327 std::vector<int> d(2 + v._dims.size() - v.dims() * 2);
328 d[0] = 1;
329 d[1] = v.size();
330 int sliceOffset = 2;
331 unsigned int origSliceOffset = v.dims() * 2;
332 for (int i = 0; i < _u.al->dims() * 2; i++) {
333 d[sliceOffset + i] = v._dims[origSliceOffset + i];
334 }
335 _dims = ASTIntVec(d);
336 } else {
337 _u.v = v._u.v;
338 if (_u.v->flag()) {
339 std::vector<int> d(2);
340 d[0] = 1;
341 d[1] = v.length();
342 _dims = ASTIntVec(d);
343 } else {
344 // don't allocate dims vector since this is a 1d array indexed from 1
345 }
346 }
347 rehash();
348 }
349
ArrayLit(const Location & loc,const std::vector<Expression * > & v)350 inline ArrayLit::ArrayLit(const Location& loc, const std::vector<Expression*>& v)
351 : Expression(loc, E_ARRAYLIT, Type()) {
352 _flag1 = false;
353 _flag2 = false;
354 std::vector<int> d(2);
355 d[0] = 1;
356 d[1] = static_cast<int>(v.size());
357 compress(v, d);
358 rehash();
359 }
360
ArrayLit(const Location & loc,const std::vector<KeepAlive> & v)361 inline ArrayLit::ArrayLit(const Location& loc, const std::vector<KeepAlive>& v)
362 : Expression(loc, E_ARRAYLIT, Type()) {
363 _flag1 = false;
364 _flag2 = false;
365 std::vector<int> d(2);
366 d[0] = 1;
367 d[1] = static_cast<int>(v.size());
368 std::vector<Expression*> vv(v.size());
369 for (unsigned int i = 0; i < v.size(); i++) {
370 vv[i] = v[i]();
371 }
372 compress(vv, d);
373 rehash();
374 }
375
ArrayLit(const Location & loc,const std::vector<std::vector<Expression * >> & v)376 inline ArrayLit::ArrayLit(const Location& loc, const std::vector<std::vector<Expression*> >& v)
377 : Expression(loc, E_ARRAYLIT, Type()) {
378 _flag1 = false;
379 _flag2 = false;
380 std::vector<int> dims(4);
381 dims[0] = 1;
382 dims[1] = static_cast<int>(v.size());
383 dims[2] = 1;
384 dims[3] = !v.empty() ? static_cast<int>(v[0].size()) : 0;
385 std::vector<Expression*> vv;
386 for (const auto& i : v) {
387 for (auto* j : i) {
388 vv.push_back(j);
389 }
390 }
391 compress(vv, dims);
392 rehash();
393 }
394
ArrayAccess(const Location & loc,Expression * v,const std::vector<Expression * > & idx)395 inline ArrayAccess::ArrayAccess(const Location& loc, Expression* v,
396 const std::vector<Expression*>& idx)
397 : Expression(loc, E_ARRAYACCESS, Type()) {
398 _v = v;
399 _idx = ASTExprVec<Expression>(idx);
400 rehash();
401 }
402
ArrayAccess(const Location & loc,Expression * v,const ASTExprVec<Expression> & idx)403 inline ArrayAccess::ArrayAccess(const Location& loc, Expression* v,
404 const ASTExprVec<Expression>& idx)
405 : Expression(loc, E_ARRAYACCESS, Type()) {
406 _v = v;
407 _idx = idx;
408 rehash();
409 }
410
init(Expression * e,Generators & g)411 inline void Comprehension::init(Expression* e, Generators& g) {
412 _e = e;
413 std::vector<Expression*> es;
414 std::vector<int> idx;
415 for (auto& i : g.g) {
416 idx.push_back(static_cast<int>(es.size()));
417 es.push_back(i._in);
418 es.push_back(i._where);
419 for (auto& j : i._v) {
420 es.push_back(j);
421 }
422 }
423 idx.push_back(static_cast<int>(es.size()));
424 _g = ASTExprVec<Expression>(es);
425 _gIndex = ASTIntVec(idx);
426 rehash();
427 }
Comprehension(const Location & loc,Expression * e,Generators & g,bool set)428 inline Comprehension::Comprehension(const Location& loc, Expression* e, Generators& g, bool set)
429 : Expression(loc, E_COMP, Type()) {
430 _flag1 = set;
431 init(e, g);
432 }
init(const std::vector<Expression * > & e_if_then,Expression * e_else)433 inline void ITE::init(const std::vector<Expression*>& e_if_then, Expression* e_else) {
434 _eIfThen = ASTExprVec<Expression>(e_if_then);
435 _eElse = e_else;
436 rehash();
437 }
ITE(const Location & loc,const std::vector<Expression * > & e_if_then,Expression * e_else)438 inline ITE::ITE(const Location& loc, const std::vector<Expression*>& e_if_then, Expression* e_else)
439 : Expression(loc, E_ITE, Type()) {
440 init(e_if_then, e_else);
441 }
442
BinOp(const Location & loc,Expression * e0,BinOpType op,Expression * e1)443 inline BinOp::BinOp(const Location& loc, Expression* e0, BinOpType op, Expression* e1)
444 : Expression(loc, E_BINOP, Type()), _e0(e0), _e1(e1), _decl(nullptr) {
445 _secondaryId = op;
446 rehash();
447 }
448
UnOp(const Location & loc,UnOpType op,Expression * e)449 inline UnOp::UnOp(const Location& loc, UnOpType op, Expression* e)
450 : Expression(loc, E_UNOP, Type()), _e0(e), _decl(nullptr) {
451 _secondaryId = op;
452 rehash();
453 }
454
hasId() const455 inline bool Call::hasId() const {
456 return (reinterpret_cast<ptrdiff_t>(_uId.decl) & static_cast<ptrdiff_t>(1)) == 0;
457 }
458
id() const459 inline ASTString Call::id() const { return hasId() ? _uId.id : decl()->id(); }
460
id(const ASTString & i)461 inline void Call::id(const ASTString& i) {
462 _uId.id = i;
463 assert(hasId());
464 assert(decl() == nullptr);
465 }
466
decl() const467 inline FunctionI* Call::decl() const {
468 return hasId() ? nullptr
469 : reinterpret_cast<FunctionI*>(reinterpret_cast<ptrdiff_t>(_uId.decl) &
470 ~static_cast<ptrdiff_t>(1));
471 }
472
decl(FunctionI * f)473 inline void Call::decl(FunctionI* f) {
474 assert(f != nullptr);
475 _uId.decl =
476 reinterpret_cast<FunctionI*>(reinterpret_cast<ptrdiff_t>(f) | static_cast<ptrdiff_t>(1));
477 }
478
Call(const Location & loc,const std::string & id0,const std::vector<Expression * > & args)479 inline Call::Call(const Location& loc, const std::string& id0, const std::vector<Expression*>& args)
480 : Expression(loc, E_CALL, Type()) {
481 _flag1 = false;
482 id(ASTString(id0));
483 if (args.size() == 1) {
484 _u.oneArg = args[0]->isUnboxedVal() ? args[0] : args[0]->tag();
485 } else {
486 _u.args = ASTExprVec<Expression>(args).vec();
487 }
488 rehash();
489 assert(hasId());
490 assert(decl() == nullptr);
491 }
492
Call(const Location & loc,const ASTString & id0,const std::vector<Expression * > & args)493 inline Call::Call(const Location& loc, const ASTString& id0, const std::vector<Expression*>& args)
494 : Expression(loc, E_CALL, Type()) {
495 _flag1 = false;
496 id(ASTString(id0));
497 if (args.size() == 1) {
498 _u.oneArg = args[0]->isUnboxedVal() ? args[0] : args[0]->tag();
499 } else {
500 _u.args = ASTExprVec<Expression>(args).vec();
501 }
502 rehash();
503 assert(hasId());
504 assert(decl() == nullptr);
505 }
506
VarDecl(const Location & loc,TypeInst * ti,const ASTString & id,Expression * e)507 inline VarDecl::VarDecl(const Location& loc, TypeInst* ti, const ASTString& id, Expression* e)
508 : Expression(loc, E_VARDECL, ti != nullptr ? ti->type() : Type()),
509 _id(nullptr),
510 _flat(nullptr) {
511 _id = new Id(loc, id, this);
512 _flag1 = true;
513 _flag2 = false;
514 _ti = ti;
515 _e = e;
516 _id->type(type());
517 _payload = 0;
518 rehash();
519 }
520
VarDecl(const Location & loc,TypeInst * ti,long long int idn,Expression * e)521 inline VarDecl::VarDecl(const Location& loc, TypeInst* ti, long long int idn, Expression* e)
522 : Expression(loc, E_VARDECL, ti != nullptr ? ti->type() : Type()),
523 _id(nullptr),
524 _flat(nullptr) {
525 _id = new Id(loc, idn, this);
526 _flag1 = true;
527 _flag2 = false;
528 _ti = ti;
529 _e = e;
530 _id->type(type());
531 _payload = 0;
532 rehash();
533 }
534
VarDecl(const Location & loc,TypeInst * ti,const std::string & id,Expression * e)535 inline VarDecl::VarDecl(const Location& loc, TypeInst* ti, const std::string& id, Expression* e)
536 : Expression(loc, E_VARDECL, ti->type()), _id(nullptr), _flat(nullptr) {
537 _id = new Id(loc, ASTString(id), this);
538 _flag1 = true;
539 _flag2 = false;
540 _ti = ti;
541 _e = e;
542 _id->type(type());
543 _payload = 0;
544 rehash();
545 }
546
VarDecl(const Location & loc,TypeInst * ti,Id * id,Expression * e)547 inline VarDecl::VarDecl(const Location& loc, TypeInst* ti, Id* id, Expression* e)
548 : Expression(loc, E_VARDECL, ti->type()), _id(nullptr), _flat(nullptr) {
549 if (id->idn() == -1) {
550 _id = new Id(id->loc(), id->v(), this);
551 } else {
552 _id = new Id(id->loc(), id->idn(), this);
553 }
554 _flag1 = true;
555 _flag2 = false;
556 _ti = ti;
557 _e = e;
558 _id->type(type());
559 _payload = 0;
560 rehash();
561 }
562
e() const563 inline Expression* VarDecl::e() const {
564 return (_e == nullptr || _e->isUnboxedVal()) ? _e : _e->untag();
565 }
566
e(Expression * rhs)567 inline void VarDecl::e(Expression* rhs) {
568 assert(rhs == nullptr || !rhs->isa<Id>() || rhs->cast<Id>() != _id);
569 _e = rhs;
570 }
571
toplevel() const572 inline bool VarDecl::toplevel() const { return _flag1; }
toplevel(bool t)573 inline void VarDecl::toplevel(bool t) { _flag1 = t; }
introduced() const574 inline bool VarDecl::introduced() const { return _flag2; }
introduced(bool t)575 inline void VarDecl::introduced(bool t) { _flag2 = t; }
evaluated() const576 inline bool VarDecl::evaluated() const { return _e->isUnboxedVal() || _e->isTagged(); }
evaluated(bool t)577 inline void VarDecl::evaluated(bool t) {
578 if (!_e->isUnboxedVal()) {
579 if (t) {
580 _e = _e->tag();
581 } else {
582 _e = _e->untag();
583 }
584 }
585 }
flat(VarDecl * vd)586 inline void VarDecl::flat(VarDecl* vd) { _flat = WeakRef(vd); }
587
TypeInst(const Location & loc,const Type & type,const ASTExprVec<TypeInst> & ranges,Expression * domain)588 inline TypeInst::TypeInst(const Location& loc, const Type& type, const ASTExprVec<TypeInst>& ranges,
589 Expression* domain)
590 : Expression(loc, E_TI, type), _ranges(ranges), _domain(domain) {
591 _flag1 = false;
592 _flag2 = false;
593 rehash();
594 }
595
TypeInst(const Location & loc,const Type & type,Expression * domain)596 inline TypeInst::TypeInst(const Location& loc, const Type& type, Expression* domain)
597 : Expression(loc, E_TI, type), _domain(domain) {
598 _flag1 = false;
599 _flag2 = false;
600 rehash();
601 }
602
IncludeI(const Location & loc,const ASTString & f)603 inline IncludeI::IncludeI(const Location& loc, const ASTString& f)
604 : Item(loc, II_INC), _f(f), _m(nullptr) {}
605
VarDeclI(const Location & loc,VarDecl * e)606 inline VarDeclI::VarDeclI(const Location& loc, VarDecl* e) : Item(loc, II_VD), _e(e) {}
607
AssignI(const Location & loc,const std::string & id,Expression * e)608 inline AssignI::AssignI(const Location& loc, const std::string& id, Expression* e)
609 : Item(loc, II_ASN), _id(ASTString(id)), _e(e), _decl(nullptr) {}
610
AssignI(const Location & loc,const ASTString & id,Expression * e)611 inline AssignI::AssignI(const Location& loc, const ASTString& id, Expression* e)
612 : Item(loc, II_ASN), _id(id), _e(e), _decl(nullptr) {}
613
ConstraintI(const Location & loc,Expression * e)614 inline ConstraintI::ConstraintI(const Location& loc, Expression* e) : Item(loc, II_CON), _e(e) {}
615
SolveI(const Location & loc,Expression * e)616 inline SolveI::SolveI(const Location& loc, Expression* e) : Item(loc, II_SOL), _e(e) {}
sat(const Location & loc)617 inline SolveI* SolveI::sat(const Location& loc) {
618 auto* si = new SolveI(loc, nullptr);
619 si->_secondaryId = ST_SAT;
620 return si;
621 }
min(const Location & loc,Expression * e)622 inline SolveI* SolveI::min(const Location& loc, Expression* e) {
623 auto* si = new SolveI(loc, e);
624 si->_secondaryId = ST_MIN;
625 return si;
626 }
max(const Location & loc,Expression * e)627 inline SolveI* SolveI::max(const Location& loc, Expression* e) {
628 auto* si = new SolveI(loc, e);
629 si->_secondaryId = ST_MAX;
630 return si;
631 }
st() const632 inline SolveI::SolveType SolveI::st() const { return static_cast<SolveType>(_secondaryId); }
st(SolveI::SolveType s)633 inline void SolveI::st(SolveI::SolveType s) { _secondaryId = s; }
634
OutputI(const Location & loc,Expression * e)635 inline OutputI::OutputI(const Location& loc, Expression* e) : Item(loc, II_OUT), _e(e) {}
636
FunctionI(const Location & loc,const std::string & id,TypeInst * ti,const std::vector<VarDecl * > & params,Expression * e,bool from_stdlib)637 inline FunctionI::FunctionI(const Location& loc, const std::string& id, TypeInst* ti,
638 const std::vector<VarDecl*>& params, Expression* e, bool from_stdlib)
639 : Item(loc, II_FUN),
640 _id(ASTString(id)),
641 _ti(ti),
642 _params(ASTExprVec<VarDecl>(params)),
643 _e(e),
644 _fromStdLib(from_stdlib) {
645 builtins.e = nullptr;
646 builtins.b = nullptr;
647 builtins.f = nullptr;
648 builtins.i = nullptr;
649 builtins.s = nullptr;
650 builtins.str = nullptr;
651 }
652
FunctionI(const Location & loc,const ASTString & id,TypeInst * ti,const ASTExprVec<VarDecl> & params,Expression * e,bool from_stdlib)653 inline FunctionI::FunctionI(const Location& loc, const ASTString& id, TypeInst* ti,
654 const ASTExprVec<VarDecl>& params, Expression* e, bool from_stdlib)
655 : Item(loc, II_FUN), _id(id), _ti(ti), _params(params), _e(e), _fromStdLib(from_stdlib) {
656 builtins.e = nullptr;
657 builtins.b = nullptr;
658 builtins.f = nullptr;
659 builtins.i = nullptr;
660 builtins.s = nullptr;
661 builtins.str = nullptr;
662 }
663
664 } // namespace MiniZinc
665