VapourSynth-llvmexpr
Loading...
Searching...
No Matches
AST.hpp
Go to the documentation of this file.
1
19
20#ifndef LLVMEXPR_FRONTEND_INFIX2POSTFIX_AST_HPP
21#define LLVMEXPR_FRONTEND_INFIX2POSTFIX_AST_HPP
22
23#include "Symbol.hpp"
24#include "types.hpp"
25#include <memory>
26#include <string>
27#include <type_traits>
28#include <variant>
29#include <vector>
30
31namespace infix2postfix {
32
33// Forward declarations
34struct Expr;
35struct Stmt;
36struct BlockStmt;
37struct GlobalDecl;
38struct FunctionDef;
39struct BuiltinFunction;
40
41// Expression node types
42struct NumberExpr {
45
46 explicit NumberExpr(Token val)
47 : value(std::move(val)), range(value.range) {}
48};
49
53 std::shared_ptr<Symbol> symbol;
54
55 explicit VariableExpr(Token n) : name(std::move(n)), range(name.range) {}
56};
57
58struct UnaryExpr {
60 std::unique_ptr<Expr> right;
62
63 UnaryExpr(Token o, std::unique_ptr<Expr> r);
64};
65
66struct BinaryExpr {
67 std::unique_ptr<Expr> left;
69 std::unique_ptr<Expr> right;
71
72 BinaryExpr(std::unique_ptr<Expr> l, Token o, std::unique_ptr<Expr> r);
73};
74
76 std::unique_ptr<Expr> cond;
77 std::unique_ptr<Expr> true_expr;
78 std::unique_ptr<Expr> false_expr;
80
81 TernaryExpr(std::unique_ptr<Expr> c, std::unique_ptr<Expr> t,
82 std::unique_ptr<Expr> f);
83};
84
85struct CallExpr {
86 std::string callee;
87 std::vector<std::unique_ptr<Expr>> args;
92
93 CallExpr(Token callee_token, std::vector<std::unique_ptr<Expr>> a);
94};
95
100
102 : clip(std::move(c)), prop(std::move(p)), range(clip.range) {}
103};
104
109 std::string boundary_suffix;
111
112 StaticRelPixelAccessExpr(Token c, Token x, Token y, std::string suffix)
113 : clip(std::move(c)), offset_x(std::move(x)), offset_y(std::move(y)),
114 boundary_suffix(std::move(suffix)), range(clip.range) {}
115};
116
118 std::string dimension_name; // "width" or "height"
119 std::unique_ptr<Expr> plane_index_expr;
121
122 FrameDimensionExpr(Token keyword, std::unique_ptr<Expr> plane);
123};
124
126 std::unique_ptr<Expr> array;
127 std::unique_ptr<Expr> index;
129 std::shared_ptr<Symbol> array_symbol;
130
131 ArrayAccessExpr(std::unique_ptr<Expr> arr, std::unique_ptr<Expr> idx);
132};
133
134// Statement node types
135struct ExprStmt {
136 std::unique_ptr<Expr> expr;
138
139 explicit ExprStmt(std::unique_ptr<Expr> e);
140};
141
144 std::unique_ptr<Expr> value;
146 std::shared_ptr<Symbol> symbol;
147
148 AssignStmt(Token n, std::unique_ptr<Expr> v);
149};
150
152 std::unique_ptr<Expr> target; // Should be an ArrayAccessExpr
153 std::unique_ptr<Expr> value;
155
156 ArrayAssignStmt(std::unique_ptr<Expr> t, std::unique_ptr<Expr> v);
157};
158
159struct BlockStmt {
160 std::vector<std::unique_ptr<Stmt>> statements;
162
163 explicit BlockStmt(std::vector<std::unique_ptr<Stmt>> s);
164};
165
166struct IfStmt {
167 std::unique_ptr<Expr> condition;
168 std::unique_ptr<Stmt> then_branch;
169 std::unique_ptr<Stmt> else_branch;
171
172 IfStmt(std::unique_ptr<Expr> c, std::unique_ptr<Stmt> t,
173 std::unique_ptr<Stmt> e);
174};
175
176struct WhileStmt {
177 std::unique_ptr<Expr> condition;
178 std::unique_ptr<Stmt> body;
180
181 WhileStmt(std::unique_ptr<Expr> c, std::unique_ptr<Stmt> b);
182};
183
186 std::unique_ptr<Expr> value;
188
189 ReturnStmt(Token kw, std::unique_ptr<Expr> v);
190};
191
192struct LabelStmt {
195 std::shared_ptr<Symbol> symbol;
196
197 explicit LabelStmt(Token n) : name(std::move(n)), range(name.range) {}
198};
199
200struct GotoStmt {
203 std::unique_ptr<Expr> condition;
205 std::shared_ptr<Symbol> target_label_symbol;
206
207 GotoStmt(Token kw, Token l, std::unique_ptr<Expr> c);
208};
209
213 std::vector<Token> globals;
215
216 GlobalDecl(Token t, GlobalMode m, std::vector<Token> g = {})
217 : keyword(std::move(t)), mode(m), globals(std::move(g)),
219};
220
226
229 std::vector<Parameter> params;
230 std::unique_ptr<BlockStmt> body;
231 std::unique_ptr<GlobalDecl> global_decl;
233 std::shared_ptr<Symbol> symbol;
234
235 FunctionDef(Token n, std::vector<Parameter> p, std::unique_ptr<BlockStmt> b,
236 std::unique_ptr<GlobalDecl> g);
237};
238
239struct Expr {
244
246
247 template <typename T> explicit Expr(T&& v) : value(std::forward<T>(v)) {}
248
249 Expr(const Expr&) = delete;
250 Expr& operator=(const Expr&) = delete;
251 Expr(Expr&&) = default;
252 Expr& operator=(Expr&&) = default;
253 ~Expr() = default;
254
255 [[nodiscard]] Range range() const {
256 return std::visit([](const auto& e) { return e.range; }, value);
257 }
258};
259
260struct Stmt {
264
266
267 template <typename T> explicit Stmt(T&& v) : value(std::forward<T>(v)) {}
268
269 Stmt(const Stmt&) = delete;
270 Stmt& operator=(const Stmt&) = delete;
271 Stmt(Stmt&&) = default;
272 Stmt& operator=(Stmt&&) = default;
273 ~Stmt() = default;
274
275 [[nodiscard]] Range range() const {
276 return std::visit([](const auto& s) { return s.range; }, value);
277 }
278};
279
281 std::unique_ptr<Expr> plane)
282 : dimension_name(std::move(keyword.value)),
283 plane_index_expr(std::move(plane)), range(keyword.range) {}
284
285inline UnaryExpr::UnaryExpr(Token o, std::unique_ptr<Expr> r)
286 : op(std::move(o)), right(std::move(r)) {
287 range.start = op.range.start;
288 range.end = right ? right->range().end : op.range.end;
289}
290
291inline BinaryExpr::BinaryExpr(std::unique_ptr<Expr> l, Token o,
292 std::unique_ptr<Expr> r)
293 : left(std::move(l)), op(std::move(o)), right(std::move(r)) {
294 range.start = left ? left->range().start : op.range.start;
295 range.end = right ? right->range().end : op.range.end;
296}
297
298inline TernaryExpr::TernaryExpr(std::unique_ptr<Expr> c,
299 std::unique_ptr<Expr> t,
300 std::unique_ptr<Expr> f)
301 : cond(std::move(c)), true_expr(std::move(t)), false_expr(std::move(f)) {
302 if (cond) {
303 range.start = cond->range().start;
304 }
305 if (false_expr) {
306 range.end = false_expr->range().end;
307 } else if (true_expr) {
308 range.end = true_expr->range().end;
309 } else if (cond) {
310 range.end = cond->range().end;
311 }
312}
313
314inline CallExpr::CallExpr(Token callee_token,
315 std::vector<std::unique_ptr<Expr>> a)
316 : callee(std::move(callee_token.value)), args(std::move(a)),
317 range(callee_token.range) {}
318
319inline ExprStmt::ExprStmt(std::unique_ptr<Expr> e) : expr(std::move(e)) {
320 if (expr) {
321 range = expr->range();
322 }
323}
324
325inline AssignStmt::AssignStmt(Token n, std::unique_ptr<Expr> v)
326 : name(std::move(n)), value(std::move(v)) {
327 range.start = name.range.start;
328 range.end = value ? value->range().end : name.range.end;
329}
330
331inline BlockStmt::BlockStmt(std::vector<std::unique_ptr<Stmt>> s)
332 : statements(std::move(s)) {
333 if (!statements.empty()) {
334 range.start = statements.front()->range().start;
335 range.end = statements.back()->range().end;
336 }
337}
338
339inline IfStmt::IfStmt(std::unique_ptr<Expr> c, std::unique_ptr<Stmt> t,
340 std::unique_ptr<Stmt> e)
341 : condition(std::move(c)), then_branch(std::move(t)),
342 else_branch(std::move(e)) {
343 if (condition) {
344 range.start = condition->range().start;
345 }
346 if (else_branch) {
347 range.end = else_branch->range().end;
348 } else if (then_branch) {
349 range.end = then_branch->range().end;
350 } else if (condition) {
351 range.end = condition->range().end;
352 }
353}
354
355inline WhileStmt::WhileStmt(std::unique_ptr<Expr> c, std::unique_ptr<Stmt> b)
356 : condition(std::move(c)), body(std::move(b)) {
357 if (condition) {
358 range.start = condition->range().start;
359 }
360 if (body) {
361 range.end = body->range().end;
362 } else if (condition) {
363 range.end = condition->range().end;
364 }
365}
366
367inline ReturnStmt::ReturnStmt(Token kw, std::unique_ptr<Expr> v)
368 : keyword(std::move(kw)), value(std::move(v)) {
369 range.start = keyword.range.start;
370 range.end = value ? value->range().end : keyword.range.end;
371}
372
373inline GotoStmt::GotoStmt(Token kw, Token l, std::unique_ptr<Expr> c)
374 : keyword(std::move(kw)), label(std::move(l)), condition(std::move(c)) {
375 range.start = keyword.range.start;
376 range.end = condition ? condition->range().end : label.range.end;
377}
378
379inline FunctionDef::FunctionDef(Token n, std::vector<Parameter> p,
380 std::unique_ptr<BlockStmt> b,
381 std::unique_ptr<GlobalDecl> g)
382 : name(std::move(n)), params(std::move(p)), body(std::move(b)),
383 global_decl(std::move(g)) {
384 range.start = name.range.start;
385 range.end = body ? body->range.end : name.range.end;
386}
387
388inline ArrayAccessExpr::ArrayAccessExpr(std::unique_ptr<Expr> arr,
389 std::unique_ptr<Expr> idx)
390 : array(std::move(arr)), index(std::move(idx)) {
391 if (array) {
392 range.start = array->range().start;
393 }
394 if (index) {
395 range.end = index->range().end;
396 } else if (array) {
397 range.end = array->range().end;
398 }
399}
400
401inline ArrayAssignStmt::ArrayAssignStmt(std::unique_ptr<Expr> t,
402 std::unique_ptr<Expr> v)
403 : target(std::move(t)), value(std::move(v)) {
404 if (target) {
405 range.start = target->range().start;
406 }
407 if (value) {
408 range.end = value->range().end;
409 } else if (target) {
410 range.end = target->range().end;
411 }
412}
413
414struct Program {
415 std::vector<std::unique_ptr<Stmt>> statements;
416};
417
418template <class, class> struct is_variant_member;
419
420template <class T, class... Types>
421struct is_variant_member<T, std::variant<Types...>>
422 : std::disjunction<std::is_same<T, Types>...> {};
423
424template <class T, class V>
426
427template <typename T> struct NodeWrapper {
430 "T must be a member of either ExprVariant or StmtVariant");
431 using type = std::conditional_t<IS_VARIANT_MEMBER_V<T, Expr::ExprVariant>,
432 Expr, Stmt>;
433};
434
435template <typename T> using node_wrapper_t = typename NodeWrapper<T>::type;
436
437template <typename T, typename... Args> auto make_node(Args&&... args) {
438 return std::make_unique<node_wrapper_t<T>>(T(std::forward<Args>(args)...));
439}
440
441template <typename T, typename Wrapper>
442auto get_if(Wrapper* wrapper) -> decltype(std::get_if<T>(&wrapper->value)) {
443 if (!wrapper) {
444 return nullptr;
445 }
446 return std::get_if<T>(&wrapper->value);
447}
448
449} // namespace infix2postfix
450
451#endif // LLVMEXPR_FRONTEND_INFIX2POSTFIX_AST_HPP
auto get_if(Wrapper *wrapper) -> decltype(std::get_if< T >(&wrapper->value))
Definition AST.hpp:442
typename NodeWrapper< T >::type node_wrapper_t
Definition AST.hpp:435
constexpr bool IS_VARIANT_MEMBER_V
Definition AST.hpp:425
auto make_node(Args &&... args)
Definition AST.hpp:437
std::unique_ptr< Expr > index
Definition AST.hpp:127
ArrayAccessExpr(std::unique_ptr< Expr > arr, std::unique_ptr< Expr > idx)
Definition AST.hpp:388
std::unique_ptr< Expr > array
Definition AST.hpp:126
std::shared_ptr< Symbol > array_symbol
Definition AST.hpp:129
ArrayAssignStmt(std::unique_ptr< Expr > t, std::unique_ptr< Expr > v)
Definition AST.hpp:401
std::unique_ptr< Expr > value
Definition AST.hpp:153
std::unique_ptr< Expr > target
Definition AST.hpp:152
std::shared_ptr< Symbol > symbol
Definition AST.hpp:146
std::unique_ptr< Expr > value
Definition AST.hpp:144
AssignStmt(Token n, std::unique_ptr< Expr > v)
Definition AST.hpp:325
BinaryExpr(std::unique_ptr< Expr > l, Token o, std::unique_ptr< Expr > r)
Definition AST.hpp:291
std::unique_ptr< Expr > right
Definition AST.hpp:69
std::unique_ptr< Expr > left
Definition AST.hpp:67
std::vector< std::unique_ptr< Stmt > > statements
Definition AST.hpp:160
BlockStmt(std::vector< std::unique_ptr< Stmt > > s)
Definition AST.hpp:331
std::vector< std::unique_ptr< Expr > > args
Definition AST.hpp:87
std::string callee
Definition AST.hpp:86
const FunctionSignature * resolved_signature
Definition AST.hpp:89
CallExpr(Token callee_token, std::vector< std::unique_ptr< Expr > > a)
Definition AST.hpp:314
const BuiltinFunction * resolved_builtin
Definition AST.hpp:91
FunctionDef * resolved_def
Definition AST.hpp:90
std::unique_ptr< Expr > expr
Definition AST.hpp:136
ExprStmt(std::unique_ptr< Expr > e)
Definition AST.hpp:319
Expr & operator=(Expr &&)=default
std::variant< NumberExpr, VariableExpr, UnaryExpr, BinaryExpr, TernaryExpr, CallExpr, PropAccessExpr, StaticRelPixelAccessExpr, FrameDimensionExpr, ArrayAccessExpr > ExprVariant
Definition AST.hpp:240
ExprVariant value
Definition AST.hpp:245
Expr(Expr &&)=default
Range range() const
Definition AST.hpp:255
Expr(const Expr &)=delete
Expr & operator=(const Expr &)=delete
FrameDimensionExpr(Token keyword, std::unique_ptr< Expr > plane)
Definition AST.hpp:280
std::unique_ptr< Expr > plane_index_expr
Definition AST.hpp:119
std::vector< Parameter > params
Definition AST.hpp:229
std::unique_ptr< BlockStmt > body
Definition AST.hpp:230
FunctionDef(Token n, std::vector< Parameter > p, std::unique_ptr< BlockStmt > b, std::unique_ptr< GlobalDecl > g)
Definition AST.hpp:379
std::unique_ptr< GlobalDecl > global_decl
Definition AST.hpp:231
std::shared_ptr< Symbol > symbol
Definition AST.hpp:233
std::vector< Token > globals
Definition AST.hpp:213
GlobalDecl(Token t, GlobalMode m, std::vector< Token > g={})
Definition AST.hpp:216
GotoStmt(Token kw, Token l, std::unique_ptr< Expr > c)
Definition AST.hpp:373
std::unique_ptr< Expr > condition
Definition AST.hpp:203
std::shared_ptr< Symbol > target_label_symbol
Definition AST.hpp:205
std::unique_ptr< Expr > condition
Definition AST.hpp:167
std::unique_ptr< Stmt > then_branch
Definition AST.hpp:168
IfStmt(std::unique_ptr< Expr > c, std::unique_ptr< Stmt > t, std::unique_ptr< Stmt > e)
Definition AST.hpp:339
std::unique_ptr< Stmt > else_branch
Definition AST.hpp:169
std::shared_ptr< Symbol > symbol
Definition AST.hpp:195
std::conditional_t< IS_VARIANT_MEMBER_V< T, Expr::ExprVariant >, Expr, Stmt > type
Definition AST.hpp:431
NumberExpr(Token val)
Definition AST.hpp:46
std::vector< std::unique_ptr< Stmt > > statements
Definition AST.hpp:415
PropAccessExpr(Token c, Token p)
Definition AST.hpp:101
std::unique_ptr< Expr > value
Definition AST.hpp:186
ReturnStmt(Token kw, std::unique_ptr< Expr > v)
Definition AST.hpp:367
StaticRelPixelAccessExpr(Token c, Token x, Token y, std::string suffix)
Definition AST.hpp:112
Stmt & operator=(const Stmt &)=delete
Range range() const
Definition AST.hpp:275
Stmt & operator=(Stmt &&)=default
StmtVariant value
Definition AST.hpp:265
Stmt(const Stmt &)=delete
std::variant< ExprStmt, AssignStmt, BlockStmt, IfStmt, WhileStmt, ReturnStmt, LabelStmt, GotoStmt, FunctionDef, GlobalDecl, ArrayAssignStmt > StmtVariant
Definition AST.hpp:261
Stmt(Stmt &&)=default
TernaryExpr(std::unique_ptr< Expr > c, std::unique_ptr< Expr > t, std::unique_ptr< Expr > f)
Definition AST.hpp:298
std::unique_ptr< Expr > cond
Definition AST.hpp:76
std::unique_ptr< Expr > true_expr
Definition AST.hpp:77
std::unique_ptr< Expr > false_expr
Definition AST.hpp:78
std::unique_ptr< Expr > right
Definition AST.hpp:60
UnaryExpr(Token o, std::unique_ptr< Expr > r)
Definition AST.hpp:285
std::shared_ptr< Symbol > symbol
Definition AST.hpp:53
std::unique_ptr< Stmt > body
Definition AST.hpp:178
std::unique_ptr< Expr > condition
Definition AST.hpp:177
WhileStmt(std::unique_ptr< Expr > c, std::unique_ptr< Stmt > b)
Definition AST.hpp:355