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