Commit 187ad9ec authored by twanvl's avatar twanvl

Use closure stuff for making built in *_rule functions, simplifying the code.

parent c2af0830
...@@ -241,6 +241,19 @@ int Context::getVariableScope(Variable var) { ...@@ -241,6 +241,19 @@ int Context::getVariableScope(Variable var) {
else return -1; else return -1;
} }
ScriptValueP Context::makeClosure(const ScriptValueP& fun) {
intrusive_ptr<ScriptClosure> closure(new ScriptClosure(fun));
// we can find out which variables are in the last level by looking at shadowed
// these variables will be at the end of the list
for (size_t i = shadowed.size() - 1 ; i + 1 > 0 ; --i) {
Variable var = shadowed[i].variable;
assert(variables[var].value);
if (variables[var].level < level) break;
closure->addBinding(var, variables[var].value);
}
return closure;
}
size_t Context::openScope() { size_t Context::openScope() {
level += 1; level += 1;
......
...@@ -70,6 +70,9 @@ class Context { ...@@ -70,6 +70,9 @@ class Context {
*/ */
int getVariableScope(Variable var); int getVariableScope(Variable var);
/// Make a closure of the function with the direct parameters of the current call
ScriptValueP makeClosure(const ScriptValueP& fun);
private: private:
/// Open a new scope /// Open a new scope
......
...@@ -93,7 +93,8 @@ SCRIPT_FUNCTION(contains) { ...@@ -93,7 +93,8 @@ SCRIPT_FUNCTION(contains) {
SCRIPT_RETURN(input.find(match) != String::npos); SCRIPT_RETURN(input.find(match) != String::npos);
} }
SCRIPT_RULE_1_C(format, String, format) { SCRIPT_FUNCTION(format) {
SCRIPT_PARAM_C(String, format);
String fmt = _("%") + replace_all(format, _("%"), _("")); String fmt = _("%") + replace_all(format, _("%"), _(""));
// determine type expected by format string // determine type expected by format string
if (format.find_first_of(_("DdIiOoXx")) != String::npos) { if (format.find_first_of(_("DdIiOoXx")) != String::npos) {
...@@ -162,13 +163,16 @@ String replace_tag_contents(String input, const String& tag, const ScriptValueP& ...@@ -162,13 +163,16 @@ String replace_tag_contents(String input, const String& tag, const ScriptValueP&
} }
// Replace the contents of a specific tag // Replace the contents of a specific tag
SCRIPT_RULE_2_C(tag_contents, String, tag, ScriptValueP, contents) { SCRIPT_FUNCTION(tag_contents) {
SCRIPT_PARAM_C(String, input); SCRIPT_PARAM_C(String, input);
SCRIPT_PARAM_C(String, tag);
SCRIPT_PARAM_C(ScriptValueP, contents);
SCRIPT_RETURN(replace_tag_contents(input, tag, contents, ctx)); SCRIPT_RETURN(replace_tag_contents(input, tag, contents, ctx));
} }
SCRIPT_RULE_1_C(tag_remove, String, tag) { SCRIPT_FUNCTION(remove_tag) {
SCRIPT_PARAM_C(String, input); SCRIPT_PARAM_C(String, input);
SCRIPT_PARAM_C(String, tag);
SCRIPT_RETURN(remove_tag(input, tag)); SCRIPT_RETURN(remove_tag(input, tag));
} }
...@@ -633,53 +637,31 @@ SCRIPT_FUNCTION_SIMPLIFY_CLOSURE(match) { ...@@ -633,53 +637,31 @@ SCRIPT_FUNCTION_SIMPLIFY_CLOSURE(match) {
// ----------------------------------------------------------------------------- : Rules : sort text // ----------------------------------------------------------------------------- : Rules : sort text
// Sort using spec_sort SCRIPT_FUNCTION(sort_text) {
class ScriptRule_sort_order: public ScriptValue { SCRIPT_PARAM_C(String, input);
public: SCRIPT_OPTIONAL_PARAM_C(String, order) {
inline ScriptRule_sort_order(const String& order) : order(order) {} SCRIPT_RETURN(spec_sort(order, input));
virtual ScriptType type() const { return SCRIPT_FUNCTION; } } else {
virtual String typeName() const { return _("sort_rule"); } sort(input.begin(), input.end());
virtual ScriptValueP eval(Context& ctx) const { SCRIPT_RETURN(input);
SCRIPT_PARAM_C(ScriptValueP, input);
if (input->type() == SCRIPT_COLLECTION) {
handle_warning(_("Sorting a collection as a string, this is probably not intended, if it is use 'collection+\"\"' to force conversion"), false);
}
SCRIPT_RETURN(spec_sort(order, input->toString()));
} }
private: }
String order;
}; // ----------------------------------------------------------------------------- : Rule form
// Sort a string alphabetically
class ScriptRule_sort: public ScriptValue { /// Turn a script function into a rule, a.k.a. a delayed closure
class ScriptRule : public ScriptValue {
public: public:
inline ScriptRule(const ScriptValueP& fun) : fun(fun) {}
virtual ScriptType type() const { return SCRIPT_FUNCTION; } virtual ScriptType type() const { return SCRIPT_FUNCTION; }
virtual String typeName() const { return _("sort_rule"); } virtual String typeName() const { return fun->typeName() + _(" rule"); }
virtual ScriptValueP eval(Context& ctx) const { virtual ScriptValueP eval(Context& ctx) const {
SCRIPT_PARAM_C(ScriptValueP, input); return ctx.makeClosure(fun);
if (input->type() == SCRIPT_COLLECTION) {
handle_warning(_("Sorting a collection as a string, this is probably not intended, if it is use 'collection+\"\"' to force conversion"), false);
}
String input_str = input->toString();
sort(input_str.begin(), input_str.end());
SCRIPT_RETURN(input_str);
} }
private: private:
ScriptValueP order_by; ScriptValueP fun;
}; };
SCRIPT_FUNCTION(sort_rule) {
SCRIPT_OPTIONAL_PARAM_C(String, order) {
return new_intrusive1<ScriptRule_sort_order>(order);
}
return new_intrusive <ScriptRule_sort>();
}
SCRIPT_FUNCTION(sort_text) {
SCRIPT_OPTIONAL_PARAM_C(String, order) {
return ScriptRule_sort_order(order).eval(ctx);
}
return ScriptRule_sort().eval(ctx);
}
// ----------------------------------------------------------------------------- : Init // ----------------------------------------------------------------------------- : Init
void init_script_basic_functions(Context& ctx) { void init_script_basic_functions(Context& ctx) {
...@@ -694,15 +676,15 @@ void init_script_basic_functions(Context& ctx) { ...@@ -694,15 +676,15 @@ void init_script_basic_functions(Context& ctx) {
ctx.setVariable(_("substring"), script_substring); ctx.setVariable(_("substring"), script_substring);
ctx.setVariable(_("contains"), script_contains); ctx.setVariable(_("contains"), script_contains);
ctx.setVariable(_("format"), script_format); ctx.setVariable(_("format"), script_format);
ctx.setVariable(_("format rule"), script_format_rule); ctx.setVariable(_("format rule"), new_intrusive1<ScriptRule>(script_format));
ctx.setVariable(_("curly quotes"), script_curly_quotes); ctx.setVariable(_("curly quotes"), script_curly_quotes);
ctx.setVariable(_("regex escape"), script_regex_escape); ctx.setVariable(_("regex escape"), script_regex_escape);
// tagged string // tagged string
ctx.setVariable(_("tag contents"), script_tag_contents); ctx.setVariable(_("tag contents"), script_tag_contents);
ctx.setVariable(_("remove tag"), script_tag_remove); ctx.setVariable(_("remove tag"), script_remove_tag);
ctx.setVariable(_("remove tags"), script_remove_tags); ctx.setVariable(_("remove tags"), script_remove_tags);
ctx.setVariable(_("tag contents rule"), script_tag_contents_rule); ctx.setVariable(_("tag contents rule"), new_intrusive1<ScriptRule>(script_tag_contents));
ctx.setVariable(_("tag remove rule"), script_tag_remove_rule); ctx.setVariable(_("tag remove rule"), new_intrusive1<ScriptRule>(script_remove_tag));
// collection // collection
ctx.setVariable(_("position"), script_position_of); ctx.setVariable(_("position"), script_position_of);
ctx.setVariable(_("length"), script_length); ctx.setVariable(_("length"), script_length);
...@@ -711,7 +693,7 @@ void init_script_basic_functions(Context& ctx) { ...@@ -711,7 +693,7 @@ void init_script_basic_functions(Context& ctx) {
ctx.setVariable(_("sort list"), script_sort_list); ctx.setVariable(_("sort list"), script_sort_list);
// keyword // keyword
ctx.setVariable(_("expand keywords"), script_expand_keywords); ctx.setVariable(_("expand keywords"), script_expand_keywords);
ctx.setVariable(_("expand keywords rule"), script_expand_keywords_rule); ctx.setVariable(_("expand keywords rule"), new_intrusive1<ScriptRule>(script_expand_keywords));
ctx.setVariable(_("keyword usage"), script_keyword_usage); ctx.setVariable(_("keyword usage"), script_keyword_usage);
// advanced string rules/functions // advanced string rules/functions
ctx.setVariable(_("replace"), script_replace); ctx.setVariable(_("replace"), script_replace);
...@@ -723,5 +705,5 @@ void init_script_basic_functions(Context& ctx) { ...@@ -723,5 +705,5 @@ void init_script_basic_functions(Context& ctx) {
ctx.setVariable(_("filter rule"), script_filter_rule); ctx.setVariable(_("filter rule"), script_filter_rule);
ctx.setVariable(_("break rule"), script_break_rule); ctx.setVariable(_("break rule"), script_break_rule);
ctx.setVariable(_("match rule"), script_match_rule); ctx.setVariable(_("match rule"), script_match_rule);
ctx.setVariable(_("sort rule"), script_sort_rule); ctx.setVariable(_("sort rule"), new_intrusive1<ScriptRule>(script_sort_text));
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment