VapourSynth-llvmexpr
Loading...
Searching...
No Matches
infix2postfix Namespace Reference

Namespaces

namespace  preprocessor_detail
namespace  preprocessor
namespace  detail
namespace  stdlib

Classes

struct  Diagnostic
class  AnalysisEngine
struct  NumberExpr
struct  VariableExpr
struct  UnaryExpr
struct  BinaryExpr
struct  TernaryExpr
struct  CallExpr
struct  PropAccessExpr
struct  StaticRelPixelAccessExpr
struct  FrameDimensionExpr
struct  ArrayAccessExpr
struct  ExprStmt
struct  AssignStmt
struct  ArrayAssignStmt
struct  BlockStmt
struct  IfStmt
struct  WhileStmt
struct  ReturnStmt
struct  LabelStmt
struct  GotoStmt
struct  GlobalDecl
struct  Parameter
struct  FunctionDef
struct  Expr
struct  Stmt
struct  Program
struct  is_variant_member
struct  is_variant_member< T, std::variant< Types... > >
struct  NodeWrapper
class  ASTPrinter
struct  BuiltinFunction
class  CodeGenError
class  CodeGenerator
struct  OverloadCandidate
struct  ErrorInfo
struct  ParseResult
class  Parser
class  PostfixBuilder
class  PreprocessorError
struct  MacroExpansion
struct  LineMapping
struct  MacroDefinition
struct  PreprocessResult
class  Preprocessor
class  SemanticAnalyzer
class  StandardLibraryManager
struct  Symbol
class  SymbolTable
class  Tokenizer
struct  SourceLocation
struct  Range
struct  TokenMapping
struct  Token
struct  ParameterInfo
struct  FunctionSignature
struct  ExportedFunction

Typedefs

template<typename T>
using node_wrapper_t = typename NodeWrapper<T>::type
using Token = preprocessor_detail::Token
using TokenType = preprocessor_detail::TokenType
using PreprocessorTokenizer = preprocessor_detail::PreprocessorTokenizer
using AllStandardLibraries
template<IsLibrary Lib>
using ResolveLibraryDependencies

Enumerations

enum class  DiagnosticSeverity : std::uint8_t { Error , Warning }
enum class  PostfixMode : std::uint8_t { Expr , SingleExpr }
enum class  SymbolKind : std::uint8_t { Variable , Function , Parameter , Label }
enum class  Type : std::uint8_t {
  Value , Clip , Literal , LiteralString ,
  Array , Void
}
enum class  TokenType : std::uint8_t {
  If , Else , While , Goto ,
  Function , Return , Plus , Minus ,
  Star , Slash , Percent , StarStar ,
  LogicalAnd , LogicalOr , BitAnd , BitOr ,
  BitXor , BitNot , Eq , Ne ,
  Lt , Le , Gt , Ge ,
  Assign , Question , Colon , Not ,
  LParen , RParen , LBrace , RBrace ,
  LBracket , RBracket , Comma , Dot ,
  Semicolon , Identifier , Number , Global ,
  Newline , EndOfFile , Invalid
}
enum class  Mode : std::uint8_t { Expr , Single , VkExpr }
enum class  GlobalMode : std::uint8_t { None , All , Specific }

Functions

template<typename T, typename... Args>
auto make_node (Args &&... args)
template<typename T, typename Wrapper>
auto get_if (Wrapper *wrapper) -> decltype(std::get_if< T >(&wrapper->value))
const std::map< std::string, std::vector< BuiltinFunction > > & get_builtin_functions ()
bool is_convertible (Type from, Type to, Mode mode)
template<typename T>
const OverloadCandidate< T > * select_best_candidate (std::vector< OverloadCandidate< T > > &candidates)
template<typename T>
bool is_ambiguous (const std::vector< OverloadCandidate< T > > &candidates, const OverloadCandidate< T > *best)
template<typename T, typename ArgTypeGetter, typename ParamTypeGetter>
std::vector< OverloadCandidate< T > > compute_candidates (const std::vector< T > &overloads, size_t arg_count, ArgTypeGetter get_arg_type, ParamTypeGetter get_param_type, Mode mode)
int compute_postfix_stack_effect (const std::string &postfix_expr, PostfixMode mode, int line, int num_inputs, int num_intermediate_inputs)
std::string token_type_to_string (TokenType type)
template<FixedString Prefix>
std::optional< int > get_index_with_prefix (const std::string &s)
template<FixedString Prefix>
bool is_name (const std::string &s)
std::optional< int > get_clip_index (const std::string &s)
bool is_clip_name (const std::string &s)
std::optional< int > get_buffer_index (const std::string &s)
bool is_buffer_name (const std::string &s)

