diff --git a/src/gfx/generated_image.cpp b/src/gfx/generated_image.cpp index 16dc9fbf..ecbe77e7 100644 --- a/src/gfx/generated_image.cpp +++ b/src/gfx/generated_image.cpp @@ -374,7 +374,7 @@ Image BuiltInImage::generate(const Options& opt) const { // TODO : use opt.width and opt.height? Image img = load_resource_image(name); if (!img.Ok()) { - throw ScriptError(_("There is no build in image '") + name + _("'")); + throw ScriptError(_("There is no built in image '") + name + _("'")); } return img; } diff --git a/src/script/context.cpp b/src/script/context.cpp index 1296d191..bac67cbf 100644 --- a/src/script/context.cpp +++ b/src/script/context.cpp @@ -12,8 +12,6 @@ #include #include -DECLARE_TYPEOF_COLLECTION(pair); - // ----------------------------------------------------------------------------- : Context Context::Context() @@ -290,41 +288,6 @@ class ScriptCompose : public ScriptValue { ScriptValueP a,b; }; -// ----------------------------------------------------------------------------- : Closures - -/// A closure around a function -class ScriptClosure : public ScriptValue { - public: - ScriptClosure(ScriptValueP fun) : fun(fun) {} - - /// Add a binding - void bind(Variable v, const ScriptValueP& value) { - bindings.push_back(make_pair(v,value)); - } - /// Apply the bindings - void applyBindings(Context& ctx) const { - FOR_EACH_CONST(b, bindings) { - if (ctx.getVariableScope(b.first) != 0) { - ctx.setVariable(b.first, b.second); - } - } - } - - virtual ScriptType type() const { return SCRIPT_FUNCTION; } - virtual String typeName() const { return _("function closure"); } - virtual ScriptValueP eval(Context& ctx) const { - applyBindings(ctx); - return fun->eval(ctx); - } - virtual ScriptValueP dependencies(Context& ctx, const Dependency& dep) const { - applyBindings(ctx); - return fun->dependencies(ctx, dep); - } - private: - ScriptValueP fun; - vector > bindings; -}; - // ----------------------------------------------------------------------------- : Simple instructions : binary // operator on ints @@ -459,11 +422,14 @@ void Context::makeObject(size_t n) { void Context::makeClosure(size_t n, const Instruction*& instr) { intrusive_ptr closure(new ScriptClosure(stack[stack.size() - n - 1])); for (size_t j = 0 ; j < n ; ++j) { - closure->bind((Variable)instr[n - j - 1].data, stack.back()); + closure->addBinding((Variable)instr[n - j - 1].data, stack.back()); stack.pop_back(); } // skip arguments instr += n; - // set value - stack.back() = closure; + // set value, try to simplify + stack.back() = closure->simplify(); + if (!stack.back()) { + stack.back() = closure; + } } diff --git a/src/script/functions/basic.cpp b/src/script/functions/basic.cpp index fec66ef1..6608a76d 100644 --- a/src/script/functions/basic.cpp +++ b/src/script/functions/basic.cpp @@ -611,9 +611,18 @@ ScriptValueP match_rule(Context& ctx) { SCRIPT_FUNCTION(match_rule) { return match_rule(ctx); } -SCRIPT_FUNCTION(match) { +SCRIPT_FUNCTION_WITH_SIMPLIFY(match) { return match_rule(ctx)->eval(ctx); } +SCRIPT_FUNCTION_SIMPLIFY_CLOSURE(match) { + ScriptValueP match = closure.getBinding(SCRIPT_VAR_match); + if (match) { + intrusive_ptr ret(new ScriptMatchRule); + from_script(match, ret->regex); + return ret; + } + return ScriptValueP(); +} // ----------------------------------------------------------------------------- : Rules : sort text diff --git a/src/script/functions/functions.hpp b/src/script/functions/functions.hpp index 4983c680..660cc1c2 100644 --- a/src/script/functions/functions.hpp +++ b/src/script/functions/functions.hpp @@ -26,7 +26,7 @@ void init_script_editor_functions(Context& ctx); void init_script_export_functions(Context& ctx); void init_script_english_functions(Context& ctx); -/// Initialize all build in functions for a context +/// Initialize all built in functions for a context inline void init_script_functions(Context& ctx) { init_script_basic_functions(ctx); init_script_image_functions(ctx); diff --git a/src/script/functions/util.hpp b/src/script/functions/util.hpp index 4abddb30..6f453f8c 100644 --- a/src/script/functions/util.hpp +++ b/src/script/functions/util.hpp @@ -42,20 +42,27 @@ SCRIPT_FUNCTION_AUX(name, virtual ScriptValueP dependencies(Context&, const Dependency&) const;) #define SCRIPT_FUNCTION_DEPENDENCIES(name) \ - ScriptValueP ScriptBuildin_##name::dependencies(Context& ctx, const Dependency& dep) const + ScriptValueP ScriptBuiltIn_##name::dependencies(Context& ctx, const Dependency& dep) const + +/// Macro to declare a new script function with custom closure simplification +#define SCRIPT_FUNCTION_WITH_SIMPLIFY(name) \ + SCRIPT_FUNCTION_AUX(name, virtual ScriptValueP simplifyClosure(ScriptClosure&) const;) + +#define SCRIPT_FUNCTION_SIMPLIFY_CLOSURE(name) \ + ScriptValueP ScriptBuiltIn_##name::simplifyClosure(ScriptClosure& closure) const // helper for SCRIPT_FUNCTION and SCRIPT_FUNCTION_DEP #define SCRIPT_FUNCTION_AUX(name,dep) \ - class ScriptBuildin_##name : public ScriptValue { \ + class ScriptBuiltIn_##name : public ScriptValue { \ dep \ virtual ScriptType type() const \ { return SCRIPT_FUNCTION; } \ virtual String typeName() const \ - { return _("build in function '") _(#name) _("'"); } \ + { return _("built-in function '") _(#name) _("'"); } \ virtual ScriptValueP eval(Context&) const; \ }; \ - ScriptValueP script_##name(new ScriptBuildin_##name); \ - ScriptValueP ScriptBuildin_##name::eval(Context& ctx) const + ScriptValueP script_##name(new ScriptBuiltIn_##name); \ + ScriptValueP ScriptBuiltIn_##name::eval(Context& ctx) const /// Return a value from a SCRIPT_FUNCTION #define SCRIPT_RETURN(value) return to_script(value) diff --git a/src/script/to_value.hpp b/src/script/to_value.hpp index b8e20944..f5607d1d 100644 --- a/src/script/to_value.hpp +++ b/src/script/to_value.hpp @@ -10,6 +10,7 @@ // ----------------------------------------------------------------------------- : Includes #include