<commit_before>/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */

/*
 *  Main authors:
 *     <NAME> <<EMAIL>>
 */

/* 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/eval_par.hh>
#include <minizinc/exception.hh>
#include <minizinc/iter.hh>
#include <minizinc/hash.hh>
#include <minizinc/copy.hh>
#include <minizinc/astiterator.hh>
#include <minizinc/flatten.hh>

namespace MiniZinc {

  template<class E>
  typename E::Val eval_id(Expression* e) {
    Id* id = e->cast<Id>();
    if (id->decl() == NULL)
      throw EvalError(e->loc(), "undeclared identifier", id->v());
    if (id->decl()->e() == NULL)
      throw EvalError(id->decl()->loc(), "cannot evaluate expression", id->v());
    typename E::Val r = E::e(id->decl()->e());
    if (id->decl()->toplevel() && !id->decl()->evaluated()) {
      id->decl()->e(E::exp(r));
      id->decl()->evaluated(true);
    }
    return r;
  }

  class EvalIntLit {
  public:
    typedef IntLit* Val;
    typedef Expression* ArrayVal;
    static IntLit* e(Expression* e) {
      return new IntLit(Location(),eval_int(e));
    }
    static Expression* exp(IntLit* e) { return e; }
  };
  class EvalIntVal {
  public:
    typedef IntVal Val;
    typedef IntVal ArrayVal;
    static IntVal e(Expression* e) {
      return eval_int(e);
    }
    static Expression* exp(IntVal e) { return new IntLit(Location(),e); }
  };
  class EvalFloatVal {
  public:
    typedef FloatVal Val;
    static FloatVal e(Expression* e) {
      return eval_float(e);
    }
    static Expression* exp(FloatVal e) { return new FloatLit(Location(),e); }
  };
  class EvalFloatLit {
  public:
    typedef FloatLit* Val;
    typedef Expression* ArrayVal;
    static FloatLit* e(Expression* e) {
      return new FloatLit(Location(),eval_float(e));
    }
    static Expression* exp(Expression* e) { return e; }
  };
  class EvalString {
  public:
    typedef std::string Val;
    typedef std::string ArrayVal;
    static std::string e(Expression* e) {
      return eval_string(e);
    }
    static Expression* exp(const std::string& e) { return new StringLit(Location(),e); }
  };
  class EvalStringLit {
  public:
    typedef StringLit* Val;
    typedef Expression* ArrayVal;
    static StringLit* e(Expression* e) {
      return new StringLit(Location(),eval_string(e));
    }
    static Expression* exp(Expression* e) { return e; }
  };
  class EvalBoolLit {
  public:
    typedef BoolLit* Val;
    typedef Expression* ArrayVal;
    static BoolLit* e(Expression* e) {
      return constants().boollit(eval_bool(e));
    }
    static Expression* exp(Expression* e) { return e; }
  };
  class EvalBoolVal {
  public:
    typedef bool Val;
    static bool e(Expression* e) {
      return eval_bool(e);
    }
    static Expression* exp(bool e) { return constants().boollit(e); }
  };
  class EvalArrayLit {
  public:
    typedef ArrayLit* Val;
    typedef Expression* ArrayVal;
    static ArrayLit* e(Expression* e) {
      return eval_array_lit(e);
    }
    static Expression* exp(Expression* e) { return e; }
  };
  class EvalIntSet {
  public:
    typedef IntSetVal* Val;
    static IntSetVal* e(Expression* e) {
      return eval_intset(e);
    }
    static Expression* exp(IntSetVal* e) { return new SetLit(Location(),e); }
  };
  class EvalSetLit {
  public:
    typedef SetLit* Val;
    typedef Expression* ArrayVal;
    static SetLit* e(Expression* e) {
      return new SetLit(e->loc(),eval_intset(e));
    }
    static Expression* exp(Expression* e) { return e; }
  };
  class EvalNone {
  public:
    typedef Expression* Val;
    typedef Expression* ArrayVal;
    static Expression* e(Expression* e) {
      return e;
    }
    static Expression* exp(Expression* e) { return e; }
  };
  class EvalCopy {
  public:
    typedef Expression* Val;
    typedef Expression* ArrayVal;
    static Expression* e(Expression* e) {
      return copy(e,true);
    }
    static Expression* exp(Expression* e) { return e; }
  };

  template<class Eval>
  typename Eval::Val eval_call(Call* ce) {
    std::vector<Expression*> previousParameters(ce->decl()->params().size());
    for (unsigned int i=ce->decl()->params().size(); i--;) {
      VarDecl* vd = ce->decl()->params()[i];
      previousParameters[i] = vd->e();
      vd->flat(vd);
      vd->e(ce->args()[i]);
    }
    typename Eval::Val ret = Eval::e(ce->decl()->e());
    for (unsigned int i=ce->decl()->params().size(); i--;) {
      VarDecl* vd = ce->decl()->params()[i];
      vd->e(previousParameters[i]);
      vd->flat(vd->e() ? vd : NULL);
    }
    return ret;
  }
  
  ArrayLit* eval_array_comp(Comprehension* e) {
    ArrayLit* ret;
    if (e->type() == Type::parint(1)) {
      std::vector<Expression*> a = eval_comp<EvalIntLit>(e);
      ret = new ArrayLit(e->loc(),a);
    } else if (e->type() == Type::parbool(1)) {
      std::vector<Expression*> a = eval_comp<EvalBoolLit>(e);<commit_msg>Need to do call-by-value in eval_call<commit_after>/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */

/*
 *  Main authors:
 *     <NAME> <<EMAIL>>
 */

