-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapply.hpp
More file actions
55 lines (42 loc) · 1.34 KB
/
apply.hpp
File metadata and controls
55 lines (42 loc) · 1.34 KB
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
#pragma once
#include "nodes.hpp"
#include "copy.hpp"
namespace lambda {
namespace _apply {
class Apply {
private:
const Variable& target;
std::unique_ptr<LambdaBase> value;
void applyVariable(std::unique_ptr<LambdaBase>& node) {
if (*(std::unique_ptr<Variable>&)node == target)
node = copy(value);
}
void applyFunction(std::unique_ptr<LambdaBase>& node) {
if (((std::unique_ptr<Function>&)node)->bound == target)
return;
apply(((std::unique_ptr<Function>&)node)->body);
}
void applyApplication(std::unique_ptr<LambdaBase>& node) {
apply(((std::unique_ptr<Application>&)node)->left);
apply(((std::unique_ptr<Application>&)node)->right);
}
public:
Apply(const Variable& target, std::unique_ptr<LambdaBase> value)
: target(target), value(std::move(value)) {}
void apply(std::unique_ptr<LambdaBase>& node) {
switch (node->getType()) {
case LambdaType::VARIABLE:
return applyVariable(node);
case LambdaType::FUNCTION:
return applyFunction(node);
case LambdaType::APPLICATION:
return applyApplication(node);
}
}
};
} // namespace _apply
inline void apply(std::unique_ptr<LambdaBase>& node, const Variable& target,
std::unique_ptr<LambdaBase> value) {
if (node && value) _apply::Apply(target, std::move(value)).apply(node);
}
} // namespace lambda