-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathast.hpp
124 lines (99 loc) · 4.48 KB
/
ast.hpp
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
114
115
116
117
118
119
120
121
122
123
124
#pragma once
#include <utility>
#include <vector>
#include <memory>
enum StatementKind {
Print,
Input,
ShiftLeft,
ShiftRight,
Loop,
Increment,
Decrement
};
class Visitor;
class Statement {
public:
virtual auto kind() const -> StatementKind = 0;
virtual auto accept(Visitor& visitor) -> void = 0;
};
class PrintStatement : public Statement {
public:
auto kind() const -> StatementKind override { return StatementKind::Print; }
auto accept(Visitor& visitor) -> void override;
};
class InputStatement : public Statement {
public:
auto kind() const -> StatementKind override { return StatementKind::Input; }
auto accept(Visitor& visitor) -> void override;
};
class ShiftLeftStatement : public Statement {
public:
long long by;
explicit ShiftLeftStatement(long long by = 1) : by(by) { }
auto kind() const -> StatementKind override { return StatementKind::ShiftLeft; }
auto accept(Visitor& visitor) -> void override;
};
class ShiftRightStatement : public Statement {
public:
long long by;
explicit ShiftRightStatement(long long by = 1) : by(by) { }
auto kind() const -> StatementKind override { return StatementKind::ShiftRight; }
auto accept(Visitor& visitor) -> void override;
};
class LoopStatement : public Statement {
public:
std::vector<std::unique_ptr<Statement>> statements;
auto kind() const -> StatementKind override { return StatementKind::Loop; }
auto accept(Visitor& visitor) -> void override;
explicit LoopStatement(std::vector<std::unique_ptr<Statement>> statements) : statements(std::move(statements)) { }
};
class IncrementStatement : public Statement {
public:
long long by;
explicit IncrementStatement(long long by = 1) : by(by) { }
auto kind() const -> StatementKind override { return StatementKind::Increment; }
auto accept(Visitor& visitor) -> void override;
};
class DecrementStatement : public Statement {
public:
long long by;
explicit DecrementStatement(long long by = 1) : by(by) { }
auto kind() const -> StatementKind override { return StatementKind::Decrement; }
auto accept(Visitor& visitor) -> void override;
};
class Visitor {
public:
virtual auto visit(const PrintStatement& printStatement) -> void { };
virtual auto visit(const InputStatement& inputStatement) -> void { };
virtual auto visit(const ShiftLeftStatement& shiftLeftStatement) -> void { };
virtual auto visit(const ShiftRightStatement& shiftRightStatement) -> void { };
virtual auto visit(const LoopStatement& loopStatement) -> void { };
virtual auto visit(const IncrementStatement& incrementStatement) -> void { };
virtual auto visit(const DecrementStatement& decrementStatement) -> void { };
};
class Listener : public Visitor {
protected:
virtual auto visitPrintStatement(const PrintStatement& printStatement) -> void { };
virtual auto visitInputStatement(const InputStatement& inputStatement) -> void { };
virtual auto visitShiftLeftStatement(const ShiftLeftStatement& shiftLeftStatement) -> void { };
virtual auto visitShiftRightStatement(const ShiftRightStatement& shiftRightStatement) -> void { };
virtual auto visitIncrementStatement(const IncrementStatement& incrementStatement) -> void { };
virtual auto visitDecrementStatement(const DecrementStatement& decrementStatement) -> void { };
virtual auto enterLoopStatement(const LoopStatement& loopStatement) -> void { };
virtual auto exitLoopStatement(const LoopStatement& loopStatement) -> void { };
private:
auto visit(const PrintStatement& printStatement) -> void override { visitPrintStatement(printStatement); };
auto visit(const InputStatement& inputStatement) -> void override { visitInputStatement(inputStatement); };
auto visit(const ShiftLeftStatement& shiftLeftStatement) -> void override { visitShiftLeftStatement(shiftLeftStatement); };
auto visit(const ShiftRightStatement& shiftRightStatement) -> void override { visitShiftRightStatement(shiftRightStatement); };
auto visit(const IncrementStatement& incrementStatement) -> void override { visitIncrementStatement(incrementStatement); };
auto visit(const DecrementStatement& decrementStatement) -> void override { visitDecrementStatement(decrementStatement); };
auto visit(const LoopStatement& loopStatement) -> void override {
enterLoopStatement(loopStatement);
for (auto& statement : loopStatement.statements) {
statement->accept(*this);
}
exitLoopStatement(loopStatement);
}
};