-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcompiler.h
164 lines (136 loc) · 3.78 KB
/
compiler.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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#ifndef COMPILER_H
#define COMPILER_H
#include "types.h"
#include "error.h"
#include "context.h"
#include <vector>
#include <string>
#include <functional>
#include <unordered_map>
namespace amps
{
class parser_iterator;
struct branch
{
token_types type;
bool taken;
};
struct block_cache
{
size_t start;
size_t end;
size_t resume;
size_t iterations;
};
class compiler
{
bool running_cache_;
bool update_main_cache_;
std::string result_;
error &error_;
size_t current_cache_;
context context_;
std::vector<branch> branches_;
std::unordered_map<size_t, block_cache> cache_;
std::function<void(const context &,
const std::vector<branch> &)> inspect_;
private:
void jump_to(token_types type);
bool parse_expression(parser_iterator &it);
bool parse_logical(parser_iterator &it);
bool parse_equality(parser_iterator &it);
bool parse_comparison(parser_iterator &it);
bool parse_addition(parser_iterator &it);
bool parse_multiplication(parser_iterator &it);
bool parse_unary(parser_iterator &it);
bool parse_primary(parser_iterator &it);
bool run_statement(parser_iterator &it, metainfo &metainfo);
bool run_print(parser_iterator &it);
bool run_for(parser_iterator &it);
bool run_endfor(parser_iterator &it);
bool run_if(parser_iterator &it);
bool run_else(parser_iterator &it);
bool run_elif(parser_iterator &it);
bool run_endif(parser_iterator &it);
bool run_insert(parser_iterator &it, metainfo &metainfo);
object compute(token_types oper, size_t line);
object compute_unary(token_types oper, size_t line);
object compute_numbers(number_t a,
number_t b,
token_types oper, size_t line);
object compute_strings(std::string a,
std::string b,
token_types oper);
public:
compiler(error &err);
std::string generate(metainfo &metainfo, const user_map &usermap);
void reset();
template <typename F>
void set_callback(F&& callback)
{
inspect_ = std::forward<F>(callback);
}
};
class parser_iterator
{
friend class compiler;
const tokens &tokens_;
const metarange &range_;
size_t cursor_;
parser_iterator(const tokens &tks, const metarange &range) :
tokens_(tks),
range_(range),
cursor_(0)
{
}
bool advance()
{
if (cursor_ > tokens_.size() - 1) {
return false;
}
++cursor_;
return true;
}
bool is_eot() const
{
if (cursor_ >= tokens_.size()) {
return true;
}
return false;
}
token_t look() const
{
return tokens_[cursor_];
}
token_t look_back() const
{
return tokens_[cursor_ - 1];
}
void next()
{
if (is_eot()) {
return;
}
advance();
}
void skip_all()
{
while (!is_eot()) {
advance();
}
}
metarange range() const
{
return range_;
}
bool match(token_types type)
{
if (!is_eot() && tokens_[cursor_].type() == type) {
advance();
return true;
}
return false;
}
};
}
#endif // COMPILER_H