Variables

template<class T, class V>
constexpr bool IS_VARIANT_MEMBER_V = is_variant_member<T, V>::value
constexpr std::array TOKEN_MAPPINGS

Detailed Description

Copyright (C) 2025 yuygfgg

This file is part of Vapoursynth-llvmexpr.

Vapoursynth-llvmexpr is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

Vapoursynth-llvmexpr is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with Vapoursynth-llvmexpr. If not, see https://www.gnu.org/licenses/.

Typedef Documentation

◆ AllStandardLibraries

Initial value:
std::tuple<stdlib::Algorithms, stdlib::Meta, stdlib::Std>

Definition at line 39 of file StandardLibrary.hpp.

◆ node_wrapper_t

template<typename T>
using infix2postfix::node_wrapper_t = typename NodeWrapper<T>::type

Definition at line 435 of file AST.hpp.

◆ PreprocessorTokenizer

◆ ResolveLibraryDependencies

template<IsLibrary Lib>
using infix2postfix::ResolveLibraryDependencies
Initial value:

Definition at line 97 of file StandardLibrary.hpp.

◆ Token

using infix2postfix::Token = preprocessor_detail::Token

Definition at line 484 of file Preprocessor.cpp.

◆ TokenType

Enumeration Type Documentation

◆ DiagnosticSeverity

enum class infix2postfix::DiagnosticSeverity : std::uint8_t
strong
Enumerator
Error 
Warning 

Definition at line 33 of file AnalysisEngine.hpp.

◆ GlobalMode

enum class infix2postfix::GlobalMode : std::uint8_t
strong
Enumerator
None 
All 
Specific 

Definition at line 207 of file types.hpp.

◆ Mode

enum class infix2postfix::Mode : std::uint8_t
strong
Enumerator
Expr 
Single 
VkExpr 

Definition at line 205 of file types.hpp.

205: std::uint8_t { Expr, Single, VkExpr };

◆ PostfixMode

enum class infix2postfix::PostfixMode : std::uint8_t
strong
Enumerator
Expr 
SingleExpr 

Definition at line 28 of file PostfixHelper.hpp.

28 : std::uint8_t {
29 Expr,
31};

◆ SymbolKind

enum class infix2postfix::SymbolKind : std::uint8_t
strong
Enumerator
Variable 
Function 
Parameter 
Label 

Definition at line 33 of file Symbol.hpp.

◆ TokenType

enum class infix2postfix::TokenType : std::uint8_t
strong
Enumerator
If 
Else 
While 
Goto 
Function 
Return 
Plus 
Minus 
Star 
Slash 
Percent 
StarStar 
LogicalAnd 
LogicalOr 
BitAnd 
BitOr 
BitXor 
BitNot 
Eq 
Ne 
Lt 
Le 
Gt 
Ge 
Assign 
Question 
Colon 
Not 
LParen 
RParen 
LBrace 
RBrace 
LBracket 
RBracket 
Comma 
Dot 
Semicolon 
Identifier 
Number 
Global 
Newline 
EndOfFile 
Invalid 

Definition at line 66 of file types.hpp.

66 : 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, // **
82 LogicalAnd, // &&
83 LogicalOr, // ||
84 BitAnd, // &
85 BitOr, // |
86 BitXor, // ^
87 BitNot, // ~
88 Eq, // ==
89 Ne, // !=
90 Lt, // <
91 Le, // <=
92 Gt, // >
93 Ge, // >=
94 Assign, // =
95 Question, // ?
96 Colon, // :
97 Not, // !
98
99 // Punctuation
100 LParen, // (
101 RParen, // )
102 LBrace, // {
103 RBrace, // }
104 LBracket, // [
105 RBracket, // ]
106 Comma, // ,
107 Dot, // .
108 Semicolon, // ;
109
110 // Literals
112 Number,
113
114 // Special
115 Global, // <global...>
116 Newline,
117 EndOfFile,
118 Invalid,
119};

◆ Type

enum class infix2postfix::Type : std::uint8_t
strong
Enumerator
Value 
Clip 
Literal 
LiteralString 
Array 
Void 

Definition at line 57 of file types.hpp.

Function Documentation

◆ compute_candidates()

