Author: dragonking
Date: Fri Apr 11 00:11:46 2008
New Revision: 25741

URL: http://svn.gna.org/viewcvs/wesnoth?rev=25741&view=rev
Log:
Added new formula functions: 
keys() and values()
Added support for [] operator, examples:
[1, 2, 3][0] returns 1,
{'elf' -> 1, 'orc' -> 2}['orc'] returns 2

Modified:
    trunk/src/formula.cpp
    trunk/src/formula_function.cpp
    trunk/src/variant.cpp
    trunk/src/variant.hpp

Modified: trunk/src/formula.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/formula.cpp?rev=25741&r1=25740&r2=25741&view=diff
==============================================================================
--- trunk/src/formula.cpp (original)
+++ trunk/src/formula.cpp Fri Apr 11 00:11:46 2008
@@ -215,6 +215,26 @@
        }
 
        expression_ptr left_, right_;
+};
+
+class square_bracket_expression : public formula_expression { //TODO
+public:
+       square_bracket_expression(expression_ptr left, expression_ptr key)
+          : left_(left), key_(key)
+       {}
+private:
+       variant execute(const formula_callable& variables) const {
+               const variant left = left_->evaluate(variables);
+               const variant key = key_->evaluate(variables);
+               if(left.is_list() || left.is_map()) {
+                       return left[ key ];
+               } else {
+                       std::cerr << "illegal usage of operator []'\n";
+                       throw formula_error();
+               }
+       }
+
+       expression_ptr left_, key_;
 };
 
 class operator_expression : public formula_expression {
@@ -491,9 +511,9 @@
        int parens = 0;
        const token* beg = i1;
        while(i1 != i2) {
-               if(i1->type == TOKEN_LPARENS || i1->type == TOKEN_LSQUARE) {
+               if(i1->type == TOKEN_LPARENS || i1->type == TOKEN_LSQUARE || 
i1->type == TOKEN_LBRACKET ) {
                        ++parens;
-               } else if(i1->type == TOKEN_RPARENS || i1->type == 
TOKEN_RSQUARE) {
+               } else if(i1->type == TOKEN_RPARENS || i1->type == 
TOKEN_RSQUARE || i1->type == TOKEN_RBRACKET) {
                        --parens;
                } else if(i1->type == TOKEN_COMMA && !parens) {
                        res->push_back(parse_expression(beg,i1, symbols));
@@ -653,11 +673,24 @@
        if(op == NULL) {
                if(i1->type == TOKEN_LPARENS && (i2-1)->type == TOKEN_RPARENS) {
                        return parse_expression(i1+1,i2-1,symbols);
-               } else if(i1->type == TOKEN_LSQUARE && (i2-1)->type == 
TOKEN_RSQUARE) {
-                               //create a list
-                               std::vector<expression_ptr> args;
-                               parse_args(i1+1,i2-1,&args,symbols);
-                               return expression_ptr(new 
list_expression(args));
+               } else if( (i2-1)->type == TOKEN_RSQUARE) { //check if there is 
[ ] : either a list definition, or a operator 
+                               const token* tok = i2-2;
+                               while (tok->type != TOKEN_LSQUARE && tok != i1) 
{
+                                               --tok;
+                               }       
+                               if (tok->type == TOKEN_LSQUARE) {
+                                       if (tok == i1) {
+                                               //create a list
+                                               std::vector<expression_ptr> 
args;
+                                               
parse_args(i1+1,i2-1,&args,symbols);
+                                               return expression_ptr(new 
list_expression(args));
+                                       } else {
+                                               //execute operator [ ]
+                                               return expression_ptr(new 
square_bracket_expression(
+                                                                               
        parse_expression(i1,tok,symbols),
+                                                                               
                parse_expression(tok+1,i2-1,symbols)));
+                                       }
+                               }
                } else if(i1->type == TOKEN_LBRACKET && (i2-1)->type == 
TOKEN_RBRACKET) {
                                //create a map TODO: add support for a set
                                std::vector<expression_ptr> args;

Modified: trunk/src/formula_function.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/formula_function.cpp?rev=25741&r1=25740&r2=25741&view=diff
==============================================================================
--- trunk/src/formula_function.cpp (original)
+++ trunk/src/formula_function.cpp Fri Apr 11 00:11:46 2008
@@ -256,6 +256,32 @@
                }
 
                return variant(res);
+       }
+};
+
+class keys_function : public function_expression {
+public:
+       explicit keys_function(const args_list& args)
+            : function_expression("keys", args, 1, 1)
+       {}
+
+private:
+       variant execute(const formula_callable& variables) const {
+               const variant map = args()[0]->evaluate(variables);
+               return map.get_keys();
+       }
+};
+
+class values_function : public function_expression {
+public:
+       explicit values_function(const args_list& args)
+            : function_expression("values", args, 1, 1)
+       {}
+
+private:
+       variant execute(const formula_callable& variables) const {
+               const variant map = args()[0]->evaluate(variables);
+               return map.get_values();
        }
 };
 
@@ -648,6 +674,8 @@
                FUNCTION(null);
                FUNCTION(refcount);
                FUNCTION(loc);
+               FUNCTION(keys);
+               FUNCTION(values);
 #undef FUNCTION
        }
 

Modified: trunk/src/variant.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/variant.cpp?rev=25741&r1=25740&r2=25741&view=diff
==============================================================================
--- trunk/src/variant.cpp (original)
+++ trunk/src/variant.cpp Fri Apr 11 00:11:46 2008
@@ -240,6 +240,28 @@
        }       
 }
 
+variant variant::get_keys() const
+{
+       must_be(TYPE_MAP);
+       assert(map_);
+       std::vector<variant> tmp;
+       for(std::map<variant,variant>::const_iterator i=map_->elements.begin(); 
i != map_->elements.end(); ++i) {
+                       tmp.push_back(i->first);
+       }
+       return variant(&tmp);
+}
+
+variant variant::get_values() const
+{
+       must_be(TYPE_MAP);
+       assert(map_);
+       std::vector<variant> tmp;
+       for(std::map<variant,variant>::const_iterator i=map_->elements.begin(); 
i != map_->elements.end(); ++i) {
+                       tmp.push_back(i->second);
+       }
+       return variant(&tmp);
+}
+
 size_t variant::num_elements() const
 {
        if(type_ == TYPE_CALLABLE) {

Modified: trunk/src/variant.hpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/variant.hpp?rev=25741&r1=25740&r2=25741&view=diff
==============================================================================
--- trunk/src/variant.hpp (original)
+++ trunk/src/variant.hpp Fri Apr 11 00:11:46 2008
@@ -102,6 +102,9 @@
        bool operator<=(const variant&) const;
        bool operator>=(const variant&) const;
 
+       variant get_keys() const;
+       variant get_values() const;
+
        void serialize_to_string(std::string& str) const;
        void serialize_from_string(const std::string& str);
 


_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits

Reply via email to