diff --git a/README.md b/README.md index cd7d2e580..a7803b7d5 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ Procedures for each standard are provided by the following R7RS-style libraries: cmake -B build -DCMAKE_BUILD_TYPE=Release cd build make package -sudo apt install build/meevax_0.5.215_amd64.deb +sudo apt install build/meevax_0.5.216_amd64.deb ``` or @@ -122,9 +122,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |-------------|------------- -| `all` | Build shared-library `libmeevax.0.5.215.so` and executable `meevax` +| `all` | Build shared-library `libmeevax.0.5.216.so` and executable `meevax` | `test` | Test executable `meevax` -| `package` | Generate debian package `meevax_0.5.215_amd64.deb` +| `package` | Generate debian package `meevax_0.5.216_amd64.deb` | `install` | Copy files into `/usr/local` directly ## Usage diff --git a/VERSION b/VERSION index 58129bae7..2b4c075c5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.5.215 +0.5.216 diff --git a/include/meevax/kernel/syntactic_environment.hpp b/include/meevax/kernel/syntactic_environment.hpp index 5ad23c2b5..262e00e5f 100644 --- a/include/meevax/kernel/syntactic_environment.hpp +++ b/include/meevax/kernel/syntactic_environment.hpp @@ -32,36 +32,31 @@ inline namespace kernel { struct syntactic_closure : public identifier { - let macro_environment, free_names, expression; + let inner_environment, free_names, expression; - explicit syntactic_closure(let const& macro_environment, + explicit syntactic_closure(let const& inner_environment, let const& free_names, let const& expression) - : macro_environment { macro_environment } + : inner_environment { inner_environment } , free_names { free_names } , expression { expression } { - assert(macro_environment.is()); + assert(inner_environment.is()); } template - auto compile(let const& use_environment, Ts&&... xs) + auto compile(let const& outer_environment, Ts&&... xs) { - assert(use_environment.is()); + assert(outer_environment.is()); - let const bound_variables = unify(car(macro_environment), - car(use_environment)); + let const bound_variables = unify(car(inner_environment), + car(outer_environment)); - let const free_variables = map([&](let const& free_name) - { - return cons(free_name, use_environment); - }, - free_names, - cdr(use_environment)); + let const free_variables = unit; - return macro_environment.as() - .generate(macro_environment.as() - .expand(expression, + return inner_environment.as() + .generate(inner_environment.as() + .expand(inject(outer_environment, free_names, expression), bound_variables, free_variables), bound_variables, @@ -69,6 +64,25 @@ inline namespace kernel std::forward(xs)...); } + static auto inject(let const& outer_environment, + let const& free_names, + let const& form) -> object + { + if (form.is()) + { + return cons(inject(outer_environment, free_names, car(form)), + inject(outer_environment, free_names, cdr(form))); + } + else if (let const& x = memq(form, free_names); x != f) + { + return make(outer_environment, unit, form); + } + else + { + return form; + } + } + friend auto operator ==(syntactic_closure const& x, syntactic_closure const& y) -> bool { /* @@ -82,13 +96,13 @@ inline namespace kernel */ return x.expression.template is_also() and y.expression.template is_also() and - eqv(x.macro_environment.template as() + eqv(x.inner_environment.template as() .identify(x.expression, - car(x.macro_environment), + car(x.inner_environment), nullptr), - y.macro_environment.template as() + y.inner_environment.template as() .identify(y.expression, - car(y.macro_environment), + car(y.inner_environment), nullptr)); } @@ -952,16 +966,6 @@ inline namespace kernel { return f; } - else if (let const& x = assq(variable, free_variables); x != f) - { - /* - If a macro transformer inserts a free reference to an identifier, - the reference refers to the binding that was visible where the - transformer was specified, regardless of any local bindings that - surround the use of the macro. - */ - return cdr(x).as().inject(car(x), bound_variables); - } else { auto i = 0; @@ -990,13 +994,13 @@ inline namespace kernel } } - if (variable.is()) + if (variable.is()) // Resolve alias { return variable.as() - .macro_environment + .inner_environment .template as() .identify(variable.as().expression, - unify(car(variable.as().macro_environment), + unify(car(variable.as().inner_environment), bound_variables), nullptr); } @@ -1042,15 +1046,6 @@ inline namespace kernel } } - inline auto inject(object const& free_variable, - object const& bound_variables) -> object - { - return identify(free_variable, - unify(first /* bound-variables */, - bound_variables), - second /* free-variables */); - } - static auto rename(std::string const& variable) { return make(core(), unit, make_symbol(variable));