template<typename T, typename ArgTypeGetter, typename ParamTypeGetter>
std::vector< OverloadCandidate< T > > infix2postfix::compute_candidates ( const std::vector< T > & overloads,
size_t arg_count,
ArgTypeGetter get_arg_type,
ParamTypeGetter get_param_type,
Mode mode )

Definition at line 84 of file OverloadResolution.hpp.

86 {
87 std::vector<OverloadCandidate<T>> candidates;
88
89 for (const auto& item : overloads) {
90 int conversion_count = 0;
91 int first_conversion_index = -1;
92 bool possible = true;
93
94 for (size_t j = 0; j < arg_count; ++j) {
95 std::optional<Type> arg_type_opt = get_arg_type(item, j);
96 std::optional<Type> param_type_opt = get_param_type(item, j);
97
98 if (!arg_type_opt.has_value() || !param_type_opt.has_value()) {
99 possible = false;
100 break;
101 }
102
103 Type arg_type = arg_type_opt.value();
104 Type param_type = param_type_opt.value();
105
106 if (arg_type != param_type) {
107 if (is_convertible(arg_type, param_type, mode)) {
108 conversion_count++;
109 if (first_conversion_index == -1) {
110 first_conversion_index = static_cast<int>(j);
111 }
112 } else {
113 possible = false;
114 break;
115 }
116 }
117 }
118
119 if (possible) {
120 candidates.push_back(
121 {&item, conversion_count, first_conversion_index});
122 }
123 }
124
125 return candidates;
126}
bool is_convertible(Type from, Type to, Mode mode)

References is_convertible().

◆ compute_postfix_stack_effect()

int infix2postfix::compute_postfix_stack_effect ( const std::string & postfix_expr,
PostfixMode mode,
int line,
int num_inputs,
int num_intermediate_inputs )

Definition at line 28 of file PostfixHelper.cpp.

30 {
32 if (mode == PostfixMode::Expr) {
33 expr_mode = (num_intermediate_inputs > 0) ? ::ExprMode::VkExpr
34 : ::ExprMode::Expr;
35 }
36
37 std::vector<::Token> tokens;
38 try {
39 tokens = ::tokenize(postfix_expr, num_inputs, expr_mode,
40 num_intermediate_inputs);
41 } catch (const std::exception& e) {
42 throw std::runtime_error(
43 std::format("Line {}: Failed to tokenize postfix expression: {}",
44 line, e.what()));
45 }
46
47 int stack = 0;
48 for (const auto& token : tokens) {
49 ::TokenBehavior behavior = ::get_token_behavior(token);
50 stack += behavior.stack_effect;
51 if (stack < 0) {
52 throw std::runtime_error(
53 std::format("Line {}: Stack underflow while processing '{}'",
54 line, token.text));
55 }
56 }
57 return stack;
58}
std::vector< Token > tokenize(const std::string &expr, int num_inputs, ExprMode mode, int num_intermediate_inputs)
TokenBehavior get_token_behavior(const Token &token)
ExprMode

References Expr, Expr, get_token_behavior(), SingleExpr, TokenBehavior::stack_effect, tokenize(), and VkExpr.

◆ get_buffer_index()

std::optional< int > infix2postfix::get_buffer_index ( const std::string & s)
inline

Definition at line 267 of file types.hpp.

267 {
268 return get_index_with_prefix<FixedString{"buf"}>(s);
269}
std::optional< int > get_index_with_prefix(const std::string &s)
Definition types.hpp:228

References get_index_with_prefix().

◆ get_builtin_functions()

const std::map< std::string, std::vector< BuiltinFunction > > & infix2postfix::get_builtin_functions ( )

Definition at line 400 of file Builtins.cpp.

400 {
401 return builtin_functions;
402}

◆ get_clip_index()

std::optional< int > infix2postfix::get_clip_index ( const std::string & s)
inline

Definition at line 256 of file types.hpp.

256 {
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}
constexpr int parse_std_clip_idx(char c)

References get_index_with_prefix(), and parse_std_clip_idx().

Referenced by is_clip_name().

◆ get_if()

template<typename T, typename Wrapper>
auto infix2postfix::get_if ( Wrapper * wrapper) -> decltype(std::get_if< T >(&wrapper->value))

Definition at line 442 of file AST.hpp.

442 {
443 if (!wrapper) {
444 return nullptr;
445 }
446 return std::get_if<T>(&wrapper->value);
447}

