Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef FORMULA_FUNCTION_HPP_INCLUDED
00018 #define FORMULA_FUNCTION_HPP_INCLUDED
00019
00020 #include "formula.hpp"
00021 #include "formula_callable.hpp"
00022
00023 namespace game_logic {
00024
00025 class formula_expression {
00026 public:
00027 formula_expression() : name_("") {}
00028 virtual ~formula_expression() {}
00029 variant evaluate(const formula_callable& variables, formula_debugger *fdb = NULL) const {
00030 call_stack_manager manager(name_);
00031 if (fdb!=NULL) {
00032 return evaluate_arg_callback(*fdb,*this,variables);
00033 } else {
00034 return execute(variables,fdb);
00035 }
00036 }
00037 void set_name(const char* name) { name_ = name; }
00038
00039 const char* get_name() const { return name_; }
00040 virtual std::string str() const = 0;
00041 private:
00042 virtual variant execute(const formula_callable& variables, formula_debugger *fdb = NULL) const = 0;
00043 const char* name_;
00044 friend class formula_debugger;
00045 };
00046
00047 typedef boost::shared_ptr<formula_expression> expression_ptr;
00048
00049 class function_expression : public formula_expression {
00050 public:
00051 typedef std::vector<expression_ptr> args_list;
00052 explicit function_expression(
00053 const std::string& name,
00054 const args_list& args,
00055 int min_args=-1, int max_args=-1)
00056 : name_(name), args_(args)
00057 {
00058 set_name(name.c_str());
00059 if(min_args >= 0 && args_.size() < static_cast<size_t>(min_args)) {
00060 throw formula_error("Too few arguments", "", "", 0);
00061 }
00062
00063 if(max_args >= 0 && args_.size() > static_cast<size_t>(max_args)) {
00064 throw formula_error("Too many arguments", "", "", 0);
00065 }
00066 }
00067 virtual std::string str() const;
00068 protected:
00069 const args_list& args() const { return args_; }
00070 private:
00071 std::string name_;
00072 args_list args_;
00073 };
00074
00075 class key_value_pair : public formula_callable {
00076 variant key_;
00077 variant value_;
00078
00079 variant get_value(const std::string& key) const;
00080
00081 void get_inputs(std::vector<game_logic::formula_input>* inputs) const;
00082 public:
00083 explicit key_value_pair(const variant& key, const variant& value) : key_(key), value_(value) {}
00084 };
00085
00086 class formula_function_expression : public function_expression {
00087 public:
00088 explicit 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);
00089 private:
00090 variant execute(const formula_callable& variables, formula_debugger *fdb) const;
00091 const_formula_ptr formula_;
00092 const_formula_ptr precondition_;
00093 std::vector<std::string> arg_names_;
00094 int star_arg_;
00095 };
00096
00097 typedef boost::shared_ptr<function_expression> function_expression_ptr;
00098
00099 class formula_function {
00100 std::string name_;
00101 const_formula_ptr formula_;
00102 const_formula_ptr precondition_;
00103 std::vector<std::string> args_;
00104 public:
00105 formula_function() :
00106 name_(),
00107 formula_(),
00108 precondition_(),
00109 args_()
00110 {
00111 }
00112
00113 formula_function(const std::string& name, const_formula_ptr formula, const_formula_ptr precondition, const std::vector<std::string>& args) : name_(name), formula_(formula), precondition_(precondition), args_(args)
00114 {}
00115
00116 function_expression_ptr generate_function_expression(const std::vector<expression_ptr>& args) const;
00117 };
00118
00119 class function_symbol_table {
00120 std::map<std::string, formula_function> custom_formulas_;
00121 public:
00122 function_symbol_table() :
00123 custom_formulas_()
00124 {
00125 }
00126
00127 virtual ~function_symbol_table() {}
00128 virtual void add_formula_function(const std::string& name, const_formula_ptr formula, const_formula_ptr precondition, const std::vector<std::string>& args);
00129 virtual expression_ptr create_function(const std::string& fn,
00130 const std::vector<expression_ptr>& args) const;
00131 std::vector<std::string> get_function_names() const;
00132 };
00133
00134 expression_ptr create_function(const std::string& fn,
00135 const std::vector<expression_ptr>& args,
00136 const function_symbol_table* symbols);
00137 std::vector<std::string> builtin_function_names();
00138
00139
00140 class wrapper_formula : public formula_expression {
00141 public:
00142 wrapper_formula()
00143 : arg_()
00144 {
00145 }
00146
00147 wrapper_formula(expression_ptr arg)
00148 : arg_(arg)
00149 {
00150 }
00151
00152 virtual ~wrapper_formula()
00153 {
00154 }
00155
00156 virtual std::string str() const
00157 {
00158 if (arg_) {
00159 return arg_->str();
00160 } else {
00161 return "";
00162 }
00163 }
00164 private:
00165 virtual variant execute(const formula_callable& variables, formula_debugger *fdb = NULL) const
00166 {
00167 if (arg_) {
00168 return arg_->evaluate(variables,fdb);
00169 } else {
00170 return variant();
00171 }
00172 }
00173 expression_ptr arg_;
00174 };
00175
00176 }
00177
00178 #endif