The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
function.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2008 - 2025
3 by David White <dave@whitevine.net>
4 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY.
12
13 See the COPYING file for more details.
14*/
15
16#pragma once
17
18#include "formula/callable.hpp"
19#include "formula/formula.hpp"
20
21#include <set>
22#include <string>
23
24namespace wfl
25{
26/** Helper macro to declare an associated class for a WFL function. */
27#define DEFINE_WFL_FUNCTION(name, min_args, max_args) \
28 class name##_function : public function_expression \
29 { \
30 public: \
31 explicit name##_function(const args_list& args) \
32 : function_expression(#name, args, min_args, max_args) \
33 { \
34 } \
35 \
36 private: \
37 variant execute(const formula_callable& variables, formula_debugger* fdb) const; \
38 }; \
39 \
40 variant name##_function::execute( \
41 [[maybe_unused]] const formula_callable& variables, [[maybe_unused]] formula_debugger* fdb) const
42
43/**
44 * Declares a function `name` in the local function table `functions_table`.
45 * The function must be defined by a `name_function` class which is accessible in the current scope.
46 */
47#define DECLARE_WFL_FUNCTION(name) \
48 functions_table.add_function(#name, std::make_shared<builtin_formula_function<name##_function>>(#name))
49
50/**
51 * Provides debugging information for error messages.
52 */
54{
55 explicit call_stack_manager(const std::string& str);
59
60 static std::string get();
61};
62
64{
65public:
66 explicit formula_expression(const std::string& name = "")
67 : name_(name)
68 {
69 }
70
72 {
73 }
74
75 variant evaluate(const formula_callable& variables, formula_debugger* fdb = nullptr) const
76 {
78
79 if(fdb != nullptr) {
80 return evaluate_arg_callback(*fdb, *this, variables);
81 } else {
82 return execute(variables, fdb);
83 }
84 }
85
86 std::string get_name() const
87 {
88 return name_;
89 }
90
91 virtual std::string str() const = 0;
92
93private:
94 virtual variant execute(const formula_callable& variables, formula_debugger* fdb = nullptr) const = 0;
95
96 const std::string name_;
97 friend class formula_debugger;
98};
99
100typedef std::shared_ptr<formula_expression> expression_ptr;
101
103{
104public:
105 typedef std::vector<expression_ptr> args_list;
106
107 explicit function_expression(const std::string& name, const args_list& args, int min_args = -1, int max_args = -1)
108 : formula_expression(name)
109 , args_(args)
110 {
111 if(min_args >= 0 && args_.size() < static_cast<std::size_t>(min_args)) {
112 throw formula_error("Too few arguments", "", "", 0);
113 }
114
115 if(max_args >= 0 && args_.size() > static_cast<std::size_t>(max_args)) {
116 throw formula_error("Too many arguments", "", "", 0);
117 }
118 }
119
120 virtual std::string str() const;
121
122protected:
123 const args_list& args() const
124 {
125 return args_;
126 }
127
128private:
130};
131
133{
134public:
135 explicit key_value_pair(const variant& key, const variant& value)
136 : key_(key)
137 , value_(value)
138 {
139 }
140
141 /** Inherited from formula_callable */
142 std::string serialize_to_string() const override;
143
144private:
147
148 variant get_value(const std::string& key) const override;
149
150 void get_inputs(formula_input_vector& inputs) const override;
151};
152
154{
155public:
156 explicit formula_function_expression(const std::string& name,
157 const args_list& args,
159 const_formula_ptr precondition,
160 const std::vector<std::string>& arg_names);
161
162private:
163 variant execute(const formula_callable& variables, formula_debugger* fdb) const;
164
167
168 std::vector<std::string> arg_names_;
169
171};
172
173typedef std::shared_ptr<function_expression> function_expression_ptr;
174
176{
177public:
178 formula_function(const std::string name)
179 : name_(name)
180 {
181 }
182
183 virtual function_expression_ptr generate_function_expression(const std::vector<expression_ptr>& args) const = 0;
184
186 {
187 }
188
189protected:
190 std::string name_;
191};
192
194{
195public:
196 user_formula_function(const std::string& name,
198 const_formula_ptr precondition,
199 const std::vector<std::string>& args)
200 : formula_function(name)
202 , precondition_(precondition)
203 , args_(args)
204 {
205 }
206
207 function_expression_ptr generate_function_expression(const std::vector<expression_ptr>& args) const;
208
209private:
212 std::vector<std::string> args_;
213};
214
215template<typename T>
217{
218public:
219 builtin_formula_function(const std::string& name)
220 : formula_function(name)
221 {
222 }
223
224 function_expression_ptr generate_function_expression(const std::vector<expression_ptr>& args) const
225 {
226 return std::make_shared<T>(args);
227 }
228};
229
230typedef std::shared_ptr<formula_function> formula_function_ptr;
231typedef std::map<std::string, formula_function_ptr> functions_map;
232
234{
235public:
236 explicit function_symbol_table(const std::shared_ptr<function_symbol_table>& parent = nullptr);
237
238 void add_function(const std::string& name, formula_function_ptr&& fcn);
239
240 expression_ptr create_function(const std::string& fn, const std::vector<expression_ptr>& args) const;
241
242 std::set<std::string> get_function_names() const;
243
244 bool empty() const
245 {
246 return custom_formulas_.empty() && (parent == nullptr || parent->empty());
247 }
248
249 static std::shared_ptr<function_symbol_table> get_builtins();
250
251private:
252 std::shared_ptr<function_symbol_table> parent;
254
259};
260
262{
263public:
264 action_function_symbol_table(const std::shared_ptr<function_symbol_table>& parent = nullptr);
265};
266
268{
269public:
271 : arg_()
272 {
273 }
274
276 : formula_expression(arg ? arg->get_name() : "")
277 , arg_(arg)
278 {
279 }
280
282 {
283 }
284
285 virtual std::string str() const
286 {
287 if(arg_) {
288 return arg_->str();
289 } else {
290 return "";
291 }
292 }
293
294private:
295 virtual variant execute(const formula_callable& variables, formula_debugger* fdb = nullptr) const
296 {
297 if(arg_) {
298 return arg_->evaluate(variables, fdb);
299 } else {
300 return variant();
301 }
302 }
303
305};
306} // end namespace wfl
function_expression_ptr generate_function_expression(const std::vector< expression_ptr > &args) const
Definition function.hpp:224
builtin_formula_function(const std::string &name)
Definition function.hpp:219
formula_input_vector inputs() const
Definition callable.hpp:63
std::string get_name() const
Definition function.hpp:86
const std::string name_
Definition function.hpp:96
virtual std::string str() const =0
virtual variant execute(const formula_callable &variables, formula_debugger *fdb=nullptr) const =0
variant evaluate(const formula_callable &variables, formula_debugger *fdb=nullptr) const
Definition function.hpp:75
virtual ~formula_expression()
Definition function.hpp:71
formula_expression(const std::string &name="")
Definition function.hpp:66
std::vector< std::string > arg_names_
Definition function.hpp:168
variant execute(const formula_callable &variables, formula_debugger *fdb) const
const_formula_ptr precondition_
Definition function.hpp:166
formula_function(const std::string name)
Definition function.hpp:178
virtual ~formula_function()
Definition function.hpp:185
virtual function_expression_ptr generate_function_expression(const std::vector< expression_ptr > &args) const =0
virtual std::string str() const
Definition function.cpp:75
const args_list & args() const
Definition function.hpp:123
std::vector< expression_ptr > args_list
Definition function.hpp:105
function_expression(const std::string &name, const args_list &args, int min_args=-1, int max_args=-1)
Definition function.hpp:107
static std::shared_ptr< function_symbol_table > get_builtins()
expression_ptr create_function(const std::string &fn, const std::vector< expression_ptr > &args) const
void add_function(const std::string &name, formula_function_ptr &&fcn)
std::set< std::string > get_function_names() const
std::shared_ptr< function_symbol_table > parent
Definition function.hpp:252
function_symbol_table(builtins_tag_t)
Definition function.hpp:256
functions_map custom_formulas_
Definition function.hpp:253
key_value_pair(const variant &key, const variant &value)
Definition function.hpp:135
std::string serialize_to_string() const override
Inherited from formula_callable.
variant get_value(const std::string &key) const override
void get_inputs(formula_input_vector &inputs) const override
function_expression_ptr generate_function_expression(const std::vector< expression_ptr > &args) const
const_formula_ptr precondition_
Definition function.hpp:211
user_formula_function(const std::string &name, const_formula_ptr formula, const_formula_ptr precondition, const std::vector< std::string > &args)
Definition function.hpp:196
const_formula_ptr formula_
Definition function.hpp:210
std::vector< std::string > args_
Definition function.hpp:212
virtual variant execute(const formula_callable &variables, formula_debugger *fdb=nullptr) const
Definition function.hpp:295
virtual std::string str() const
Definition function.hpp:285
virtual ~wrapper_formula()
Definition function.hpp:281
wrapper_formula(expression_ptr arg)
Definition function.hpp:275
expression_ptr arg_
Definition function.hpp:304
std::vector< formula_input > formula_input_vector
std::shared_ptr< const formula > const_formula_ptr
std::shared_ptr< formula_expression > expression_ptr
Definition formula.hpp:29
std::map< std::string, formula_function_ptr > functions_map
Definition function.hpp:231
variant evaluate_arg_callback(formula_debugger &fdb, const formula_expression &expression, const formula_callable &variables)
std::shared_ptr< function_expression > function_expression_ptr
Definition function.hpp:173
std::shared_ptr< formula_function > formula_function_ptr
Definition function.hpp:230
std::unique_ptr< MIX_Audio, decltype(&MIX_DestroyAudio)> value
Definition sound.cpp:139
Provides debugging information for error messages.
Definition function.hpp:54
static std::string get()
Definition function.cpp:63
call_stack_manager(const call_stack_manager &)=delete
call_stack_manager & operator=(const call_stack_manager &)=delete