From 1b2899d791d29989d6d95d126ad1dcb8a0c9c749 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Mon, 13 Jun 2022 01:52:16 +0900 Subject: [PATCH 1/5] Update `environment::evaluate` to not to dump registors Signed-off-by: yamacir-kit --- README.md | 6 +++--- VERSION | 2 +- include/meevax/kernel/machine.hpp | 20 ++++++++++++++++---- src/kernel/environment.cpp | 20 ++++++++++++-------- src/kernel/identity.cpp | 2 +- src/kernel/syntax.cpp | 2 +- 6 files changed, 34 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 72bba3ebb..9d5472e7d 100644 --- a/README.md +++ b/README.md @@ -103,9 +103,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.59.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.60.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.59_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.60_amd64.deb`. | `install` | Copy files into `/usr/local` __(1)__. | `install.deb` | `all` + `package` + `sudo apt install .deb` | `safe-install.deb` | `all` + `test` + `package` + `sudo apt install .deb` @@ -120,7 +120,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.59 +Meevax Lisp System, version 0.4.60 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index b7c7a484a..de41f35ea 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.59 +0.4.60 diff --git a/include/meevax/kernel/machine.hpp b/include/meevax/kernel/machine.hpp index a00662782..f86aa2896 100644 --- a/include/meevax/kernel/machine.hpp +++ b/include/meevax/kernel/machine.hpp @@ -471,16 +471,23 @@ inline namespace kernel * ------------------------------------------------------------------- */ [this]() { - auto && [current_expression, current_scope] = unpair(cadr(c)); + auto [current_expression, current_scope] = unpair(cadr(c)); + + let const syntactic_environment = fork(cdr(current_scope)); + + let const c_ = c; for (let const& keyword_ : car(current_scope)) { let & binding = keyword_.as().load(); - binding = make(environment(static_cast(*this)).execute(binding), - fork(cdr(current_scope))); + c = binding; + + binding = make(execute(), syntactic_environment); } + c = c_; + std::swap(c.as(), compile(context(), static_cast(*this), @@ -699,8 +706,13 @@ inline namespace kernel return [this]() { assert(cdr(s).template is()); + assert(cdr(c).template is()); + let const x = car(s); - s = unit; + + s = cdr(s); + c = cdr(c); + return x; }(); } diff --git a/src/kernel/environment.cpp b/src/kernel/environment.cpp index e6697b516..0f73e3b4a 100644 --- a/src/kernel/environment.cpp +++ b/src/kernel/environment.cpp @@ -33,6 +33,8 @@ inline namespace kernel auto environment::apply(const_reference f, const_reference xs) -> lvalue { + assert(f.is() or f.is() or f.is()); + auto dump = std::make_tuple(std::exchange(s, list(f, xs)), std::exchange(e, unit), std::exchange(c, list(make(mnemonic::call), @@ -124,10 +126,12 @@ inline namespace kernel } else { - auto dump = std::make_tuple(std::exchange(s, unit), - std::exchange(e, unit), - std::exchange(c, compile(context(), *this, expression, scope())), - std::exchange(d, unit)); + assert(s.is()); + assert(e.is()); + assert(c.is()); + assert(d.is()); + + c = compile(context(), *this, expression, scope()); if (debug) { @@ -136,10 +140,10 @@ inline namespace kernel let const result = execute(); - s = std::get<0>(dump); - e = std::get<1>(dump); - c = std::get<2>(dump); - d = std::get<3>(dump); + assert(s.is()); + assert(e.is()); + assert(c.is()); + assert(d.is()); return result; } diff --git a/src/kernel/identity.cpp b/src/kernel/identity.cpp index a824472bf..fcde5f6e2 100644 --- a/src/kernel/identity.cpp +++ b/src/kernel/identity.cpp @@ -31,7 +31,7 @@ inline namespace kernel auto identity::symbol() const -> const_reference { - assert(first.is()); + assert(first.is_also()); return first; } diff --git a/src/kernel/syntax.cpp b/src/kernel/syntax.cpp index 2c3e9464b..6b9f7a763 100644 --- a/src/kernel/syntax.cpp +++ b/src/kernel/syntax.cpp @@ -22,7 +22,7 @@ inline namespace kernel { syntax::syntax(std::string const& name, function_type const& compile) : description { name } - , compile { compile } + , compile { compile } {} auto operator <<(std::ostream & os, syntax const& datum) -> std::ostream & From 842c4e07cce2106855c70697ff1c8bb35b19515a Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Mon, 13 Jun 2022 03:58:11 +0900 Subject: [PATCH 2/5] Add experimental optimization for `load-constant` Signed-off-by: yamacir-kit --- README.md | 6 +-- VERSION | 2 +- include/meevax/kernel/machine.hpp | 84 +++++++++++++++++++++++++++++++ src/kernel/environment.cpp | 2 + 4 files changed, 90 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9d5472e7d..362a571b2 100644 --- a/README.md +++ b/README.md @@ -103,9 +103,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.60.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.61.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.60_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.61_amd64.deb`. | `install` | Copy files into `/usr/local` __(1)__. | `install.deb` | `all` + `package` + `sudo apt install .deb` | `safe-install.deb` | `all` + `test` + `package` + `sudo apt install .deb` @@ -120,7 +120,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.60 +Meevax Lisp System, version 0.4.61 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index de41f35ea..45976791b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.60 +0.4.61 diff --git a/include/meevax/kernel/machine.hpp b/include/meevax/kernel/machine.hpp index f86aa2896..56dab65d6 100644 --- a/include/meevax/kernel/machine.hpp +++ b/include/meevax/kernel/machine.hpp @@ -752,6 +752,90 @@ inline namespace kernel return variable.is() ? variable.as().identify_with_offset(scope) : f; } + static auto optimize(const_reference c) -> lvalue + { + if (not c.is()) + { + return c; + } + else switch (car(c).template as()) + { + case mnemonic::call: + case mnemonic::cons: + case mnemonic::drop: + case mnemonic::dummy: + case mnemonic::join: + case mnemonic::letrec: + case mnemonic::return_: + case mnemonic::stop: + case mnemonic::tail_call: + return cons(car(c), + optimize(cdr(c))); + + case mnemonic::define: + case mnemonic::define_syntax: + case mnemonic::let_syntax: + case mnemonic::letrec_syntax: + case mnemonic::load_absolute: + case mnemonic::load_relative: + case mnemonic::load_variadic: + case mnemonic::store_absolute: + case mnemonic::store_relative: + case mnemonic::store_variadic: + return cons(car(c), + cadr(c), + optimize(cddr(c))); + + case mnemonic::load_closure: + case mnemonic::load_continuation: + return cons(car(c), + optimize(cadr(c)), + optimize(cddr(c))); + + case mnemonic::select: + case mnemonic::tail_select: + return cons(car(c), + optimize(cadr(c)), + optimize(caddr(c)), + optimize(cdddr(c))); + + + case mnemonic::load_constant: /* ----------------------------------------- + * + * (load-constant x + * load-constant y + * cons + * ...) + * + * => (load-constant (x . y) + * ...) + * + * --------------------------------------------------------------------- */ + if (5 <= length(c) and + list_ref(c, 0).is() and + list_ref(c, 0).as() == mnemonic::load_constant and + list_ref(c, 2).is() and + list_ref(c, 2).as() == mnemonic::load_constant and + list_ref(c, 4).is() and + list_ref(c, 4).as() == mnemonic::cons) + { + return optimize(cons(list_ref(c, 0), cons(list_ref(c, 3), + list_ref(c, 1)), + optimize(list_tail(c, 5)))); + } + else + { + return cons(car(c), cadr(c), + optimize(cddr(c))); + } + + default: + assert(false); + return c; + } + } + + [[deprecated]] inline auto reset() -> void { s = unit; diff --git a/src/kernel/environment.cpp b/src/kernel/environment.cpp index 0f73e3b4a..60b22e459 100644 --- a/src/kernel/environment.cpp +++ b/src/kernel/environment.cpp @@ -133,6 +133,8 @@ inline namespace kernel c = compile(context(), *this, expression, scope()); + c = optimize(c); + if (debug) { disassemble(debug_port().as(), c); From 66536229efa8594b95f3a31e10d55f121478ea21 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Tue, 14 Jun 2022 01:56:53 +0900 Subject: [PATCH 3/5] Update `optimize` to reuse given code Signed-off-by: yamacir-kit --- README.md | 6 +-- VERSION | 2 +- include/meevax/kernel/machine.hpp | 68 ++++++++++++++++++++++++------- 3 files changed, 58 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 362a571b2..e9670df89 100644 --- a/README.md +++ b/README.md @@ -103,9 +103,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.61.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.62.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.61_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.62_amd64.deb`. | `install` | Copy files into `/usr/local` __(1)__. | `install.deb` | `all` + `package` + `sudo apt install .deb` | `safe-install.deb` | `all` + `test` + `package` + `sudo apt install .deb` @@ -120,7 +120,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.61 +Meevax Lisp System, version 0.4.62 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 45976791b..73de7f980 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.61 +0.4.62 diff --git a/include/meevax/kernel/machine.hpp b/include/meevax/kernel/machine.hpp index 56dab65d6..8f94be28c 100644 --- a/include/meevax/kernel/machine.hpp +++ b/include/meevax/kernel/machine.hpp @@ -769,8 +769,17 @@ inline namespace kernel case mnemonic::return_: case mnemonic::stop: case mnemonic::tail_call: - return cons(car(c), - optimize(cdr(c))); + return [&]() + { + if (let const& continuation = optimize(cdr(c)); continuation == cdr(c)) + { + return c; + } + else + { + return cons(car(c), continuation); + } + }(); case mnemonic::define: case mnemonic::define_syntax: @@ -782,22 +791,50 @@ inline namespace kernel case mnemonic::store_absolute: case mnemonic::store_relative: case mnemonic::store_variadic: - return cons(car(c), - cadr(c), - optimize(cddr(c))); + return [&]() + { + if (let const& continuation = optimize(cddr(c)); continuation == cddr(c)) + { + return c; + } + else + { + return cons(car(c), cadr(c), continuation); + } + }(); case mnemonic::load_closure: case mnemonic::load_continuation: - return cons(car(c), - optimize(cadr(c)), - optimize(cddr(c))); + return [&]() + { + if (let const& branch = optimize(cadr(c)), + continuation = optimize(cddr(c)); + branch == cadr(c) and continuation == cddr(c)) + { + return c; + } + else + { + return cons(car(c), branch, continuation); + } + }(); case mnemonic::select: case mnemonic::tail_select: - return cons(car(c), - optimize(cadr(c)), - optimize(caddr(c)), - optimize(cdddr(c))); + return [&]() + { + if (let const& consequent = optimize(cadr(c)), + alternate = optimize(caddr(c)), + continuation = optimize(cdddr(c)); + consequent == cadr(c) and alternate == caddr(c) and continuation == cdddr(c)) + { + return c; + } + else + { + return cons(car(c), consequent, alternate, continuation); + } + }(); case mnemonic::load_constant: /* ----------------------------------------- @@ -823,10 +860,13 @@ inline namespace kernel list_ref(c, 1)), optimize(list_tail(c, 5)))); } + else if (let const& continuation = optimize(cddr(c)); continuation == cddr(c)) + { + return c; + } else { - return cons(car(c), cadr(c), - optimize(cddr(c))); + return cons(car(c), cadr(c), continuation); } default: From 4879c442b3b9b4cf6007a526311eaade1db000e9 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Tue, 14 Jun 2022 02:43:41 +0900 Subject: [PATCH 4/5] Add new struct `optimizer` Signed-off-by: yamacir-kit --- README.md | 6 +- VERSION | 2 +- include/meevax/kernel/environment.hpp | 8 +- include/meevax/kernel/machine.hpp | 123 ------------------- include/meevax/kernel/optimizer.hpp | 168 ++++++++++++++++++++++++++ 5 files changed, 177 insertions(+), 130 deletions(-) create mode 100644 include/meevax/kernel/optimizer.hpp diff --git a/README.md b/README.md index e9670df89..4b608ef44 100644 --- a/README.md +++ b/README.md @@ -103,9 +103,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.62.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.63.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.62_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.63_amd64.deb`. | `install` | Copy files into `/usr/local` __(1)__. | `install.deb` | `all` + `package` + `sudo apt install .deb` | `safe-install.deb` | `all` + `test` + `package` + `sudo apt install .deb` @@ -120,7 +120,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.62 +Meevax Lisp System, version 0.4.63 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 73de7f980..6c75a3792 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.62 +0.4.63 diff --git a/include/meevax/kernel/environment.hpp b/include/meevax/kernel/environment.hpp index 8c7ee5d37..70142d36d 100644 --- a/include/meevax/kernel/environment.hpp +++ b/include/meevax/kernel/environment.hpp @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -28,9 +29,10 @@ inline namespace kernel { class environment : public virtual pair , public configurator - , public machine - , public reader - , public writer + , public machine + , public optimizer + , public reader + , public writer { using pair::pair; diff --git a/include/meevax/kernel/machine.hpp b/include/meevax/kernel/machine.hpp index 8f94be28c..600cfcc4e 100644 --- a/include/meevax/kernel/machine.hpp +++ b/include/meevax/kernel/machine.hpp @@ -752,129 +752,6 @@ inline namespace kernel return variable.is() ? variable.as().identify_with_offset(scope) : f; } - static auto optimize(const_reference c) -> lvalue - { - if (not c.is()) - { - return c; - } - else switch (car(c).template as()) - { - case mnemonic::call: - case mnemonic::cons: - case mnemonic::drop: - case mnemonic::dummy: - case mnemonic::join: - case mnemonic::letrec: - case mnemonic::return_: - case mnemonic::stop: - case mnemonic::tail_call: - return [&]() - { - if (let const& continuation = optimize(cdr(c)); continuation == cdr(c)) - { - return c; - } - else - { - return cons(car(c), continuation); - } - }(); - - case mnemonic::define: - case mnemonic::define_syntax: - case mnemonic::let_syntax: - case mnemonic::letrec_syntax: - case mnemonic::load_absolute: - case mnemonic::load_relative: - case mnemonic::load_variadic: - case mnemonic::store_absolute: - case mnemonic::store_relative: - case mnemonic::store_variadic: - return [&]() - { - if (let const& continuation = optimize(cddr(c)); continuation == cddr(c)) - { - return c; - } - else - { - return cons(car(c), cadr(c), continuation); - } - }(); - - case mnemonic::load_closure: - case mnemonic::load_continuation: - return [&]() - { - if (let const& branch = optimize(cadr(c)), - continuation = optimize(cddr(c)); - branch == cadr(c) and continuation == cddr(c)) - { - return c; - } - else - { - return cons(car(c), branch, continuation); - } - }(); - - case mnemonic::select: - case mnemonic::tail_select: - return [&]() - { - if (let const& consequent = optimize(cadr(c)), - alternate = optimize(caddr(c)), - continuation = optimize(cdddr(c)); - consequent == cadr(c) and alternate == caddr(c) and continuation == cdddr(c)) - { - return c; - } - else - { - return cons(car(c), consequent, alternate, continuation); - } - }(); - - - case mnemonic::load_constant: /* ----------------------------------------- - * - * (load-constant x - * load-constant y - * cons - * ...) - * - * => (load-constant (x . y) - * ...) - * - * --------------------------------------------------------------------- */ - if (5 <= length(c) and - list_ref(c, 0).is() and - list_ref(c, 0).as() == mnemonic::load_constant and - list_ref(c, 2).is() and - list_ref(c, 2).as() == mnemonic::load_constant and - list_ref(c, 4).is() and - list_ref(c, 4).as() == mnemonic::cons) - { - return optimize(cons(list_ref(c, 0), cons(list_ref(c, 3), - list_ref(c, 1)), - optimize(list_tail(c, 5)))); - } - else if (let const& continuation = optimize(cddr(c)); continuation == cddr(c)) - { - return c; - } - else - { - return cons(car(c), cadr(c), continuation); - } - - default: - assert(false); - return c; - } - } - [[deprecated]] inline auto reset() -> void { diff --git a/include/meevax/kernel/optimizer.hpp b/include/meevax/kernel/optimizer.hpp new file mode 100644 index 000000000..f10466acb --- /dev/null +++ b/include/meevax/kernel/optimizer.hpp @@ -0,0 +1,168 @@ +/* + Copyright 2018-2022 Tatsuya Yamasaki. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef INCLUDED_MEEVAX_KERNEL_OPTIMIZER_HPP +#define INCLUDED_MEEVAX_KERNEL_OPTIMIZER_HPP + +#include + +namespace meevax +{ +inline namespace kernel +{ + struct optimizer + { + static inline auto fmerge_constants = true; + + static auto merge_constants(const_reference c) -> lvalue + { + if (not c.is()) + { + return c; + } + else switch (car(c).template as()) + { + case mnemonic::call: + case mnemonic::cons: + case mnemonic::drop: + case mnemonic::dummy: + case mnemonic::join: + case mnemonic::letrec: + case mnemonic::return_: + case mnemonic::stop: + case mnemonic::tail_call: + return [&]() + { + if (let const& continuation = merge_constants(cdr(c)); continuation == cdr(c)) + { + return c; + } + else + { + return cons(car(c), continuation); + } + }(); + + case mnemonic::define: + case mnemonic::define_syntax: + case mnemonic::let_syntax: + case mnemonic::letrec_syntax: + case mnemonic::load_absolute: + case mnemonic::load_relative: + case mnemonic::load_variadic: + case mnemonic::store_absolute: + case mnemonic::store_relative: + case mnemonic::store_variadic: + return [&]() + { + if (let const& continuation = merge_constants(cddr(c)); continuation == cddr(c)) + { + return c; + } + else + { + return cons(car(c), cadr(c), continuation); + } + }(); + + case mnemonic::load_closure: + case mnemonic::load_continuation: + return [&]() + { + if (let const& branch = merge_constants(cadr(c)), + continuation = merge_constants(cddr(c)); + branch == cadr(c) and continuation == cddr(c)) + { + return c; + } + else + { + return cons(car(c), branch, continuation); + } + }(); + + case mnemonic::select: + case mnemonic::tail_select: + return [&]() + { + if (let const& consequent = merge_constants(cadr(c)), + alternate = merge_constants(caddr(c)), + continuation = merge_constants(cdddr(c)); + consequent == cadr(c) and alternate == caddr(c) and continuation == cdddr(c)) + { + return c; + } + else + { + return cons(car(c), consequent, alternate, continuation); + } + }(); + + + case mnemonic::load_constant: /* ----------------------------------------- + * + * (load-constant x + * load-constant y + * cons + * ...) + * + * => (load-constant (x . y) + * ...) + * + * --------------------------------------------------------------------- */ + if (5 <= length(c) and + list_ref(c, 0).is() and + list_ref(c, 0).as() == mnemonic::load_constant and + list_ref(c, 2).is() and + list_ref(c, 2).as() == mnemonic::load_constant and + list_ref(c, 4).is() and + list_ref(c, 4).as() == mnemonic::cons) + { + return merge_constants(cons(list_ref(c, 0), cons(list_ref(c, 3), + list_ref(c, 1)), + merge_constants(list_tail(c, 5)))); + } + else if (let const& continuation = merge_constants(cddr(c)); continuation == cddr(c)) + { + return c; + } + else + { + return cons(car(c), cadr(c), continuation); + } + + default: + assert(false); + return c; + } + } + + static auto optimize(const_reference c) + { + let code = c; + + if (fmerge_constants) + { + code = merge_constants(code); + } + + return code; + } + }; +} // namespace kernel +} // namespace meevax + +#endif // INCLUDED_MEEVAX_KERNEL_OPTIMIZER_HPP From 9af5e561a259a9b3b46ebfbf2b852ca7783fe885 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Tue, 14 Jun 2022 03:03:10 +0900 Subject: [PATCH 5/5] Simplify instruction `tail_call` Signed-off-by: yamacir-kit --- README.md | 6 ++-- VERSION | 2 +- include/meevax/kernel/machine.hpp | 49 ++++++++----------------------- 3 files changed, 16 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 4b608ef44..a9e0bbf9f 100644 --- a/README.md +++ b/README.md @@ -103,9 +103,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.63.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.64.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.63_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.64_amd64.deb`. | `install` | Copy files into `/usr/local` __(1)__. | `install.deb` | `all` + `package` + `sudo apt install .deb` | `safe-install.deb` | `all` + `test` + `package` + `sudo apt install .deb` @@ -120,7 +120,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.63 +Meevax Lisp System, version 0.4.64 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 6c75a3792..96b9b226d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.63 +0.4.64 diff --git a/include/meevax/kernel/machine.hpp b/include/meevax/kernel/machine.hpp index 600cfcc4e..afddfdad7 100644 --- a/include/meevax/kernel/machine.hpp +++ b/include/meevax/kernel/machine.hpp @@ -533,66 +533,40 @@ inline namespace kernel }(); goto decode; - case mnemonic::call: + case mnemonic::tail_call: if (let const& callee = car(s); callee.is()) /* --------------- * - * ( xs . s) e (%call . c) d => () (xs . e') c' (s e c . d) + * ( xs . s) e (%tail-call . c) d => () (xs . e') c' d * * where = (c' . e') * * ------------------------------------------------------------------- */ { - d = cons(cddr(s), e, cdr(c), d); c = callee.as().c(); e = cons(cadr(s), callee.as().e()); s = unit; + goto decode; } - else if (callee.is_also()) /* ------------------------------- - * - * ( xs . s) e (%call . c) d => (x . s) e c d - * - * where x = procedure(xs) - * - * ------------------------------------------------------------------- */ - { - s = cons(callee.as().call(cadr(s)), cddr(s)); - c = cdr(c); - } - else if (callee.is()) /* --------------------------------- - * - * ( xs . s) e (%call . c) d => (xs . s') e' c' d' - * - * where = (s' e' c' . 'd) - * - * ------------------------------------------------------------------- */ - { - s = cons(caadr(s), callee.as().s()); - e = callee.as().e(); - c = callee.as().c(); - d = callee.as().d(); - } - else - { - throw error(make("not applicable"), callee); - } - goto decode; + [[fallthrough]]; // This is inefficient because the type check occurs twice, but currently the performance difference caused by this is too small. - case mnemonic::tail_call: + case mnemonic::call: if (let const& callee = car(s); callee.is()) /* --------------- * - * ( xs . s) e (%tail-call . c) d => () (xs . e') c' d + * ( xs . s) e (%call . c) d => () (xs . e') c' (s e c . d) * * where = (c' . e') * * ------------------------------------------------------------------- */ { + d = cons(cddr(s), e, cdr(c), d); c = callee.as().c(); e = cons(cadr(s), callee.as().e()); s = unit; + goto decode; } else if (callee.is_also()) /* ------------------------------- * - * ( xs . s) e (%tail-call . c) d => (x . s) e c d + * ( xs . s) e (%call . c) d => (x . s) e c d * * where x = procedure(xs) * @@ -600,10 +574,11 @@ inline namespace kernel { s = cons(callee.as().call(cadr(s)), cddr(s)); c = cdr(c); + goto decode; } else if (callee.is()) /* --------------------------------- * - * ( xs . s) e (%tail-call . c) d => (xs . s') e' c' d' + * ( xs . s) e (%call . c) d => (xs . s') e' c' d' * * where = (s' e' c' . 'd) * @@ -613,12 +588,12 @@ inline namespace kernel e = callee.as().e(); c = callee.as().c(); d = callee.as().d(); + goto decode; } else { throw error(make("not applicable"), callee); } - goto decode; case mnemonic::dummy: /* ------------------------------------------------- *