/
closure.H
113 lines (81 loc) · 2.38 KB
/
closure.H
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#ifndef CLOSURE_H
#define CLOSURE_H
#include <vector>
#include <string>
#include <boost/container/small_vector.hpp>
#include "object.H"
#include "computation/expression.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);
closure trim_unnormalize(closure C);
expression_ref deindexify(const closure& C);
#endif