-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrename.hpp
More file actions
93 lines (69 loc) · 2.74 KB
/
rename.hpp
File metadata and controls
93 lines (69 loc) · 2.74 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
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
#pragma once
#include "nodes.hpp"
// takes away the need for alpha conversion
namespace lambda {
namespace _rename {
class Rename {
private:
std::uint16_t globalCount = 0;
void renameBoundVariable(std::unique_ptr<LambdaBase>& node,
const Variable& target, std::uint16_t count) noexcept {
if (*(std::unique_ptr<Variable>&)node == target)
((std::unique_ptr<Variable>&)node)->count = count;
}
void renameBoundFunction(std::unique_ptr<LambdaBase>& node,
const Variable& target, std::uint16_t count) noexcept {
if (((std::unique_ptr<Function>&)node)->bound != target)
renameBound(((std::unique_ptr<Function>&)node)->body, target, count);
globalCount++;
std::uint16_t newCount = globalCount;
renameBound(((std::unique_ptr<Function>&)node)->body,
((std::unique_ptr<Function>&)node)->bound, newCount);
((std::unique_ptr<Function>&)node)->bound.count = newCount;
}
void renameBoundApplication(std::unique_ptr<LambdaBase>& node,
const Variable& target, std::uint16_t count) noexcept {
renameBound(((std::unique_ptr<Application>&)node)->left, target, count);
renameBound(((std::unique_ptr<Application>&)node)->right, target, count);
}
void renameBound(std::unique_ptr<LambdaBase>& node, const Variable& target,
std::uint16_t count) noexcept {
switch (node->getType()) {
case LambdaType::VARIABLE:
return renameBoundVariable(node, target, count);
case LambdaType::FUNCTION:
return renameBoundFunction(node, target, count);
case LambdaType::APPLICATION:
return renameBoundApplication(node, target, count);
}
}
void renameUnboundVariable(std::unique_ptr<LambdaBase>& node) noexcept {}
void renameUnboundFunction(std::unique_ptr<LambdaBase>& node) noexcept {
globalCount++;
std::uint16_t count = globalCount;
renameBound(((std::unique_ptr<Function>&)node)->body,
((std::unique_ptr<Function>&)node)->bound, count);
((std::unique_ptr<Function>&)node)->bound.count = count;
}
void renameUnboundApplication(std::unique_ptr<LambdaBase>& node) noexcept {
renameUnbound(((std::unique_ptr<Application>&)node)->left);
renameUnbound(((std::unique_ptr<Application>&)node)->right);
}
public:
Rename() noexcept = default;
void renameUnbound(std::unique_ptr<LambdaBase>& node) noexcept {
switch (node->getType()) {
case LambdaType::VARIABLE:
return renameUnboundVariable(node);
case LambdaType::FUNCTION:
return renameUnboundFunction(node);
case LambdaType::APPLICATION:
return renameUnboundApplication(node);
}
}
};
} // namespace _rename
inline void rename(std::unique_ptr<LambdaBase>& node) noexcept {
if (node) _rename::Rename().renameUnbound(node);
}
} // namespace lambda