/* 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/eval_par.hh>
#include <minizinc/exception.hh>
#include <minizinc/iter.hh>
#include <minizinc/hash.hh>
#include <minizinc/copy.hh>
#include <minizinc/astiterator.hh>
#include <minizinc/flatten.hh>

namespace MiniZinc {

  template<class E>
  typename E::Val eval_id(Expression* e) {
    Id* id = e->cast<Id>();
    if (id->decl() == NULL)
      throw EvalError(e->loc(), "undeclared identifier", id->v());
    if (id->decl()->e() == NULL)
      throw EvalError(id->decl()->loc(), "cannot evaluate expression", id->v());
    typename E::Val r = E::e(id->decl()->e());
    if (id->decl()->toplevel() && !id->decl()->evaluated()) {
      id->decl()->e(E::exp(r));
      id->decl()->evaluated(true);
    }
    return r;
  }

  class EvalIntLit {
  public:
    typedef IntLit* Val;
    typedef Expression* ArrayVal;
    static IntLit* e(Expression* e) {
      return new IntLit(Location(),eval_int(e));
    }
    static Expression* exp(IntLit* e) { return e; }
  };
  class EvalIntVal {
  public:
    typedef IntVal Val;
    typedef IntVal ArrayVal;
    static IntVal e(Expression* e) {
      return eval_int(e);
    }
    static Expression* exp(IntVal e) { return new IntLit(Location(),e); }
  };
  class EvalFloatVal {
  public:
    typedef FloatVal Val;
    static FloatVal e(Expression* e) {
      return eval_float(e);
    }
    static Expression* exp(FloatVal e) { return new FloatLit(Location(),e); }
  };
  class EvalFloatLit {
  public:
    typedef FloatLit* Val;
    typedef Expression* ArrayVal;
    static FloatLit* e(Expression* e) {
      return new FloatLit(Location(),eval_float(e));
    }
    static Expression* exp(Expression* e) { return e; }
  };
  class EvalString {
  public:
    typedef std::string Val;
    typedef std::string ArrayVal;
    static std::string e(Expression* e) {
      return eval_string(e);
    }
    static Expression* exp(const std::string& e) { return new StringLit(Location(),e); }
  };
  class EvalStringLit {
  public:
    typedef StringLit* Val;
    typedef Expression* ArrayVal;
    static StringLit* e(Expression* e) {
      return new StringLit(Location(),eval_string(e));
    }
    static Expression* exp(Expression* e) { return e; }
  };
  class EvalBoolLit {
  public:
    typedef BoolLit* Val;
    typedef Expression* ArrayVal;
    static BoolLit* e(Expression* e) {
      return constants().boollit(eval_bool(e));
    }
    static Expression* exp(Expression* e) { return e; }
  };
  class EvalBoolVal {
  public:
    typedef bool Val;
    static bool e(Expression* e) {
      return eval_bool(e);
    }
    static Expression* exp(bool e) { return constants().boollit(e); }
  };
  class EvalArrayLit {
  public:
    typedef ArrayLit* Val;
    typedef Expression* ArrayVal;
    static ArrayLit* e(Expression* e) {
      return eval_array_lit(e);
    }
    static Expression* exp(Expression* e) { return e; }
  };
  class EvalIntSet {
  public:
    typedef IntSetVal* Val;
    static IntSetVal* e(Expression* e) {
      return eval_intset(e);
    }
    static Expression* exp(IntSetVal* e) { return new SetLit(Location(),e); }
  };
  class EvalSetLit {
  public:
    typedef SetLit* Val;
    typedef Expression* ArrayVal;
    static SetLit* e(Expression* e) {
      return new SetLit(e->loc(),eval_intset(e));
    }
    static Expression* exp(Expression* e) { return e; }
  };
  class EvalNone {
  public:
    typedef Expression* Val;
    typedef Expression* ArrayVal;
    static Expression* e(Expression* e) {
      return e;
    }
    static Expression* exp(Expression* e) { return e; }
  };
  class EvalCopy {
  public:
    typedef Expression* Val;
    typedef Expression* ArrayVal;
    static Expression* e(Expression* e) {
      return copy(e,true);
    }
    static Expression* exp(Expression* e) { return e; }
  };

  template<class Eval>
  typename Eval::Val eval_call(Call* ce) {
    std::vector<Expression*> previousParameters(ce->decl()->params().size());
    for (unsigned int i=ce->decl()->params().size(); i--;) {
      VarDecl* vd = ce->decl()->params()[i];
      previousParameters[i] = vd->e();
      vd->flat(vd);
      vd->e(eval_par(ce->args()[i]));
    }
    typename Eval::Val ret = Eval::e(ce->decl()->e());
    for (unsigned int i=ce->decl()->params().size(); i--;) {
      VarDecl* vd = ce->decl()->params()[i];
      vd->e(previousParameters[i]);
      vd->flat(vd->e() ? vd : NULL);
    }
    return ret;
  }
  
  ArrayLit* eval_array_comp(Comprehension* e) {
    ArrayLit* ret;
    if (e->type() == Type::parint(1)) {
      std::vector<Expression*> a = eval_comp<EvalIntLit>(e);
      ret = new ArrayLit(e->loc(),a);
    } else if (e->type() == Type::parbool(1)) {
      std::vector<Expression*> a = eval_comp<EvalBoolLit>(e);
{'fraction_non_alphanumeric': 0.15737640338782746, 'fraction_numerical': 0.001378766988378964, 'mean_word_length': 3.1180048661800486, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 123, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5239211', 'n_tokens_mistral': 3438, 'n_tokens_neox': 3329, 'n_words': 866}