VapourSynth-llvmexpr
Loading...
Searching...
No Matches
types.hpp
Go to the documentation of this file.
1
19
20#ifndef LLVMEXPR_FRONTEND_INFIX2POSTFIX_TYPES_HPP
21#define LLVMEXPR_FRONTEND_INFIX2POSTFIX_TYPES_HPP
22
25
26#include <algorithm>
27#include <array>
28#include <cctype>
29#include <charconv>
30#include <cstdint>
31#include <format>
32#include <optional>
33#include <set>
34#include <string>
35#include <string_view>
36#include <utility>
37#include <vector>
38
39namespace infix2postfix {
40
42 int line = 0;
43 int column = 0;
44};
45
46struct Range {
49
50 // NOLINTNEXTLINE(readability-identifier-naming)
51 [[nodiscard]] std::string to_string() const {
52 return std::format("{}:{} - {}:{}", start.line, start.column, end.line,
53 end.column);
54 }
55};
56
57enum class Type : std::uint8_t {
64};
65
66enum class TokenType : std::uint8_t {
67 // Keywords
68 If, // if
69 Else, // else
70 While, // while
71 Goto, // goto
72 Function, // function
73 Return, // return
74
75 // Operators
76 Plus, // +
77 Minus, // -
78 Star, // *
79 Slash, // /
80 Percent, // %
81 StarStar, // **
83 LogicalOr, // ||
84 BitAnd, // &
85 BitOr, // |
86 BitXor, // ^
87 BitNot, // ~
88 Eq, // ==
89 Ne, // !=
90 Lt, // <
91 Le, // <=
92 Gt, // >
93 Ge, // >=
94 Assign, // =
96 Colon, // :
97 Not, // !
98
99 // Punctuation
100 LParen, // (
101 RParen, // )
102 LBrace, // {
103 RBrace, // }
106 Comma, // ,
107 Dot, // .
109
110 // Literals
113
114 // Special
115 Global, // <global...>
119};
120
123 std::string_view str;
124};
125
126constexpr std::array TOKEN_MAPPINGS = {
127 // Keywords
128 TokenMapping{.type = TokenType::If, .str = "if"},
129 TokenMapping{.type = TokenType::Else, .str = "else"},
130 TokenMapping{.type = TokenType::While, .str = "while"},
131 TokenMapping{.type = TokenType::Goto, .str = "goto"},
132 TokenMapping{.type = TokenType::Function, .str = "function"},
133 TokenMapping{.type = TokenType::Return, .str = "return"},
134
135 // Operators
136 TokenMapping{.type = TokenType::Plus, .str = "+"},
137 TokenMapping{.type = TokenType::Minus, .str = "-"},
138 TokenMapping{.type = TokenType::Star, .str = "*"},
139 TokenMapping{.type = TokenType::Slash, .str = "/"},
140 TokenMapping{.type = TokenType::Percent, .str = "%"},
141 TokenMapping{.type = TokenType::StarStar, .str = "**"},
142 TokenMapping{.type = TokenType::LogicalAnd, .str = "&&"},
143 TokenMapping{.type = TokenType::LogicalOr, .str = "||"},
144 TokenMapping{.type = TokenType::BitAnd, .str = "&"},
145 TokenMapping{.type = TokenType::BitOr, .str = "|"},
146 TokenMapping{.type = TokenType::BitXor, .str = "^"},
147 TokenMapping{.type = TokenType::BitNot, .str = "~"},
148 TokenMapping{.type = TokenType::Eq, .str = "=="},
149 TokenMapping{.type = TokenType::Ne, .str = "!="},
150 TokenMapping{.type = TokenType::Lt, .str = "<"},
151 TokenMapping{.type = TokenType::Le, .str = "<="},
152 TokenMapping{.type = TokenType::Gt, .str = ">"},
153 TokenMapping{.type = TokenType::Ge, .str = ">="},
154 TokenMapping{.type = TokenType::Assign, .str = "="},
155 TokenMapping{.type = TokenType::Question, .str = "?"},
156 TokenMapping{.type = TokenType::Colon, .str = ":"},
157 TokenMapping{.type = TokenType::Not, .str = "!"},
158
159 // Punctuation
160 TokenMapping{.type = TokenType::LParen, .str = "("},
161 TokenMapping{.type = TokenType::RParen, .str = ")"},
162 TokenMapping{.type = TokenType::LBrace, .str = "{"},
163 TokenMapping{.type = TokenType::RBrace, .str = "}"},
164 TokenMapping{.type = TokenType::LBracket, .str = "["},
165 TokenMapping{.type = TokenType::RBracket, .str = "]"},
166 TokenMapping{.type = TokenType::Comma, .str = ","},
167 TokenMapping{.type = TokenType::Dot, .str = "."},
168 TokenMapping{.type = TokenType::Semicolon, .str = ";"},
169};
170
171inline std::string token_type_to_string(TokenType type) {
172 if (const auto* it = std::ranges::find_if(
174 [type](const auto& mapping) { return mapping.type == type; });
175 it != TOKEN_MAPPINGS.end()) {
176 return std::string(it->str);
177 }
178 // Handle special cases not in the table
179 switch (type) {
180 case TokenType::Identifier:
181 return "identifier";
183 return "number";
184 case TokenType::Global:
185 return "global declaration";
186 case TokenType::Newline:
187 return "newline";
188 case TokenType::Semicolon:
189 return "semicolon";
190 case TokenType::EndOfFile:
191 return "end of file";
192 case TokenType::Invalid:
193 return "invalid token";
194 default:
195 std::unreachable();
196 }
197}
198
199struct Token {
201 std::string value;
203};
204
205enum class Mode : std::uint8_t { Expr, Single, VkExpr };
206
207enum class GlobalMode : std::uint8_t { None, All, Specific };
208
210 std::string name;
212};
213
215 std::string name;
216 std::vector<ParameterInfo> params;
221 std::set<std::string> specific_globals;
222
223 // For <global.all>, track which global variables are actually used in the function body
224 std::set<std::string> used_globals;
225};
226
227template <FixedString Prefix>
228inline std::optional<int> get_index_with_prefix(const std::string& s) {
229 if (!s.starts_with(Prefix.view())) {
230 return std::nullopt;
231 }
232 auto idx_str = s.substr(Prefix.view().size());
233 if (idx_str.empty()) {
234 return std::nullopt;
235 }
236
237 if (!std::ranges::all_of(idx_str,
238 [](char c) { return std::isdigit(c) != 0; })) {
239 return std::nullopt;
240 }
241
242 int idx = 0;
243 const char* begin = idx_str.data();
244 const char* end = begin + static_cast<std::ptrdiff_t>(idx_str.size());
245 auto res = std::from_chars(begin, end, idx);
246 if (res.ec != std::errc{} || res.ptr != end) {
247 return std::nullopt;
248 }
249 return idx;
250}
251
252template <FixedString Prefix> inline bool is_name(const std::string& s) {
253 return get_index_with_prefix<Prefix>(s).has_value();
254}
255
256inline std::optional<int> get_clip_index(const std::string& s) {
257 if (s.length() == 1 && s[0] >= 'a' && s[0] <= 'z') {
258 return parse_std_clip_idx(s[0]);
259 }
260 return get_index_with_prefix<FixedString{"src"}>(s);
261}
262
263inline bool is_clip_name(const std::string& s) {
264 return get_clip_index(s).has_value();
265}
266
267inline std::optional<int> get_buffer_index(const std::string& s) {
268 return get_index_with_prefix<FixedString{"buf"}>(s);
269}
270
271inline bool is_buffer_name(const std::string& s) {
272 return is_name<FixedString{"buf"}>(s);
273}
274
275} // namespace infix2postfix
276
277#endif // LLVMEXPR_FRONTEND_INFIX2POSTFIX_TYPES_HPP
constexpr int parse_std_clip_idx(char c)
std::optional< int > get_buffer_index(const std::string &s)
Definition types.hpp:267
bool is_clip_name(const std::string &s)
Definition types.hpp:263
bool is_buffer_name(const std::string &s)
Definition types.hpp:271
std::string token_type_to_string(TokenType type)
Definition types.hpp:171
std::optional< int > get_clip_index(const std::string &s)
Definition types.hpp:256
constexpr std::array TOKEN_MAPPINGS
Definition types.hpp:126
std::optional< int > get_index_with_prefix(const std::string &s)
Definition types.hpp:228
bool is_name(const std::string &s)
Definition types.hpp:252
std::set< std::string > specific_globals
Definition types.hpp:221
std::set< std::string > used_globals
Definition types.hpp:224
std::vector< ParameterInfo > params
Definition types.hpp:216
SourceLocation end
Definition types.hpp:48
std::string to_string() const
Definition types.hpp:51
SourceLocation start
Definition types.hpp:47
std::string_view str
Definition types.hpp:123
std::string value
Definition types.hpp:201