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