-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
70 lines (42 loc) · 1.74 KB
/
main.cpp
File metadata and controls
70 lines (42 loc) · 1.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
#include "ir.h"
#include "patterns.h"
#include "analysis.h"
/** Ok, so we can match on
1) instruction types
We can have different patterns, they may match a single instruction, or many. The fewer instructions it matches, the higher its priority.
2) abstract values
Each pattern can match only a single abstract value. The more specific the abstract value, the higher the priority od the pattern.
This means that both instruction and value pattern must be able to tell the matcher what they match
*/
using namespace analysis;
class SimplerAdd : public Visitlet {
// this is what is actually happening
TypeShape::Pattern * lhs = new TypeShape::Pattern(TypeShape::naked(TypeShape::Value::Type::Int));
// if the analyses provide shortcut methods, the code can be much nicer (we can in theory get them out of the classes, but I would consider that ugly)
TypeShape::Pattern * rhs = TypeShape::nakedInt();
// already with sugared shortcut method
CallTarget::Pattern * f = CallTarget::builtin("+");
Call * e = new Call(f, { lhs, rhs });
public:
Pattern * pattern() override {
return e;
}
void match() override {
Constants & cp(analysis<Constants>());
if (cp[lhs].isConstant() and cp[rhs].isConstant()) {
// missing, depends on how to instantiate Push matcher with actual operand
} else {
e->replaceWith(new Add(lhs, rhs));
}
}
};
int main(int argc, char const * argv[]) {
Code f;
f.append(Instruction::Push(f.pool.append(1)));
f.append(Instruction::Push(f.pool.append(2)));
f.append(Instruction::Add());
f.append(Instruction::Push(f.pool.append(3)));
f.append(Instruction::Add());
std::cout << f;
return EXIT_SUCCESS;
}