File: flatten_fieldaccess.cpp

package info (click to toggle)
minizinc 2.9.3%2Bdfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 17,620 kB
  • sloc: cpp: 74,682; ansic: 8,541; python: 3,322; sh: 79; makefile: 13
file content (39 lines) | stat: -rw-r--r-- 1,255 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */

/*
 *  Main authors:
 *     Jip J. Dekker <jip.dekker@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/. */

#include <minizinc/flat_exp.hh>

namespace MiniZinc {

EE flatten_fieldaccess(EnvI& env, const Ctx& ctx, Expression* e, VarDecl* r, VarDecl* b) {
  auto* fa = Expression::cast<FieldAccess>(e);
  assert(Expression::type(fa->v()).istuple() || Expression::type(fa->v()).isrecord());

  // Resolve tuple
  Ctx nctx = ctx;
  nctx.b = +nctx.b;
  nctx.neg = false;
  EE ret = flat_exp(env, nctx, fa->v(), nullptr, b);
  auto* al = Expression::cast<ArrayLit>(eval_array_lit(env, ret.r()));

  // Resolve field
  IntVal i = IntLit::v(Expression::cast<IntLit>(fa->field()));
  if (i < 1 || i > al->size()) {
    // This should not happen, type checking should ensure all fields are valid.
    throw EvalError(env, Expression::loc(fa), "Internal error: accessing invalid field");
  }

  // Bind result
  ret.r = bind(env, ctx, r, (*al)[static_cast<unsigned int>(i.toInt()) - 1]);
  return ret;
}

}  // namespace MiniZinc