Referenced by infix2postfix::SemanticAnalyzer::analyze().

◆ get_index_with_prefix()

template<FixedString Prefix>
std::optional< int > infix2postfix::get_index_with_prefix ( const std::string & s)
inline

Definition at line 228 of file types.hpp.

228 {
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}

Referenced by get_buffer_index(), get_clip_index(), and is_name().

◆ is_ambiguous()

template<typename T>
bool infix2postfix::is_ambiguous ( const std::vector< OverloadCandidate< T > > & candidates,
const OverloadCandidate< T > * best )

Definition at line 68 of file OverloadResolution.hpp.

69 {
70 if (!best || candidates.size() <= 1) {
71 return false;
72 }
73
74 int count = 0;
75 count = std::ranges::count_if(candidates, [best](const auto& cand) {
76 return cand.conversion_count == best->conversion_count &&
77 cand.first_conversion_index == best->first_conversion_index;
78 });
79 return count > 1;
80}

References infix2postfix::OverloadCandidate< T >::conversion_count, and infix2postfix::OverloadCandidate< T >::first_conversion_index.

◆ is_buffer_name()

bool infix2postfix::is_buffer_name ( const std::string & s)
inline

Definition at line 271 of file types.hpp.

271 {
272 return is_name<FixedString{"buf"}>(s);
273}
bool is_name(const std::string &s)
Definition types.hpp:252

References is_name().

◆ is_clip_name()

bool infix2postfix::is_clip_name ( const std::string & s)
inline

Definition at line 263 of file types.hpp.

263 {
264 return get_clip_index(s).has_value();
265}
std::optional< int > get_clip_index(const std::string &s)
Definition types.hpp:256

References get_clip_index().

◆ is_convertible()

bool infix2postfix::is_convertible ( Type from,
Type to,
Mode mode )
inline

Definition at line 31 of file OverloadResolution.hpp.

31 {
32 if (from == Type::Void) {
33 return false;
34 }
35 return from == to || (to == Type::Value && from != Type::LiteralString &&
36 from != Type::Array &&
37 (mode != Mode::Single || from != Type::Clip));
38}

References Array, Clip, LiteralString, Single, Value, and Void.

Referenced by compute_candidates().

◆ is_name()

template<FixedString Prefix>
bool infix2postfix::is_name ( const std::string & s)
inline

Definition at line 252 of file types.hpp.

252 {
253 return get_index_with_prefix<Prefix>(s).has_value();
254}

References get_index_with_prefix().

Referenced by is_buffer_name().

◆ make_node()

template<typename T, typename... Args>
auto infix2postfix::make_node ( Args &&... args)

Definition at line 437 of file AST.hpp.

437 {
438 return std::make_unique<node_wrapper_t<T>>(T(std::forward<Args>(args)...));
439}

◆ select_best_candidate()

template<typename T>
const OverloadCandidate< T > * infix2postfix::select_best_candidate ( std::vector< OverloadCandidate< T > > & candidates)

Definition at line 48 of file OverloadResolution.hpp.

48 {
49 if (candidates.empty()) {
50 return nullptr;
51 }
52
53 OverloadCandidate<T>* best = candidates.data();
54 for (size_t i = 1; i < candidates.size(); ++i) {
55 if (candidates[i].conversion_count < best->conversion_count) {
56 best = &candidates[i];
57 } else if (candidates[i].conversion_count == best->conversion_count) {
58 if (candidates[i].first_conversion_index >
59 best->first_conversion_index) {
60 best = &candidates[i];
61 }
62 }
63 }
64 return best;
65}

References infix2postfix::OverloadCandidate< T >::conversion_count, and infix2postfix::OverloadCandidate< T >::first_conversion_index.

◆ token_type_to_string()

std::string infix2postfix::token_type_to_string ( TokenType type)
inline

Definition at line 171 of file types.hpp.

171 {
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}
constexpr std::array TOKEN_MAPPINGS
Definition types.hpp:126

References Number, and TOKEN_MAPPINGS.

Variable Documentation

◆ IS_VARIANT_MEMBER_V

template<class T, class V>
bool infix2postfix::IS_VARIANT_MEMBER_V = is_variant_member<T, V>::value
inlineconstexpr

Definition at line 425 of file AST.hpp.

◆ TOKEN_MAPPINGS

std::array infix2postfix::TOKEN_MAPPINGS
constexpr

Definition at line 126 of file types.hpp.

126 {
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};

Referenced by token_type_to_string().