Permalink
Switch branches/tags
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
116 lines (82 sloc) 2.45 KB
#ifndef CLOSURE_H
#define CLOSURE_H
#include <vector>
#include <string>
#include <boost/container/small_vector.hpp>
#include "object.H"
#include "computation/expression/expression_ref.H"
struct closure
{
typedef boost::container::small_vector<int,10> Env_t;
/// The expression
expression_ref exp;
/// The environment (regs bound to free variables of E).
Env_t Env;
/// Is the closure not empty
operator bool() const {return exp and exp.head();}
bool operator==(const closure& C2) const {return exp == C2.exp and Env == C2.Env;}
int lookup_in_env(int i) const;
/// Clear the closure.
void clear();
std::string print() const;
// Assignment operators
closure& operator=(const closure&) = default;
closure& operator=(closure&& C) noexcept
{
exp = C.exp;
Env = std::move(C.Env);
return *this;
}
// Default
closure() = default;
closure(const closure&) = default;
closure(closure&& C) noexcept
:exp(C.exp),
Env( std::move(C.Env) )
{ }
// Constructing from an expression_ref
closure(const expression_ref& e)
:exp(e)
{ }
closure(const expression_ref& e, const Env_t& E)
:exp(e), Env(E)
{ }
closure(const expression_ref& e, std::initializer_list<int> E)
:closure(e, Env_t(E))
{ }
// Constructing w/ an environment
closure(Object* o, const Env_t& E)
:closure(expression_ref(o),E)
{ }
closure(const object_ptr<const Object>& o, const Env_t& E)
:closure(expression_ref(o),E)
{ }
template <typename T>
closure(const object_ptr<T>& o, const Env_t& E)
:closure(expression_ref(o),E)
{ }
closure(const Object& O, const Env_t& E):closure(expression_ref(O),E) { }
closure(const Object& O, std::initializer_list<int> E):closure(O,Env_t(E)) { }
// Constructing w/o an environment
closure(Object* o)
:closure(expression_ref(o))
{ }
closure(const object_ptr<const Object>& o)
:closure(expression_ref(o))
{ }
template <typename T>
closure(const object_ptr<T>& o)
:closure(expression_ref(o))
{ }
closure(const Object& O)
:closure(expression_ref(O))
{ }
};
inline int lookup_in_env(const closure::Env_t& Env, int i) {return Env[Env.size() - 1 - i];}
inline int closure::lookup_in_env(int i) const {return ::lookup_in_env(Env,i);}
closure get_trimmed(const closure& C);
closure get_trimmed(closure&& C);
void do_trim(closure& C);
closure trim_unnormalize(closure C);
expression_ref deindexify(const closure& C);
#endif