The Battle for Wesnoth  1.19.5+dev
function.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2024
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 
24 namespace 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 {
65 public:
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 
93 private:
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 
100 typedef std::shared_ptr<formula_expression> expression_ptr;
101 
103 {
104 public:
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 
122 protected:
123  const args_list& args() const
124  {
125  return args_;
126  }
127 
128 private:
130 };
131 
133 {
134 public:
135  explicit key_value_pair(const variant& key, const variant& value)
136  : key_(key)
137  , value_(value)
138  {
139  }
140 
141  void serialize_to_string(std::string& str) const override;
142 
143 private:
146 
147  variant get_value(const std::string& key) const override;
148 
149  void get_inputs(formula_input_vector& inputs) const override;
150 };
151 
153 {
154 public:
155  explicit formula_function_expression(const std::string& name,
156  const args_list& args,
158  const_formula_ptr precondition,
159  const std::vector<std::string>& arg_names);
160 
161 private:
162  variant execute(const formula_callable& variables, formula_debugger* fdb) const;
163 
166 
167  std::vector<std::string> arg_names_;
168 
170 };
171 
172 typedef std::shared_ptr<function_expression> function_expression_ptr;
173 
175 {
176 public:
177  formula_function(const std::string name)
178  : name_(name)
179  {
180  }
181 
182  virtual function_expression_ptr generate_function_expression(const std::vector<expression_ptr>& args) const = 0;
183 
185  {
186  }
187 
188 protected:
189  std::string name_;
190 };
191 
193 {
194 public:
195  user_formula_function(const std::string& name,
197  const_formula_ptr precondition,
198  const std::vector<std::string>& args)
199  : formula_function(name)
200  , formula_(formula)
201  , precondition_(precondition)
202  , args_(args)
203  {
204  }
205 
206  function_expression_ptr generate_function_expression(const std::vector<expression_ptr>& args) const;
207 
208 private:
211  std::vector<std::string> args_;
212 };
213 
214 template<typename T>
216 {
217 public:
218  builtin_formula_function(const std::string& name)
219  : formula_function(name)
220  {
221  }
222 
223  function_expression_ptr generate_function_expression(const std::vector<expression_ptr>& args) const
224  {
225  return std::make_shared<T>(args);
226  }
227 };
228 
229 typedef std::shared_ptr<formula_function> formula_function_ptr;
230 typedef std::map<std::string, formula_function_ptr> functions_map;
231 
233 {
234 public:
235  explicit function_symbol_table(std::shared_ptr<function_symbol_table> parent = nullptr);
236 
237  void add_function(const std::string& name, formula_function_ptr&& fcn);
238 
239  expression_ptr create_function(const std::string& fn, const std::vector<expression_ptr>& args) const;
240 
241  std::set<std::string> get_function_names() const;
242 
243  bool empty() const
244  {
245  return custom_formulas_.empty() && (parent == nullptr || parent->empty());
246  }
247 
248  static std::shared_ptr<function_symbol_table> get_builtins();
249 
250 private:
251  std::shared_ptr<function_symbol_table> parent;
253 
256  {
257  }
258 };
259 
261 {
262 public:
263  action_function_symbol_table(std::shared_ptr<function_symbol_table> parent = nullptr);
264 };
265 
267 {
268 public:
270  : arg_()
271  {
272  }
273 
275  : formula_expression(arg ? arg->get_name() : "")
276  , arg_(arg)
277  {
278  }
279 
281  {
282  }
283 
284  virtual std::string str() const
285  {
286  if(arg_) {
287  return arg_->str();
288  } else {
289  return "";
290  }
291  }
292 
293 private:
294  virtual variant execute(const formula_callable& variables, formula_debugger* fdb = nullptr) const
295  {
296  if(arg_) {
297  return arg_->evaluate(variables, fdb);
298  } else {
299  return variant();
300  }
301  }
302 
304 };
305 } // end namespace wfl
Class that manages AIs for all sides and manages AI redeployment.
Definition: manager.hpp:111
action_function_symbol_table(std::shared_ptr< function_symbol_table > parent=nullptr)
Definition: function.cpp:1673
function_expression_ptr generate_function_expression(const std::vector< expression_ptr > &args) const
Definition: function.hpp:223
builtin_formula_function(const std::string &name)
Definition: function.hpp:218
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
formula_function_expression(const std::string &name, const args_list &args, const_formula_ptr formula, const_formula_ptr precondition, const std::vector< std::string > &arg_names)
Definition: function.cpp:1480
std::vector< std::string > arg_names_
Definition: function.hpp:167
variant execute(const formula_callable &variables, formula_debugger *fdb) const
Definition: function.cpp:1500
const_formula_ptr precondition_
Definition: function.hpp:165
formula_function(const std::string name)
Definition: function.hpp:177
virtual ~formula_function()
Definition: function.hpp:184
virtual function_expression_ptr generate_function_expression(const std::vector< expression_ptr > &args) const =0
const args_list & args() const
Definition: function.hpp:123
virtual std::string str() const
Definition: function.cpp:73
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()
Definition: function.cpp:1587
expression_ptr create_function(const std::string &fn, const std::vector< expression_ptr > &args) const
Definition: function.cpp:1555
void add_function(const std::string &name, formula_function_ptr &&fcn)
Definition: function.cpp:1550
std::set< std::string > get_function_names() const
Definition: function.cpp:1573
std::shared_ptr< function_symbol_table > parent
Definition: function.hpp:251
function_symbol_table(builtins_tag_t)
Definition: function.hpp:255
functions_map custom_formulas_
Definition: function.hpp:252
function_symbol_table(std::shared_ptr< function_symbol_table > parent=nullptr)
Definition: function.cpp:1545
key_value_pair(const variant &key, const variant &value)
Definition: function.hpp:135
void serialize_to_string(std::string &str) const override
Definition: function.cpp:1471
variant get_value(const std::string &key) const override
Definition: function.cpp:1454
void get_inputs(formula_input_vector &inputs) const override
Definition: function.cpp:1465
function_expression_ptr generate_function_expression(const std::vector< expression_ptr > &args) const
Definition: function.cpp:1539
const_formula_ptr precondition_
Definition: function.hpp:210
user_formula_function(const std::string &name, const_formula_ptr formula, const_formula_ptr precondition, const std::vector< std::string > &args)
Definition: function.hpp:195
const_formula_ptr formula_
Definition: function.hpp:209
std::vector< std::string > args_
Definition: function.hpp:211
virtual variant execute(const formula_callable &variables, formula_debugger *fdb=nullptr) const
Definition: function.hpp:294
virtual std::string str() const
Definition: function.hpp:284
virtual ~wrapper_formula()
Definition: function.hpp:280
wrapper_formula(expression_ptr arg)
Definition: function.hpp:274
expression_ptr arg_
Definition: function.hpp:303
Definition: contexts.hpp:43
std::vector< formula_input > formula_input_vector
std::shared_ptr< const formula > const_formula_ptr
Definition: formula_fwd.hpp:24
std::shared_ptr< formula_expression > expression_ptr
Definition: formula.hpp:29
std::map< std::string, formula_function_ptr > functions_map
Definition: function.hpp:230
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:172
std::shared_ptr< formula_function > formula_function_ptr
Definition: function.hpp:229
Provides debugging information for error messages.
Definition: function.hpp:54
call_stack_manager(const std::string &str)
Definition: function.cpp:51
static std::string get()
Definition: function.cpp:61
call_stack_manager & operator=(const call_stack_manager &)=delete
call_stack_manager(const call_stack_manager &)=delete