VapourSynth-llvmexpr
Loading...
Searching...
No Matches
PostfixBuilder.cpp
Go to the documentation of this file.
1
19
20#include "PostfixBuilder.hpp"
21
22#include <cctype>
23#include <format>
24#include <numeric>
25#include <sstream>
26
27namespace infix2postfix {
28
29void PostfixBuilder::pushToken(const std::string& token) {
30 if (!token.empty()) {
31 tokens.push_back(token);
32 }
33}
34
36 switch (type) {
37 case TokenType::Plus:
38 pushToken("+");
39 break;
40 case TokenType::Minus:
41 pushToken("-");
42 break;
43 case TokenType::Star:
44 pushToken("*");
45 break;
46 case TokenType::Slash:
47 pushToken("/");
48 break;
49 case TokenType::Percent:
50 pushToken("%");
51 break;
52 case TokenType::StarStar:
53 pushToken("pow");
54 break;
55 case TokenType::LogicalAnd:
56 pushToken("and");
57 break;
58 case TokenType::LogicalOr:
59 pushToken("or");
60 break;
61 case TokenType::BitAnd:
62 pushToken("bitand");
63 break;
64 case TokenType::BitOr:
65 pushToken("bitor");
66 break;
67 case TokenType::BitXor:
68 pushToken("bitxor");
69 break;
70 case TokenType::Eq:
71 pushToken("=");
72 break;
73 case TokenType::Ne:
74 pushToken("=");
75 pushToken("not");
76 break;
77 case TokenType::Lt:
78 pushToken("<");
79 break;
80 case TokenType::Le:
81 pushToken("<=");
82 break;
83 case TokenType::Gt:
84 pushToken(">");
85 break;
86 case TokenType::Ge:
87 pushToken(">=");
88 break;
89 default:
90 std::unreachable();
91 }
92}
93
95 switch (type) {
96 case TokenType::Minus:
97 pushToken("neg");
98 break;
99 case TokenType::Not:
100 pushToken("not");
101 break;
102 case TokenType::BitNot:
103 pushToken("bitnot");
104 break;
105 default:
106 std::unreachable();
107 }
108}
109
110void PostfixBuilder::addTernaryOp() { pushToken("?"); }
111
112void PostfixBuilder::addFunctionCall(const std::string& func_name) {
113 pushToken(func_name);
114}
115
116void PostfixBuilder::addNumber(const std::string& num_literal) {
117 pushToken(num_literal);
118}
119
120void PostfixBuilder::addConstant(const std::string& const_name) {
121 pushToken(const_name);
122}
123
124void PostfixBuilder::addVariableLoad(const std::string& var_name) {
125 pushToken(var_name + "@");
126}
127
128void PostfixBuilder::addVariableStore(const std::string& var_name) {
129 pushToken(var_name + "!");
130}
131
132void PostfixBuilder::addLabel(const std::string& label_name) {
133 pushToken("#" + label_name);
134}
135
136void PostfixBuilder::addConditionalJump(const std::string& label_name) {
137 pushToken(label_name + "#");
138}
139
140void PostfixBuilder::addUnconditionalJump(const std::string& label_name) {
141 pushToken("1");
142 addConditionalJump(label_name);
143}
144
145void PostfixBuilder::addPropAccess(const std::string& clip_name,
146 const std::string& prop_name) {
147 pushToken(std::format("{}.{}", clip_name, prop_name));
148}
149
150void PostfixBuilder::addPropExist(const std::string& clip_name,
151 const std::string& prop_name) {
152 pushToken(std::format("{}.{}?", clip_name, prop_name));
153}
154
155void PostfixBuilder::addSetProp(const std::string& prop_name,
156 const std::string& suffix) {
157 pushToken(std::format("{}${}", prop_name, suffix));
158}
159
160void PostfixBuilder::addDeleteProp(const std::string& prop_name) {
161 pushToken(std::format("{}$d", prop_name));
162}
163
164void PostfixBuilder::addStaticPixelAccess(const std::string& clip_name,
165 const std::string& x,
166 const std::string& y,
167 const std::string& suffix) {
168 pushToken(std::format("{}[{},{}]{}", clip_name, x, y, suffix));
169}
170
171void PostfixBuilder::addDynPixelAccessExpr(const std::string& clip_name,
172 const std::string& suffix) {
173 pushToken(std::format("{}[]{}", clip_name, suffix));
174}
175
176void PostfixBuilder::addDynPixelAccessSingle(const std::string& clip_name,
177 const std::string& plane) {
178 pushToken(std::format("{}^{}[]", clip_name, plane));
179}
180
181void PostfixBuilder::addStoreExpr() { pushToken("@[]"); }
182
183void PostfixBuilder::addStoreSingle(const std::string& plane) {
184 pushToken(std::format("@[]^{}", plane));
185}
186
187void PostfixBuilder::addFrameDimension(const std::string& dim,
188 const std::string& plane) {
189 pushToken(std::format("{}^{}", dim, plane));
190}
191
192void PostfixBuilder::addExitMarker() { pushToken("^exit^"); }
193
195 pushToken(std::format("drop{}", count));
196}
197
198void PostfixBuilder::addDupN(int count) {
199 pushToken(std::format("dup{}", count));
200}
201
203 pushToken(std::format("swap{}", count));
204}
205
207 pushToken(std::format("sort{}", count));
208}
209
210void PostfixBuilder::addArrayAllocStatic(const std::string& array_name,
211 const std::string& size) {
212 pushToken(std::format("{}{{}}^{}", array_name, size));
213}
214
215void PostfixBuilder::addArrayAllocDynamic(const std::string& array_name) {
216 pushToken(std::format("{}{{}}^", array_name));
217}
218
219void PostfixBuilder::addArrayLoad(const std::string& array_name) {
220 pushToken(std::format("{}{{}}@", array_name));
221}
222
223void PostfixBuilder::addArrayStore(const std::string& array_name) {
224 pushToken(std::format("{}{{}}!", array_name));
225}
226
227void PostfixBuilder::addRaw(const std::string& raw_string) {
228 std::stringstream ss(raw_string);
229 std::string token;
230 while (ss >> token) {
231 pushToken(token);
232 }
233}
234
235std::string PostfixBuilder::getExpression() const {
236 if (tokens.empty()) {
237 return "";
238 }
239
240 size_t total_len =
241 std::accumulate(tokens.begin(), tokens.end(), size_t{0},
242 [](size_t sum, const std::string& token) {
243 return sum + token.length();
244 });
245 total_len += tokens.size() - 1; // for spaces
246
247 std::string result;
248 result.reserve(total_len);
249
250 result.append(tokens[0]);
251 for (size_t i = 1; i < tokens.size(); ++i) {
252 result.push_back(' ');
253 result.append(tokens[i]);
254 }
255
256 return result;
257}
258
259void PostfixBuilder::clear() { tokens.clear(); }
260
261bool PostfixBuilder::empty() const { return tokens.empty(); }
262
264 tokens.insert(tokens.end(), other.tokens.begin(), other.tokens.end());
265}
266
267void PostfixBuilder::prefixLabels(const std::string& prefix) {
268 for (auto& token : tokens) {
269 if (token.empty()) {
270 continue;
271 }
272
273 bool is_label_def = token.front() == '#';
274 bool is_jump = token.back() == '#';
275
276 if (is_label_def || is_jump) {
277 std::string label_name = is_label_def
278 ? token.substr(1)
279 : token.substr(0, token.size() - 1);
280
281 if (label_name.empty()) {
282 continue;
283 }
284
285 if (label_name.starts_with("__internal_")) {
286 continue;
287 }
288
289 std::string new_label = prefix + label_name;
290 if (is_label_def) {
291 token = "#" + new_label;
292 } else {
293 token = new_label + "#";
294 }
295 }
296 }
297}
298
299} // namespace infix2postfix
void addConstant(const std::string &const_name)
void addStaticPixelAccess(const std::string &clip_name, const std::string &x, const std::string &y, const std::string &suffix)
void addSetProp(const std::string &prop_name, const std::string &suffix)
void addNumber(const std::string &num_literal)
void addLabel(const std::string &label_name)
void addUnconditionalJump(const std::string &label_name)
void addArrayAllocStatic(const std::string &array_name, const std::string &size)
void addPropExist(const std::string &clip_name, const std::string &prop_name)
void addConditionalJump(const std::string &label_name)
void addDeleteProp(const std::string &prop_name)
void prefixLabels(const std::string &prefix)
void addStoreSingle(const std::string &plane)
void addFunctionCall(const std::string &func_name)
void addArrayAllocDynamic(const std::string &array_name)
void addArrayLoad(const std::string &array_name)
void addDynPixelAccessExpr(const std::string &clip_name, const std::string &suffix)
void addUnaryOp(TokenType type)
void addArrayStore(const std::string &array_name)
void addDynPixelAccessSingle(const std::string &clip_name, const std::string &plane)
std::string getExpression() const
void append(const PostfixBuilder &other)
void addFrameDimension(const std::string &dim, const std::string &plane)
void addVariableStore(const std::string &var_name)
void addRaw(const std::string &raw_string)
void addPropAccess(const std::string &clip_name, const std::string &prop_name)
void addVariableLoad(const std::string &var_name)