this repo has no description
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#include <minizinc/flat_exp.hh> 13 14namespace MiniZinc { 15 16CallArgItem::CallArgItem(EnvI& env0) : env(env0) { 17 env.idStack.push_back(static_cast<int>(env.callStack.size())); 18} 19CallArgItem::~CallArgItem() { env.idStack.pop_back(); } 20 21Expression* create_dummy_value(EnvI& env, const Type& t) { 22 if (t.dim() > 0) { 23 Expression* ret = new ArrayLit(Location().introduce(), std::vector<Expression*>()); 24 Type ret_t = t; 25 ret_t.ti(Type::TI_PAR); 26 ret->type(ret_t); 27 return ret; 28 } 29 if (t.st() == Type::ST_SET) { 30 Expression* ret = new SetLit(Location().introduce(), std::vector<Expression*>()); 31 Type ret_t = t; 32 ret_t.ti(Type::TI_PAR); 33 ret->type(ret_t); 34 return ret; 35 } 36 switch (t.bt()) { 37 case Type::BT_INT: 38 return IntLit::a(0); 39 case Type::BT_BOOL: 40 return constants().boollit(false); 41 case Type::BT_FLOAT: 42 return FloatLit::a(0); 43 case Type::BT_STRING: 44 return new StringLit(Location().introduce(), ""); 45 case Type::BT_ANN: 46 return constants().ann.promise_total; 47 default: 48 return nullptr; 49 } 50} 51 52EE flatten_error(EnvI& env, const Ctx& ctx, Expression* e, VarDecl* r, VarDecl* b) { 53 throw InternalError("invalid expression encountered during compilation"); 54} 55 56#ifndef NDEBUG 57void mzn_break_here(Expression* e) { std::cerr << "% mzn_break_here: " << *e << "\n"; } 58#endif 59 60typedef EE (*ExprFlattener)(EnvI& env, const Ctx& ctx, Expression* e, VarDecl* r, VarDecl* b); 61 62EE flatten_setlit(EnvI& env, const Ctx& ctx, Expression* e, VarDecl* r, VarDecl* b); 63EE flatten_id(EnvI& env, const Ctx& ctx, Expression* e, VarDecl* r, VarDecl* b); 64EE flatten_anon(EnvI& env, const Ctx& ctx, Expression* e, VarDecl* r, VarDecl* b); 65EE flatten_arraylit(EnvI& env, const Ctx& ctx, Expression* e, VarDecl* r, VarDecl* b); 66EE flatten_arrayaccess(EnvI& env, const Ctx& ctx, Expression* e, VarDecl* r, VarDecl* b); 67EE flatten_comp(EnvI& env, const Ctx& ctx, Expression* e, VarDecl* r, VarDecl* b); 68EE flatten_ite(EnvI& env, const Ctx& ctx, Expression* e, VarDecl* r, VarDecl* b); 69EE flatten_binop(EnvI& env, const Ctx& ctx, Expression* e, VarDecl* r, VarDecl* b); 70EE flatten_unop(EnvI& env, const Ctx& ctx, Expression* e, VarDecl* r, VarDecl* b); 71EE flatten_call(EnvI& env, const Ctx& ctx, Expression* e, VarDecl* r, VarDecl* b); 72EE flatten_vardecl(EnvI& env, const Ctx& ctx, Expression* e, VarDecl* r, VarDecl* b); 73EE flatten_let(EnvI& env, const Ctx& ctx, Expression* e, VarDecl* r, VarDecl* b); 74EE flatten_par(EnvI& env, const Ctx& ctx, Expression* e, VarDecl* r, VarDecl* b); 75 76EE flat_exp(EnvI& env, const Ctx& ctx, Expression* e, VarDecl* r, VarDecl* b) { 77 if (e == nullptr) { 78 return EE(); 79 } 80 81#ifndef NDEBUG 82 Annotation& e_ann = e->ann(); 83 if (e_ann.contains(constants().ann.mzn_break_here)) { 84 mzn_break_here(e); 85 } 86#endif 87 88 assert(!e->type().isunknown()); 89 90 static const ExprFlattener flattener_dispatch[] = { 91 &flatten_par, // par expressions 92 &flatten_error, // E_INTLIT 93 &flatten_error, // E_FLOATLIT 94 &flatten_setlit, // E_SETLIT 95 &flatten_error, // E_BOOLLIT 96 &flatten_error, // E_STRINGLIT 97 &flatten_id, // E_ID 98 &flatten_anon, // E_ANON 99 &flatten_arraylit, // E_ARRAYLIT 100 &flatten_arrayaccess, // E_ARRAYACCESS 101 &flatten_comp, // E_COMP 102 &flatten_ite, // E_ITE 103 &flatten_binop, // E_BINOP 104 &flatten_unop, // E_UNOP 105 &flatten_call, // E_CALL 106 &flatten_vardecl, // E_VARDECL 107 &flatten_let, // E_LET 108 &flatten_error, // E_TI 109 &flatten_error // E_TIID 110 }; 111 112 bool is_par = e->type().isPar() && 113 (!e->type().cv() || !e->type().isbool() || ctx.b != C_ROOT || e->isa<BoolLit>()) && 114 !e->isa<Let>() && !e->isa<VarDecl>() && e->type().bt() != Type::BT_ANN; 115 116#ifdef OUTPUT_CALLTREE 117 if (auto* call = e->dynamicCast<Call>()) { 118 for (int i = 0; i < env.callDepth; ++i) { 119 std::cerr << "──"; 120 } 121 std::cerr << *call << std::endl; 122 env.callDepth++; 123 124 EE ee = flatten_call(env, ctx, e, r, b); 125 126 env.callDepth--; 127 return ee; 128 } 129#endif 130 131 int dispatch = is_par ? 0 : e->eid() - Expression::E_INTLIT + 1; 132 133 return flattener_dispatch[dispatch](env, ctx, e, r, b); 134} 135 136} // namespace MiniZinc