00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef FORMULA_FUNCTION_HPP_INCLUDED
00016 #define FORMULA_FUNCTION_HPP_INCLUDED
00017
00018 #include <boost/shared_ptr.hpp>
00019
00020 #include <map>
00021
00022 #include "formula.hpp"
00023 #include "variant.hpp"
00024
00025 namespace game_logic {
00026
00027 class formula_expression {
00028 public:
00029 formula_expression() : name_(NULL) {}
00030 virtual ~formula_expression() {}
00031 variant evaluate(const formula_callable& variables) const {
00032 call_stack_manager manager(name_);
00033 return execute(variables);
00034 }
00035 void set_name(const char* name) { name_ = name; }
00036 private:
00037 virtual variant execute(const formula_callable& variables) const = 0;
00038 const char* name_;
00039 };
00040
00041 typedef boost::shared_ptr<formula_expression> expression_ptr;
00042
00043 class function_expression : public formula_expression {
00044 public:
00045 typedef std::vector<expression_ptr> args_list;
00046 explicit function_expression(
00047 const std::string& name,
00048 const args_list& args,
00049 int min_args=-1, int max_args=-1)
00050 : name_(name), args_(args)
00051 {
00052 set_name(name.c_str());
00053 if(min_args >= 0 && args_.size() < static_cast<size_t>(min_args)) {
00054 std::cerr << "too few arguments\n";
00055 throw formula_error();
00056 }
00057
00058 if(max_args >= 0 && args_.size() > static_cast<size_t>(max_args)) {
00059 std::cerr << "too many arguments\n";
00060 throw formula_error();
00061 }
00062 }
00063
00064 protected:
00065 const args_list& args() const { return args_; }
00066 private:
00067 std::string name_;
00068 args_list args_;
00069 };
00070
00071 class formula_function_expression : public function_expression {
00072 public:
00073 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);
00074 private:
00075 variant execute(const formula_callable& variables) const;
00076 const_formula_ptr formula_;
00077 const_formula_ptr precondition_;
00078 std::vector<std::string> arg_names_;
00079 int star_arg_;
00080 };
00081
00082 typedef boost::shared_ptr<function_expression> function_expression_ptr;
00083
00084 class formula_function {
00085 std::string name_;
00086 const_formula_ptr formula_;
00087 const_formula_ptr precondition_;
00088 std::vector<std::string> args_;
00089 public:
00090 formula_function() {}
00091 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)
00092 {}
00093
00094 function_expression_ptr generate_function_expression(const std::vector<expression_ptr>& args) const;
00095 };
00096
00097 class function_symbol_table {
00098 std::map<std::string, formula_function> custom_formulas_;
00099 public:
00100 virtual ~function_symbol_table() {}
00101 virtual void add_formula_function(const std::string& name, const_formula_ptr formula, const_formula_ptr precondition, const std::vector<std::string>& args);
00102 virtual expression_ptr create_function(const std::string& fn,
00103 const std::vector<expression_ptr>& args) const;
00104 std::vector<std::string> get_function_names() const;
00105 };
00106
00107 expression_ptr create_function(const std::string& fn,
00108 const std::vector<expression_ptr>& args,
00109 const function_symbol_table* symbols);
00110 std::vector<std::string> builtin_function_names();
00111
00112 }
00113
00114 #endif