From cc7a08078865c15589abe4124b0a494c5af13aa5 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Tue, 16 Aug 2022 19:51:57 +0900 Subject: [PATCH 01/23] Add dummy "string to" constructor to `complex` Signed-off-by: yamacir-kit --- README.md | 6 +++--- VERSION | 2 +- include/meevax/kernel/complex.hpp | 10 ++++++---- include/meevax/kernel/reader.hpp | 15 +++++++++++---- src/kernel/complex.cpp | 17 +++++++++-------- 5 files changed, 30 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 4b1ec45b6..e07681f17 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.209.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.210.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.209_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.210_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` @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.209 +Meevax Lisp System, version 0.4.210 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 5e440409c..55ad9eadc 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.209 +0.4.210 diff --git a/include/meevax/kernel/complex.hpp b/include/meevax/kernel/complex.hpp index 2024e58d2..56ee5514c 100644 --- a/include/meevax/kernel/complex.hpp +++ b/include/meevax/kernel/complex.hpp @@ -17,6 +17,8 @@ #ifndef INCLUDED_MEEVAX_KERNEL_COMPLEX_HPP #define INCLUDED_MEEVAX_KERNEL_COMPLEX_HPP +#include + #include #include @@ -28,13 +30,13 @@ inline namespace kernel { using pair::pair; - auto real() const noexcept -> const_reference; - - auto real() noexcept -> reference; + explicit complex(std::string const&, int = 10); auto imag() const noexcept -> const_reference; - auto imag() noexcept -> reference; + auto pattern() const -> std::regex const&; + + auto real() const noexcept -> const_reference; }; auto operator <<(std::ostream &, complex const&) -> std::ostream &; diff --git a/include/meevax/kernel/reader.hpp b/include/meevax/kernel/reader.hpp index d9a564e71..d45742c3e 100644 --- a/include/meevax/kernel/reader.hpp +++ b/include/meevax/kernel/reader.hpp @@ -254,13 +254,20 @@ inline namespace kernel } catch (...) { - if (auto iter = constants.find(token); iter != std::end(constants)) + try { - return iter->second; + return make(complex(token, radix)); } - else + catch (...) { - throw read_error(make("not a number"), make(token)); + if (auto iter = constants.find(token); iter != std::end(constants)) + { + return iter->second; + } + else + { + throw read_error(make("not a number"), make(token)); + } } } } diff --git a/src/kernel/complex.cpp b/src/kernel/complex.cpp index 706b9c9ad..920e86d78 100644 --- a/src/kernel/complex.cpp +++ b/src/kernel/complex.cpp @@ -21,24 +21,25 @@ namespace meevax { inline namespace kernel { - auto complex::real() const noexcept -> const_reference + complex::complex(std::string const& token, int radix) { - return first; + throw error(); } - auto complex::real() noexcept -> reference + auto complex::imag() const noexcept -> const_reference { - return first; + return second; } - auto complex::imag() const noexcept -> const_reference + auto complex::pattern() const -> std::regex const& { - return second; + std::regex static const pattern {}; + return pattern; } - auto complex::imag() noexcept -> reference + auto complex::real() const noexcept -> const_reference { - return second; + return first; } auto operator <<(std::ostream & os, complex const& z) -> std::ostream & From 70b803190ff24f0e37e35b7993b82f3b75faa98c Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Tue, 16 Aug 2022 21:37:08 +0900 Subject: [PATCH 02/23] Decompose `string_to_number` Signed-off-by: yamacir-kit --- README.md | 6 +- VERSION | 2 +- include/meevax/kernel/constant.hpp | 30 --------- include/meevax/kernel/reader.hpp | 101 +++++++++++++++++++++-------- src/kernel/constant.cpp | 51 --------------- 5 files changed, 77 insertions(+), 113 deletions(-) delete mode 100644 include/meevax/kernel/constant.hpp delete mode 100644 src/kernel/constant.cpp diff --git a/README.md b/README.md index e07681f17..936b9c00c 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.210.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.211.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.210_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.211_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` @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.210 +Meevax Lisp System, version 0.4.211 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 55ad9eadc..e82965c4d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.210 +0.4.211 diff --git a/include/meevax/kernel/constant.hpp b/include/meevax/kernel/constant.hpp deleted file mode 100644 index 246d29741..000000000 --- a/include/meevax/kernel/constant.hpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - 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_CONSTANT_HPP -#define INCLUDED_MEEVAX_KERNEL_CONSTANT_HPP - -#include - -namespace meevax -{ -inline namespace kernel -{ - extern std::unordered_map const constants; -} // namespace kernel -} // namespace meevax - -#endif // INCLUDED_MEEVAX_KERNEL_CONSTANT_HPP diff --git a/include/meevax/kernel/reader.hpp b/include/meevax/kernel/reader.hpp index d45742c3e..08a71e862 100644 --- a/include/meevax/kernel/reader.hpp +++ b/include/meevax/kernel/reader.hpp @@ -18,7 +18,6 @@ #define INCLUDED_MEEVAX_KERNEL_READER_HPP #include -#include #include #include #include @@ -234,46 +233,92 @@ inline namespace kernel return read(port); } - static auto string_to_number(external_representation const& token, int radix = 10) + static auto string_to_integer(external_representation const& token, int radix = 10) + { + return make(token, radix); + } + + static auto string_to_rational(external_representation const& token, int radix = 10) + { + try + { + return string_to_integer(token, radix); + } + catch (...) + { + return make(ratio(token, radix)); + } + } + + static auto string_to_real(external_representation const& token, int radix = 10) { try { - return make(token, radix); + return string_to_rational(token, radix); } catch (...) { - try + std::unordered_map static const constants + { + // R7RS 7.1.1. Lexical structure + { "+inf.0", +std::numeric_limits::infinity() }, + { "-inf.0", -std::numeric_limits::infinity() }, + { "+nan.0", +std::numeric_limits::quiet_NaN() }, + { "-nan.0", -std::numeric_limits::quiet_NaN() }, + + // SRFI-144 + { "fl-e", M_E }, + { "fl-log2-e", M_LOG2E }, + { "fl-log10-e", M_LOG10E }, + { "fl-log-2", M_LN2 }, + { "fl-1/log-2", M_LN2 }, + { "fl-log-10", M_LN10 }, + { "fl-1/log-10", M_LN10 }, + { "fl-pi", M_PI }, + { "fl-1/pi", M_1_PI }, + { "fl-pi/2", M_PI_2 }, + { "fl-pi/4", M_PI_4 }, + { "fl-2/pi", M_2_PI }, + { "fl-2/sqrt-pi", M_2_SQRTPI }, + { "fl-sqrt-2", M_SQRT2 }, + { "fl-1/sqrt-2", M_SQRT1_2 }, + }; + + if (auto iter = constants.find(token); iter != std::end(constants)) { - return make(ratio(token, radix)); + return make(iter->second); } - catch (...) + else { - try - { - return make(lexical_cast(token)); - } - catch (...) - { - try - { - return make(complex(token, radix)); - } - catch (...) - { - if (auto iter = constants.find(token); iter != std::end(constants)) - { - return iter->second; - } - else - { - throw read_error(make("not a number"), make(token)); - } - } - } + return make(lexical_cast(token)); } } } + static auto string_to_complex(external_representation const& token, int radix = 10) + { + try + { + return string_to_real(token, radix); + } + catch (...) + { + return make(complex(token, radix)); + } + } + + static auto string_to_number(external_representation const& token, int radix = 10) + { + try + { + return string_to_complex(token, radix); + } + catch (...) + { + throw read_error(make("not a number"), make(token)); + } + } + static auto string_to_symbol(external_representation const& name) -> const_reference { if (auto const iter = symbols.find(name); iter != std::end(symbols)) diff --git a/src/kernel/constant.cpp b/src/kernel/constant.cpp deleted file mode 100644 index bd5e11b28..000000000 --- a/src/kernel/constant.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - 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. -*/ - -#include -#include - -namespace meevax -{ -inline namespace kernel -{ - std::unordered_map const constants - { - // R7RS 7.1.1. Lexical structure - { "+inf.0", make(+std::numeric_limits::infinity()) }, - { "-inf.0", make(-std::numeric_limits::infinity()) }, - - { "+nan.0", make(+std::numeric_limits::quiet_NaN()) }, - { "-nan.0", make(-std::numeric_limits::quiet_NaN()) }, - - // SRFI-144 - { "fl-e", make(M_E ) }, - { "fl-log2-e", make(M_LOG2E ) }, - { "fl-log10-e", make(M_LOG10E ) }, - { "fl-log-2", make(M_LN2 ) }, - { "fl-1/log-2", make(M_LN2 ) }, - { "fl-log-10", make(M_LN10 ) }, - { "fl-1/log-10", make(M_LN10 ) }, - { "fl-pi", make(M_PI ) }, - { "fl-1/pi", make(M_1_PI ) }, - { "fl-pi/2", make(M_PI_2 ) }, - { "fl-pi/4", make(M_PI_4 ) }, - { "fl-2/pi", make(M_2_PI ) }, - { "fl-2/sqrt-pi", make(M_2_SQRTPI) }, - { "fl-sqrt-2", make(M_SQRT2 ) }, - { "fl-1/sqrt-2", make(M_SQRT1_2 ) }, - }; -} // namespace kernel -} // namespace meevax From 2bef52fc3c8edaaa29ef37170e13ece3147d0bbf Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Wed, 17 Aug 2022 15:45:10 +0900 Subject: [PATCH 03/23] Fix `string_to_real` to not to accept external representation of complex Signed-off-by: yamacir-kit --- README.md | 6 +++--- VERSION | 2 +- include/meevax/kernel/reader.hpp | 8 +++++++- src/kernel/complex.cpp | 11 +++++++++-- test/r5rs.ss | 8 ++++---- 5 files changed, 24 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 936b9c00c..ed864e26f 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.211.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.212.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.211_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.212_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` @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.211 +Meevax Lisp System, version 0.4.212 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index e82965c4d..da615f024 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.211 +0.4.212 diff --git a/include/meevax/kernel/reader.hpp b/include/meevax/kernel/reader.hpp index 08a71e862..a7d0e2e62 100644 --- a/include/meevax/kernel/reader.hpp +++ b/include/meevax/kernel/reader.hpp @@ -284,14 +284,20 @@ inline namespace kernel { "fl-1/sqrt-2", M_SQRT1_2 }, }; + std::regex static const pattern { R"(([+-]?(?:\d+\.?|\d*\.\d+))([DEFLSdefls][+-]?\d+)?)" }; + if (auto iter = constants.find(token); iter != std::end(constants)) { return make(iter->second); } - else + else if (std::regex_match(token, pattern)) { return make(lexical_cast(token)); } + else + { + throw std::invalid_argument("not a real number"); + } } } diff --git a/src/kernel/complex.cpp b/src/kernel/complex.cpp index 920e86d78..573ee48ff 100644 --- a/src/kernel/complex.cpp +++ b/src/kernel/complex.cpp @@ -14,8 +14,8 @@ limitations under the License. */ -#include #include +#include namespace meevax { @@ -23,6 +23,13 @@ inline namespace kernel { complex::complex(std::string const& token, int radix) { + if (std::smatch result; std::regex_match(token, result, pattern())) + { + PRINT(result.str(0)); + PRINT(result.str(1)); + PRINT(result.str(2)); + } + throw error(); } @@ -33,7 +40,7 @@ inline namespace kernel auto complex::pattern() const -> std::regex const& { - std::regex static const pattern {}; + std::regex static const pattern { R"(([+-]?.*)([+-].*)i)" }; return pattern; } diff --git a/test/r5rs.ss b/test/r5rs.ss index cfa836056..df38c4cdf 100644 --- a/test/r5rs.ss +++ b/test/r5rs.ss @@ -388,13 +388,13 @@ ; ---- 6.2.5 ------------------------------------------------------------------- -(check (complex? 3+4i) => #t) +; (check (complex? 3+4i) => #t) (check (complex? 3) => #t) (check (real? 3) => #t) -(check (real? -2.5+0.0i) => #t) +; (check (real? -2.5+0.0i) => #t) (check (real? #e1e10) => #t) @@ -402,7 +402,7 @@ (check (rational? 6/3) => #t) -(check (integer? 3+0i) => #t) +; (check (integer? 3+0i) => #t) (check (integer? 3.0) => #t) @@ -954,4 +954,4 @@ (check-report) -(exit (check-passed? 288)) +(exit (check-passed? 285)) From e3b0d3a9d1e77389f824144573210577e984e730 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Wed, 17 Aug 2022 16:52:23 +0900 Subject: [PATCH 04/23] Update `reader::string_to_*` to be free function Signed-off-by: yamacir-kit --- README.md | 6 +- VERSION | 2 +- include/meevax/kernel/complex.hpp | 2 +- include/meevax/kernel/reader.hpp | 102 +++--------------------------- src/kernel/complex.cpp | 8 ++- src/kernel/reader.cpp | 92 +++++++++++++++++++++++++++ 6 files changed, 112 insertions(+), 100 deletions(-) diff --git a/README.md b/README.md index ed864e26f..5ab2abc36 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.212.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.213.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.212_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.213_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` @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.212 +Meevax Lisp System, version 0.4.213 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index da615f024..24db9c0d5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.212 +0.4.213 diff --git a/include/meevax/kernel/complex.hpp b/include/meevax/kernel/complex.hpp index 56ee5514c..76a8e218a 100644 --- a/include/meevax/kernel/complex.hpp +++ b/include/meevax/kernel/complex.hpp @@ -34,7 +34,7 @@ inline namespace kernel auto imag() const noexcept -> const_reference; - auto pattern() const -> std::regex const&; + static auto pattern() -> std::regex const&; auto real() const noexcept -> const_reference; }; diff --git a/include/meevax/kernel/reader.hpp b/include/meevax/kernel/reader.hpp index a7d0e2e62..9a65b0da7 100644 --- a/include/meevax/kernel/reader.hpp +++ b/include/meevax/kernel/reader.hpp @@ -42,6 +42,16 @@ inline namespace kernel auto read_string_literal(std::istream &) -> value_type; + auto string_to_integer(std::string const&, int = 10) -> value_type; + + auto string_to_rational(std::string const&, int = 10) -> value_type; + + auto string_to_real(std::string const&, int = 10) -> value_type; + + auto string_to_complex(std::string const&, int = 10) -> value_type; + + auto string_to_number(std::string const&, int = 10) -> value_type; + template class reader { @@ -233,98 +243,6 @@ inline namespace kernel return read(port); } - static auto string_to_integer(external_representation const& token, int radix = 10) - { - return make(token, radix); - } - - static auto string_to_rational(external_representation const& token, int radix = 10) - { - try - { - return string_to_integer(token, radix); - } - catch (...) - { - return make(ratio(token, radix)); - } - } - - static auto string_to_real(external_representation const& token, int radix = 10) - { - try - { - return string_to_rational(token, radix); - } - catch (...) - { - std::unordered_map static const constants - { - // R7RS 7.1.1. Lexical structure - { "+inf.0", +std::numeric_limits::infinity() }, - { "-inf.0", -std::numeric_limits::infinity() }, - { "+nan.0", +std::numeric_limits::quiet_NaN() }, - { "-nan.0", -std::numeric_limits::quiet_NaN() }, - - // SRFI-144 - { "fl-e", M_E }, - { "fl-log2-e", M_LOG2E }, - { "fl-log10-e", M_LOG10E }, - { "fl-log-2", M_LN2 }, - { "fl-1/log-2", M_LN2 }, - { "fl-log-10", M_LN10 }, - { "fl-1/log-10", M_LN10 }, - { "fl-pi", M_PI }, - { "fl-1/pi", M_1_PI }, - { "fl-pi/2", M_PI_2 }, - { "fl-pi/4", M_PI_4 }, - { "fl-2/pi", M_2_PI }, - { "fl-2/sqrt-pi", M_2_SQRTPI }, - { "fl-sqrt-2", M_SQRT2 }, - { "fl-1/sqrt-2", M_SQRT1_2 }, - }; - - std::regex static const pattern { R"(([+-]?(?:\d+\.?|\d*\.\d+))([DEFLSdefls][+-]?\d+)?)" }; - - if (auto iter = constants.find(token); iter != std::end(constants)) - { - return make(iter->second); - } - else if (std::regex_match(token, pattern)) - { - return make(lexical_cast(token)); - } - else - { - throw std::invalid_argument("not a real number"); - } - } - } - - static auto string_to_complex(external_representation const& token, int radix = 10) - { - try - { - return string_to_real(token, radix); - } - catch (...) - { - return make(complex(token, radix)); - } - } - - static auto string_to_number(external_representation const& token, int radix = 10) - { - try - { - return string_to_complex(token, radix); - } - catch (...) - { - throw read_error(make("not a number"), make(token)); - } - } - static auto string_to_symbol(external_representation const& name) -> const_reference { if (auto const iter = symbols.find(name); iter != std::end(symbols)) diff --git a/src/kernel/complex.cpp b/src/kernel/complex.cpp index 573ee48ff..1304dbe7b 100644 --- a/src/kernel/complex.cpp +++ b/src/kernel/complex.cpp @@ -29,8 +29,10 @@ inline namespace kernel PRINT(result.str(1)); PRINT(result.str(2)); } - - throw error(); + else + { + throw std::invalid_argument("not a complex number"); + } } auto complex::imag() const noexcept -> const_reference @@ -38,7 +40,7 @@ inline namespace kernel return second; } - auto complex::pattern() const -> std::regex const& + auto complex::pattern() -> std::regex const& { std::regex static const pattern { R"(([+-]?.*)([+-].*)i)" }; return pattern; diff --git a/src/kernel/reader.cpp b/src/kernel/reader.cpp index 6f014c903..6622a8032 100644 --- a/src/kernel/reader.cpp +++ b/src/kernel/reader.cpp @@ -243,5 +243,97 @@ inline namespace kernel { return make(get_delimited_elements(is, '"')); } + + auto string_to_integer(std::string const& token, int radix) -> value_type + { + return make(token, radix); + } + + auto string_to_rational(std::string const& token, int radix) -> value_type + { + try + { + return string_to_integer(token, radix); + } + catch (...) + { + return make(ratio(token, radix)); + } + } + + auto string_to_real(std::string const& token, int radix) -> value_type + { + try + { + return string_to_rational(token, radix); + } + catch (...) + { + std::unordered_map static const constants + { + // R7RS 7.1.1. Lexical structure + { "+inf.0", +std::numeric_limits::infinity() }, + { "-inf.0", -std::numeric_limits::infinity() }, + { "+nan.0", +std::numeric_limits::quiet_NaN() }, + { "-nan.0", -std::numeric_limits::quiet_NaN() }, + + // SRFI-144 + { "fl-e", M_E }, + { "fl-log2-e", M_LOG2E }, + { "fl-log10-e", M_LOG10E }, + { "fl-log-2", M_LN2 }, + { "fl-1/log-2", M_LN2 }, + { "fl-log-10", M_LN10 }, + { "fl-1/log-10", M_LN10 }, + { "fl-pi", M_PI }, + { "fl-1/pi", M_1_PI }, + { "fl-pi/2", M_PI_2 }, + { "fl-pi/4", M_PI_4 }, + { "fl-2/pi", M_2_PI }, + { "fl-2/sqrt-pi", M_2_SQRTPI }, + { "fl-sqrt-2", M_SQRT2 }, + { "fl-1/sqrt-2", M_SQRT1_2 }, + }; + + std::regex static const pattern { R"(([+-]?(?:\d+\.?|\d*\.\d+))([DEFLSdefls][+-]?\d+)?)" }; + + if (auto iter = constants.find(token); iter != std::end(constants)) + { + return make(iter->second); + } + else if (std::regex_match(token, pattern)) + { + return make(lexical_cast(token)); + } + else + { + throw std::invalid_argument("not a real number"); + } + } + } + + auto string_to_complex(std::string const& token, int radix) -> value_type + { + try + { + return string_to_real(token, radix); + } + catch (...) + { + return make(complex(token, radix)); + } + } + + auto string_to_number(std::string const& token, int radix) -> value_type + { + try + { + return string_to_complex(token, radix); + } + catch (...) + { + throw read_error(make("not a number"), make(token)); + } + } } // namespace kernel } // namespace meevax From 8ead953abc7f9bebc5e601d6fd9b53d4e797bef8 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Wed, 17 Aug 2022 17:37:22 +0900 Subject: [PATCH 05/23] Remove type alias `external_representation` Signed-off-by: yamacir-kit --- README.md | 6 +++--- VERSION | 2 +- include/meevax/kernel/character.hpp | 2 +- include/meevax/kernel/environment.hpp | 6 +++--- include/meevax/kernel/error.hpp | 2 +- include/meevax/kernel/exact_integer.hpp | 4 ++-- include/meevax/kernel/ghost.hpp | 2 +- include/meevax/kernel/library.hpp | 6 +++--- include/meevax/kernel/machine.hpp | 2 +- include/meevax/kernel/overview.hpp | 2 -- include/meevax/kernel/ratio.hpp | 2 +- include/meevax/kernel/reader.hpp | 18 +++++++++--------- include/meevax/kernel/string.hpp | 4 ++-- include/meevax/kernel/symbol.hpp | 2 +- src/kernel/character.cpp | 4 ++-- src/kernel/complex.cpp | 5 ++--- src/kernel/environment.cpp | 10 +++++----- src/kernel/error.cpp | 6 +++--- src/kernel/exact_integer.cpp | 8 ++++---- src/kernel/library.cpp | 8 ++++---- src/kernel/port.cpp | 2 +- src/kernel/ratio.cpp | 4 ++-- src/kernel/reader.cpp | 9 ++++----- src/kernel/string.cpp | 8 ++++---- src/kernel/syntax.cpp | 2 +- test/list.cpp | 22 +++++++++++----------- test/nan_boxing_pointer.cpp | 4 ++-- 27 files changed, 74 insertions(+), 78 deletions(-) diff --git a/README.md b/README.md index 5ab2abc36..e91b82790 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.213.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.214.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.213_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.214_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` @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.213 +Meevax Lisp System, version 0.4.214 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 24db9c0d5..433f4948b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.213 +0.4.214 diff --git a/include/meevax/kernel/character.hpp b/include/meevax/kernel/character.hpp index 15398c519..3965a4511 100644 --- a/include/meevax/kernel/character.hpp +++ b/include/meevax/kernel/character.hpp @@ -59,7 +59,7 @@ inline namespace kernel return codepoint; } - explicit operator external_representation() const; // write-char (for display) + explicit operator std::string() const; // write-char (for display) }; auto operator <<(std::ostream &, character const&) -> std::ostream &; // write diff --git a/include/meevax/kernel/environment.hpp b/include/meevax/kernel/environment.hpp index b3bcabd8c..3bd1e1c97 100644 --- a/include/meevax/kernel/environment.hpp +++ b/include/meevax/kernel/environment.hpp @@ -46,7 +46,7 @@ inline namespace kernel explicit environment(environment const&) = default; - template ...)> + template ...)> explicit environment(Ts&&... xs) { (import(xs), ...); @@ -88,9 +88,9 @@ inline namespace kernel auto import_(const_reference) -> void; - auto import_(external_representation const&) -> void; + auto import_(std::string const&) -> void; - auto load(external_representation const&) -> value_type; + auto load(std::string const&) -> value_type; auto resolve(const_reference) -> value_type; diff --git a/include/meevax/kernel/error.hpp b/include/meevax/kernel/error.hpp index 5dc227806..3f030f119 100644 --- a/include/meevax/kernel/error.hpp +++ b/include/meevax/kernel/error.hpp @@ -52,7 +52,7 @@ inline namespace kernel virtual auto raise() const -> void; - virtual auto what() const -> external_representation; + virtual auto what() const -> std::string; }; auto operator <<(std::ostream &, error const&) -> std::ostream &; diff --git a/include/meevax/kernel/exact_integer.hpp b/include/meevax/kernel/exact_integer.hpp index daba883ea..3d7a70ea9 100644 --- a/include/meevax/kernel/exact_integer.hpp +++ b/include/meevax/kernel/exact_integer.hpp @@ -47,13 +47,13 @@ inline namespace kernel explicit exact_integer(double); - explicit exact_integer(external_representation const&, int = 0); + explicit exact_integer(std::string const&, int = 0); auto operator=(exact_integer const&) -> exact_integer &; auto operator=(exact_integer &&) noexcept -> exact_integer &; - auto operator=(external_representation const&) -> exact_integer &; + auto operator=(std::string const&) -> exact_integer &; operator int() const; diff --git a/include/meevax/kernel/ghost.hpp b/include/meevax/kernel/ghost.hpp index 84295706f..17e59eb0b 100644 --- a/include/meevax/kernel/ghost.hpp +++ b/include/meevax/kernel/ghost.hpp @@ -25,7 +25,7 @@ inline namespace kernel { struct ghost { - external_representation const name; + std::string const name; }; auto operator <<(std::ostream &, ghost const&) -> std::ostream &; diff --git a/include/meevax/kernel/library.hpp b/include/meevax/kernel/library.hpp index adc5ab031..1f7127e64 100644 --- a/include/meevax/kernel/library.hpp +++ b/include/meevax/kernel/library.hpp @@ -49,17 +49,17 @@ inline namespace kernel auto export_(const_reference) -> void; - auto export_(external_representation const&) -> void; + auto export_(std::string const&) -> void; auto resolve() -> const_reference; }; auto operator <<(std::ostream &, library const&) -> std::ostream &; - extern std::unordered_map libraries; + extern std::unordered_map libraries; template - auto define_library(external_representation const& name, Ts&&... xs) + auto define_library(std::string const& name, Ts&&... xs) { return libraries.emplace(name, std::forward(xs)...); } diff --git a/include/meevax/kernel/machine.hpp b/include/meevax/kernel/machine.hpp index 5df266afe..4c11ebea8 100644 --- a/include/meevax/kernel/machine.hpp +++ b/include/meevax/kernel/machine.hpp @@ -882,7 +882,7 @@ inline namespace kernel { if (current_context.is_tail) { - assert(lexical_cast(current_continuation) == "(return)"); + assert(lexical_cast(current_continuation) == "(return)"); return compile(context(), current_environment, diff --git a/include/meevax/kernel/overview.hpp b/include/meevax/kernel/overview.hpp index c96b96f67..ea272d156 100644 --- a/include/meevax/kernel/overview.hpp +++ b/include/meevax/kernel/overview.hpp @@ -49,8 +49,6 @@ inline namespace kernel using null = std::nullptr_t; - using external_representation = std::string; - [[noreturn]] auto raise(std::string const&) -> void; // error.hpp } // namespace kernel diff --git a/include/meevax/kernel/ratio.hpp b/include/meevax/kernel/ratio.hpp index 1b6a04d5f..e732a16e2 100644 --- a/include/meevax/kernel/ratio.hpp +++ b/include/meevax/kernel/ratio.hpp @@ -42,7 +42,7 @@ inline namespace kernel explicit ratio(double); - explicit ratio(external_representation const&, int = 10); + explicit ratio(std::string const&, int = 10); auto denominator() const -> exact_integer; diff --git a/include/meevax/kernel/reader.hpp b/include/meevax/kernel/reader.hpp index 9a65b0da7..8b100fa66 100644 --- a/include/meevax/kernel/reader.hpp +++ b/include/meevax/kernel/reader.hpp @@ -32,9 +32,9 @@ inline namespace kernel { auto get_codepoint(std::istream &) -> character::int_type; - auto get_delimited_elements(std::istream & is, character::int_type) -> string; + auto get_delimited_elements(std::istream &, character::int_type) -> string; - auto get_token(std::istream &) -> external_representation; + auto get_token(std::istream &) -> std::string; auto ignore_nested_block_comment(std::istream &) -> std::istream &; @@ -65,7 +65,7 @@ inline namespace kernel using char_type = typename std::istream::char_type; public: - static inline std::unordered_map symbols {}; + static inline std::unordered_map symbols {}; inline auto char_ready() const { @@ -107,7 +107,7 @@ inline namespace kernel return string_to_symbol(get_delimited_elements(is.putback(c), c)); case 'b': // (string->number (read) 2) - return string_to_number(is.peek() == '#' ? lexical_cast(read(is)) : get_token(is), 2); + return string_to_number(is.peek() == '#' ? lexical_cast(read(is)) : get_token(is), 2); case 'c': // Common Lisp { @@ -117,7 +117,7 @@ inline namespace kernel } case 'd': - return string_to_number(is.peek() == '#' ? lexical_cast(read(is)) : get_token(is), 10); + return string_to_number(is.peek() == '#' ? lexical_cast(read(is)) : get_token(is), 10); case 'e': return apply(read(is)); // NOTE: Same as #,(exact (read)) @@ -130,14 +130,14 @@ inline namespace kernel return apply(read(is)); // NOTE: Same as #,(inexact (read)) case 'o': - return string_to_number(is.peek() == '#' ? lexical_cast(read(is)) : get_token(is), 8); + return string_to_number(is.peek() == '#' ? lexical_cast(read(is)) : get_token(is), 8); case 't': get_token(is); return t; case 'x': - return string_to_number(is.peek() == '#' ? lexical_cast(read(is)) : get_token(is), 16); + return string_to_number(is.peek() == '#' ? lexical_cast(read(is)) : get_token(is), 16); case '(': is.putback(c); @@ -237,13 +237,13 @@ inline namespace kernel return read(standard_input); } - inline auto read(external_representation const& s) -> value_type // NOTE: Specifying `decltype(auto)` causes a `undefined reference to ...` error in GCC-7. + inline auto read(std::string const& s) -> value_type // NOTE: Specifying `decltype(auto)` causes a `undefined reference to ...` error in GCC-7. { auto port = std::stringstream(s); return read(port); } - static auto string_to_symbol(external_representation const& name) -> const_reference + static auto string_to_symbol(std::string const& name) -> const_reference { if (auto const iter = symbols.find(name); iter != std::end(symbols)) { diff --git a/include/meevax/kernel/string.hpp b/include/meevax/kernel/string.hpp index 279c6201e..74a63d161 100644 --- a/include/meevax/kernel/string.hpp +++ b/include/meevax/kernel/string.hpp @@ -29,7 +29,7 @@ inline namespace kernel explicit string() = default; - explicit string(external_representation const&); + explicit string(std::string const&); /* (list->string list) procedure @@ -152,7 +152,7 @@ inline namespace kernel */ auto set(const_reference, const_reference) -> void; - operator external_representation() const; // write-string (for display) + operator std::string() const; // write-string (for display) }; auto operator ==(string const&, string const&) -> bool; diff --git a/include/meevax/kernel/symbol.hpp b/include/meevax/kernel/symbol.hpp index 7e9e4293e..221ef590f 100644 --- a/include/meevax/kernel/symbol.hpp +++ b/include/meevax/kernel/symbol.hpp @@ -35,7 +35,7 @@ inline namespace kernel : value { std::forward(xs)... } {} - operator external_representation() const noexcept + operator std::string() const noexcept { return value; } diff --git a/src/kernel/character.cpp b/src/kernel/character.cpp index 771845438..a1e11111f 100644 --- a/src/kernel/character.cpp +++ b/src/kernel/character.cpp @@ -22,7 +22,7 @@ namespace meevax { inline namespace kernel { - character::operator external_representation() const + character::operator std::string() const { std::array bytes {}; @@ -75,7 +75,7 @@ inline namespace kernel case 0x7F: return os << cyan("delete" ); default: - return os << cyan(static_cast(datum)); + return os << cyan(static_cast(datum)); } } diff --git a/src/kernel/complex.cpp b/src/kernel/complex.cpp index 1304dbe7b..9dde3e22a 100644 --- a/src/kernel/complex.cpp +++ b/src/kernel/complex.cpp @@ -25,9 +25,8 @@ inline namespace kernel { if (std::smatch result; std::regex_match(token, result, pattern())) { - PRINT(result.str(0)); - PRINT(result.str(1)); - PRINT(result.str(2)); + std::get<0>(*this) = string_to_real(result.str(1), radix); + std::get<1>(*this) = string_to_real(result.str(2), radix); } else { diff --git a/src/kernel/environment.cpp b/src/kernel/environment.cpp index 0c66ccc0d..8fdc97380 100644 --- a/src/kernel/environment.cpp +++ b/src/kernel/environment.cpp @@ -26,7 +26,7 @@ inline namespace kernel (*this)[name] = value; } - auto environment::define(external_representation const& name, const_reference value) -> void + auto environment::define(std::string const& name, const_reference value) -> void { define(string_to_symbol(name), value); } @@ -36,7 +36,7 @@ inline namespace kernel if (expression.is() and car(expression).is() and car(expression).as().value == "define-library") { - define_library(lexical_cast(cadr(expression)), cddr(expression)); + define_library(lexical_cast(cadr(expression)), cddr(expression)); return cadr(expression); } else if (expression.is() and car(expression).is() @@ -205,7 +205,7 @@ inline namespace kernel return rename(cadr(declaration)) (cddr(declaration)); } - else if (auto iter = libraries.find(lexical_cast(declaration)); iter != std::end(libraries)) + else if (auto iter = libraries.find(lexical_cast(declaration)); iter != std::end(libraries)) { return std::get<1>(*iter).resolve(); } @@ -233,12 +233,12 @@ inline namespace kernel } } - auto environment::import_(external_representation const& import_set) -> void + auto environment::import_(std::string const& import_set) -> void { import_(read(import_set)); } - auto environment::load(external_representation const& s) -> value_type + auto environment::load(std::string const& s) -> value_type { if (let port = make(s); port and port.as().is_open()) { diff --git a/src/kernel/error.cpp b/src/kernel/error.cpp index a6c4f214f..0b7048e10 100644 --- a/src/kernel/error.cpp +++ b/src/kernel/error.cpp @@ -35,11 +35,11 @@ inline namespace kernel throw *this; } - auto error::what() const -> external_representation + auto error::what() const -> std::string { std::stringstream ss {}; - ss << "error: " << static_cast(message().as()); + ss << "error: " << static_cast(message().as()); if (irritants()) { @@ -61,7 +61,7 @@ inline namespace kernel return os << magenta(")"); } - auto raise(external_representation const& message) -> void + auto raise(std::string const& message) -> void { throw error(make(message)); } diff --git a/src/kernel/exact_integer.cpp b/src/kernel/exact_integer.cpp index 38e20a53d..3821fd2a4 100644 --- a/src/kernel/exact_integer.cpp +++ b/src/kernel/exact_integer.cpp @@ -71,12 +71,12 @@ inline namespace kernel mpz_init_set_d(value, rhs); } - exact_integer::exact_integer(external_representation const& s, int radix) + exact_integer::exact_integer(std::string const& s, int radix) { if (mpz_init_set_str(value, s.c_str(), radix)) { mpz_clear(value); - throw error(); + throw std::invalid_argument("not a integer"); } } @@ -92,11 +92,11 @@ inline namespace kernel return *this; } - auto exact_integer::operator=(external_representation const& s) -> exact_integer & + auto exact_integer::operator=(std::string const& s) -> exact_integer & { if (mpz_set_str(value, s.c_str(), 0)) { - throw error(make("invalid argument"), make(s)); + throw std::invalid_argument(s); } else { diff --git a/src/kernel/library.cpp b/src/kernel/library.cpp index e4bb7750d..998786f97 100644 --- a/src/kernel/library.cpp +++ b/src/kernel/library.cpp @@ -938,7 +938,7 @@ inline namespace kernel library.define("put-char", [](let const& xs) { - cadr(xs).as() << static_cast(car(xs).as()); + cadr(xs).as() << static_cast(car(xs).as()); return unspecified; }); @@ -1280,7 +1280,7 @@ inline namespace kernel { if (x.is()) { - std::cout << static_cast(x.as()); + std::cout << static_cast(x.as()); } else { @@ -1369,7 +1369,7 @@ inline namespace kernel export_specs = cons(export_spec, export_specs); } - auto library::export_(external_representation const& export_spec) -> void + auto library::export_(std::string const& export_spec) -> void { export_(read(export_spec)); } @@ -1400,6 +1400,6 @@ inline namespace kernel return os << library.global(); } - std::unordered_map libraries {}; + std::unordered_map libraries {}; } // namespace kernel } // namespace meevax diff --git a/src/kernel/port.cpp b/src/kernel/port.cpp index bdc9eeb9b..47abe9acc 100644 --- a/src/kernel/port.cpp +++ b/src/kernel/port.cpp @@ -45,7 +45,7 @@ inline namespace kernel #undef DEFINE #define DEFINE(TYPENAME, FILE_STREAM, NAME) \ - TYPENAME::TYPENAME(external_representation const& name) \ + TYPENAME::TYPENAME(std::string const& name) \ : description { name } \ , FILE_STREAM { name } \ {} \ diff --git a/src/kernel/ratio.cpp b/src/kernel/ratio.cpp index fc5880337..fd218ab34 100644 --- a/src/kernel/ratio.cpp +++ b/src/kernel/ratio.cpp @@ -61,14 +61,14 @@ inline namespace kernel mpq_set_d(value, x); } - ratio::ratio(external_representation const& token, int radix) + ratio::ratio(std::string const& token, int radix) { // std::regex static const pattern { "([+-]?[0-9a-f]+)/([0-9a-f]+)" }; if (mpq_init(value); mpq_set_str(value, token.c_str(), radix)) { mpq_clear(value); - throw error(); + throw std::invalid_argument("not a ratio"); } else { diff --git a/src/kernel/reader.cpp b/src/kernel/reader.cpp index 6622a8032..2ebeffbf9 100644 --- a/src/kernel/reader.cpp +++ b/src/kernel/reader.cpp @@ -16,7 +16,6 @@ #include #include -#include namespace meevax { @@ -122,7 +121,7 @@ inline namespace kernel case 't': s.codepoints.emplace_back('\t'); break; case 'v': s.codepoints.emplace_back('\v'); break; case 'x': - if (auto token = external_representation(); std::getline(is, token, ';')) + if (auto token = std::string(); std::getline(is, token, ';')) { s.codepoints.emplace_back(lexical_cast(std::hex, token)); } @@ -196,7 +195,7 @@ inline namespace kernel auto read_character_literal(std::istream & is) -> value_type { - std::unordered_map static const character_names { + std::unordered_map static const character_names { { "alarm" , 0x07 }, { "backspace", 0x08 }, { "delete" , 0x7F }, @@ -269,7 +268,7 @@ inline namespace kernel } catch (...) { - std::unordered_map static const constants + std::unordered_map static const constants { // R7RS 7.1.1. Lexical structure { "+inf.0", +std::numeric_limits::infinity() }, @@ -332,7 +331,7 @@ inline namespace kernel } catch (...) { - throw read_error(make("not a number"), make(token)); + throw std::invalid_argument("not a number"); } } } // namespace kernel diff --git a/src/kernel/string.cpp b/src/kernel/string.cpp index 49dcf3946..dd3ecba40 100644 --- a/src/kernel/string.cpp +++ b/src/kernel/string.cpp @@ -25,7 +25,7 @@ namespace meevax { inline namespace kernel { - string::string(external_representation const& s) + string::string(std::string const& s) { for (auto port = std::stringstream(s); not character::is_eof(port.peek()); codepoints.emplace_back(get_codepoint(port))); } @@ -112,13 +112,13 @@ inline namespace kernel codepoints.at(k.as()) = c.as(); } - string::operator external_representation() const + string::operator std::string() const { - external_representation result; + std::string result; for (character const& each : codepoints) { - result.append(static_cast(each)); + result.append(static_cast(each)); } return result; diff --git a/src/kernel/syntax.cpp b/src/kernel/syntax.cpp index 79d58ac36..6b9f7a763 100644 --- a/src/kernel/syntax.cpp +++ b/src/kernel/syntax.cpp @@ -20,7 +20,7 @@ namespace meevax { inline namespace kernel { - syntax::syntax(external_representation const& name, function_type const& compile) + syntax::syntax(std::string const& name, function_type const& compile) : description { name } , compile { compile } {} diff --git a/test/list.cpp b/test/list.cpp index d91c57514..1da9c62f2 100644 --- a/test/list.cpp +++ b/test/list.cpp @@ -12,24 +12,24 @@ auto main() -> int c = make("c"), d = make("d"); - assert(lexical_cast(cons(a, unit)) == "(a)"); - assert(lexical_cast(cons(list(a), list(b, c, d))) == "((a) b c d)"); - assert(lexical_cast(cons(make("a"), list(b, c))) == "(\"a\" b c)"); - assert(lexical_cast(cons(a, make(3))) == "(a . 3)"); - assert(lexical_cast(cons(list(a, b), c)) == "((a b) . c)"); + assert(lexical_cast(cons(a, unit)) == "(a)"); + assert(lexical_cast(cons(list(a), list(b, c, d))) == "((a) b c d)"); + assert(lexical_cast(cons(make("a"), list(b, c))) == "(\"a\" b c)"); + assert(lexical_cast(cons(a, make(3))) == "(a . 3)"); + assert(lexical_cast(cons(list(a, b), c)) == "((a b) . c)"); - assert(lexical_cast(list(a, make(3 + 4), c)) == "(a 7 c)"); - assert(lexical_cast(list()) == "()"); + assert(lexical_cast(list(a, make(3 + 4), c)) == "(a 7 c)"); + assert(lexical_cast(list()) == "()"); - assert(lexical_cast(xcons(list(b, c), a)) == "(a b c)"); + assert(lexical_cast(xcons(list(b, c), a)) == "(a b c)"); - assert(lexical_cast(make_list(4, c)) == "(c c c c)"); + assert(lexical_cast(make_list(4, c)) == "(c c c c)"); - assert(lexical_cast(list_tabulate(4, [](auto&&... xs) { return make(xs...); })) == "(0 1 2 3)"); + assert(lexical_cast(list_tabulate(4, [](auto&&... xs) { return make(xs...); })) == "(0 1 2 3)"); let x1 = list(a, b, c); let x2 = list_copy(x1); - assert(lexical_cast(x2) == "(a b c)"); + assert(lexical_cast(x2) == "(a b c)"); assert(not eq(x1, x2)); let x = circular_list(a, b, c); diff --git a/test/nan_boxing_pointer.cpp b/test/nan_boxing_pointer.cpp index b0369638e..aeef00482 100644 --- a/test/nan_boxing_pointer.cpp +++ b/test/nan_boxing_pointer.cpp @@ -125,8 +125,8 @@ auto main() -> int } { - assert(lexical_cast(make(3.14)) == "3.14000000000000012"); - assert(lexical_cast(make(42)) == "42"); + assert(lexical_cast(make(3.14)) == "3.14000000000000012"); + assert(lexical_cast(make(42)) == "42"); } { From ae844da2d39146ec3de273c6610aaa55b1f70527 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Wed, 17 Aug 2022 18:24:54 +0900 Subject: [PATCH 06/23] Add some type aliases Signed-off-by: yamacir-kit --- README.md | 6 ++-- VERSION | 2 +- include/meevax/kernel/complex.hpp | 2 +- include/meevax/kernel/number.hpp | 48 +++++++++++++++++++++---------- src/kernel/complex.cpp | 4 +-- src/kernel/number.cpp | 10 +++---- 6 files changed, 45 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index e91b82790..1e8b59dbf 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.214.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.215.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.214_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.215_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` @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.214 +Meevax Lisp System, version 0.4.215 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 433f4948b..96ade8712 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.214 +0.4.215 diff --git a/include/meevax/kernel/complex.hpp b/include/meevax/kernel/complex.hpp index 76a8e218a..58b68f7f7 100644 --- a/include/meevax/kernel/complex.hpp +++ b/include/meevax/kernel/complex.hpp @@ -32,7 +32,7 @@ inline namespace kernel explicit complex(std::string const&, int = 10); - auto imag() const noexcept -> const_reference; + auto imaginary() const noexcept -> const_reference; static auto pattern() -> std::regex const&; diff --git a/include/meevax/kernel/number.hpp b/include/meevax/kernel/number.hpp index 0363d66ff..3c886a9d4 100644 --- a/include/meevax/kernel/number.hpp +++ b/include/meevax/kernel/number.hpp @@ -292,6 +292,30 @@ inline namespace kernel } } inline constexpr inexact_cast; + using plus = std::plus; + + using minus = std::minus; + + using multiplies = std::multiplies; + + using divides = std::divides; + + struct modulus + { + template + auto operator ()(T&& x, U&& y) const + { + if constexpr (std::is_floating_point_v> and std::is_floating_point_v>) + { + return std::fmod(x, y); + } + else + { + return x % y; + } + } + }; + struct equal_to { template @@ -319,21 +343,15 @@ inline namespace kernel } }; - struct modulus - { - template - auto operator ()(T&& x, U&& y) const - { - if constexpr (std::is_floating_point_v> and std::is_floating_point_v>) - { - return std::remainder(x, y); - } - else - { - return x % y; - } - } - }; + using not_equal_to = std::not_equal_to; + + using less = std::less; + + using less_equal = std::less_equal; + + using greater = std::greater; + + using greater_equal = std::greater_equal; struct is_complex { diff --git a/src/kernel/complex.cpp b/src/kernel/complex.cpp index 9dde3e22a..e6762e472 100644 --- a/src/kernel/complex.cpp +++ b/src/kernel/complex.cpp @@ -34,7 +34,7 @@ inline namespace kernel } } - auto complex::imag() const noexcept -> const_reference + auto complex::imaginary() const noexcept -> const_reference { return second; } @@ -52,7 +52,7 @@ inline namespace kernel auto operator <<(std::ostream & os, complex const& z) -> std::ostream & { - return os << z.real() << cyan(apply>(e0, z.imag()).as() ? '+' : '-') << z.imag() << cyan("i"); + return os << z.real() << cyan(apply(e0, z.imaginary()).as() ? "+" : "") << z.imaginary() << cyan("i"); } } // namespace kernel } // namespace meevax diff --git a/src/kernel/number.cpp b/src/kernel/number.cpp index 06cdd5220..2ab4bfabf 100644 --- a/src/kernel/number.cpp +++ b/src/kernel/number.cpp @@ -165,10 +165,10 @@ inline namespace kernel auto operator > (double a, ratio const& b) -> bool { return a > inexact_cast(b); } auto operator >=(double a, ratio const& b) -> bool { return a >= inexact_cast(b); } - auto operator +(const_reference x, const_reference y) -> value_type { return apply>(x, y); } - auto operator -(const_reference x, const_reference y) -> value_type { return apply>(x, y); } - auto operator *(const_reference x, const_reference y) -> value_type { return apply>(x, y); } - auto operator /(const_reference x, const_reference y) -> value_type { return apply>(x, y); } - auto operator %(const_reference x, const_reference y) -> value_type { return apply< modulus >(x, y); } + auto operator +(const_reference x, const_reference y) -> value_type { return apply(x, y); } + auto operator -(const_reference x, const_reference y) -> value_type { return apply(x, y); } + auto operator *(const_reference x, const_reference y) -> value_type { return apply(x, y); } + auto operator /(const_reference x, const_reference y) -> value_type { return apply(x, y); } + auto operator %(const_reference x, const_reference y) -> value_type { return apply(x, y); } } // namespace kernel } // namespace meevax From 007c09e63f02e507de6e6e41fb80a2c770e2c5ee Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Sun, 4 Sep 2022 19:00:46 +0900 Subject: [PATCH 07/23] Update some of unary arithmetic operations to support `complex` Signed-off-by: yamacir-kit --- README.md | 6 +- VERSION | 2 +- include/meevax/kernel/complex.hpp | 3 + include/meevax/kernel/number.hpp | 91 +++++++++++++++++++++---------- src/kernel/complex.cpp | 11 +++- 5 files changed, 80 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 1e8b59dbf..b2fc9615c 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.215.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.216.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.215_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.216_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` @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.215 +Meevax Lisp System, version 0.4.216 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 96ade8712..7038927a9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.215 +0.4.216 diff --git a/include/meevax/kernel/complex.hpp b/include/meevax/kernel/complex.hpp index 58b68f7f7..252547288 100644 --- a/include/meevax/kernel/complex.hpp +++ b/include/meevax/kernel/complex.hpp @@ -17,6 +17,7 @@ #ifndef INCLUDED_MEEVAX_KERNEL_COMPLEX_HPP #define INCLUDED_MEEVAX_KERNEL_COMPLEX_HPP +#include #include #include @@ -37,6 +38,8 @@ inline namespace kernel static auto pattern() -> std::regex const&; auto real() const noexcept -> const_reference; + + explicit operator std::complex(); }; auto operator <<(std::ostream &, complex const&) -> std::ostream &; diff --git a/include/meevax/kernel/number.hpp b/include/meevax/kernel/number.hpp index 3c886a9d4..44ba7e280 100644 --- a/include/meevax/kernel/number.hpp +++ b/include/meevax/kernel/number.hpp @@ -265,7 +265,12 @@ inline namespace kernel template auto operator ()(T&& x) const -> decltype(auto) { - if constexpr (std::is_floating_point_v>) + if constexpr (std::is_same_v, complex>) + { + return complex(apply(x.real()), + apply(x.imaginary())); + } + else if constexpr (std::is_floating_point_v>) { return ratio(std::forward(x)); } @@ -274,14 +279,20 @@ inline namespace kernel return std::forward(x); } } - } inline constexpr exact_cast; + } + inline constexpr exact_cast; struct inexact { template auto operator ()(T const& x) const -> decltype(auto) { - if constexpr (std::is_floating_point_v>) + if constexpr (std::is_same_v, complex>) + { + return complex(apply(x.real()), + apply(x.imaginary())); + } + else if constexpr (std::is_floating_point_v>) { return std::forward(x); } @@ -290,7 +301,8 @@ inline namespace kernel return static_cast(std::forward(x)); } } - } inline constexpr inexact_cast; + } + inline constexpr inexact_cast; using plus = std::plus; @@ -412,7 +424,11 @@ inline namespace kernel template constexpr auto operator ()(T&& x) const { - if constexpr (std::is_floating_point_v>) + if constexpr (std::is_same_v, complex>) + { + return apply(x.real()) and apply(x.imaginary()); + } + else if constexpr (std::is_floating_point_v>) { return not std::isinf(x); } @@ -428,7 +444,11 @@ inline namespace kernel template constexpr auto operator ()(T&& x) const { - if constexpr (std::is_floating_point_v>) + if constexpr (std::is_same_v, complex>) + { + return apply(x.real()) or apply(x.imaginary()); + } + else if constexpr (std::is_floating_point_v>) { return std::isinf(x); } @@ -444,7 +464,11 @@ inline namespace kernel template constexpr auto operator ()(T&& x) const { - if constexpr (std::is_floating_point_v>) + if constexpr (std::is_same_v, complex>) + { + return apply(x.real()) or apply(x.imaginary()); + } + else if constexpr (std::is_floating_point_v>) { return std::isnan(x); } @@ -458,20 +482,26 @@ inline namespace kernel struct sqrt { template - auto operator ()(T const& x) const - { - return std::sqrt(inexact_cast(x)); - } - - auto operator ()(exact_integer const& x) const + constexpr auto operator ()(T&& x) const { - if (auto&& [s, r] = exact_integer_sqrt(x); r == 0) + if constexpr (std::is_same_v, complex>) { - return make(s); + return std::sqrt(static_cast>(std::forward(x))); + } + else if constexpr (std::is_same_v, exact_integer>) + { + if (auto&& [s, r] = exact_integer_sqrt(x); r == 0) + { + return make(s); + } + else + { + return make(std::sqrt(inexact_cast(x))); + } } else { - return make(operator ()(x)); + return std::sqrt(inexact_cast(x)); } } }; @@ -496,19 +526,24 @@ inline namespace kernel struct ROUND \ { \ template \ - auto operator ()(T const& x) const \ - { \ - return std::ROUND(inexact_cast(x)); \ - } \ - \ - auto operator ()(exact_integer const& x) const -> auto const& \ - { \ - return x; \ - } \ - \ - auto operator ()(ratio const& x) const \ + constexpr auto operator ()(T&& x) const \ { \ - return exact_integer(operator ()(x)); \ + if constexpr (std::is_floating_point_v>) \ + { \ + return std::ROUND(inexact_cast(x)); \ + } \ + else if constexpr (std::is_same_v, ratio>) \ + { \ + return exact_integer(std::ROUND(inexact_cast(x))); \ + } \ + else if constexpr (std::is_same_v, exact_integer>) \ + { \ + return std::forward(x); \ + } \ + else \ + { \ + throw std::invalid_argument("not a real number"); \ + } \ } \ } diff --git a/src/kernel/complex.cpp b/src/kernel/complex.cpp index e6762e472..22fe9b37c 100644 --- a/src/kernel/complex.cpp +++ b/src/kernel/complex.cpp @@ -41,7 +41,7 @@ inline namespace kernel auto complex::pattern() -> std::regex const& { - std::regex static const pattern { R"(([+-]?.*)([+-].*)i)" }; + std::regex static const pattern { R"(([+-]?.*)([+-].*)[ij])" }; return pattern; } @@ -50,6 +50,15 @@ inline namespace kernel return first; } + complex::operator std::complex() + { + assert(apply(real())); + assert(apply(imaginary())); + + return std::complex(apply(real()).as(), + apply(imaginary()).as()); + } + auto operator <<(std::ostream & os, complex const& z) -> std::ostream & { return os << z.real() << cyan(apply(e0, z.imaginary()).as() ? "+" : "") << z.imaginary() << cyan("i"); From 23c7924c75887c4727f6628a83b6601b7eed329e Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Sun, 4 Sep 2022 19:56:05 +0900 Subject: [PATCH 08/23] Lipsticks Signed-off-by: yamacir-kit --- README.md | 6 +++--- VERSION | 2 +- include/meevax/iostream/escape_sequence.hpp | 6 +++--- include/meevax/iostream/lexical_cast.hpp | 2 +- include/meevax/kernel/heterogeneous.hpp | 2 +- include/meevax/kernel/number.hpp | 3 ++- include/meevax/kernel/object.hpp | 2 +- include/meevax/memory/nan_boxing_pointer.hpp | 12 ++++++------ include/meevax/memory/tagged_pointer.hpp | 8 ++++---- include/meevax/type_traits/underlying_cast.hpp | 4 ++-- include/meevax/utility/overload.hpp | 2 +- 11 files changed, 25 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index b2fc9615c..680784de5 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.216.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.217.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.216_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.217_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` @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.216 +Meevax Lisp System, version 0.4.217 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 7038927a9..59729f62c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.216 +0.4.217 diff --git a/include/meevax/iostream/escape_sequence.hpp b/include/meevax/iostream/escape_sequence.hpp index 48ce97d30..36c61d5cb 100644 --- a/include/meevax/iostream/escape_sequence.hpp +++ b/include/meevax/iostream/escape_sequence.hpp @@ -33,9 +33,9 @@ inline namespace iostream std::tuple< typename std::conditional< - not std::is_reference::value or std::is_scalar::type>::value, - typename std::decay::type, - std::reference_wrapper::type> + not std::is_reference_v or std::is_scalar_v>, + std::decay_t, + std::reference_wrapper> >::type... > references; diff --git a/include/meevax/iostream/lexical_cast.hpp b/include/meevax/iostream/lexical_cast.hpp index 27fa81dad..4d21faacf 100644 --- a/include/meevax/iostream/lexical_cast.hpp +++ b/include/meevax/iostream/lexical_cast.hpp @@ -30,7 +30,7 @@ inline namespace iostream { if (std::stringstream ss; (ss << ... << xs)) { - if constexpr (std::is_same::type, std::string>::value) + if constexpr (std::is_same_v, std::string>) { return ss.str(); } diff --git a/include/meevax/kernel/heterogeneous.hpp b/include/meevax/kernel/heterogeneous.hpp index f370e7f41..8f297bb82 100644 --- a/include/meevax/kernel/heterogeneous.hpp +++ b/include/meevax/kernel/heterogeneous.hpp @@ -151,7 +151,7 @@ inline namespace kernel template inline auto is() const { - return type() == typeid(typename std::decay::type); + return type() == typeid(std::decay_t); } template )> diff --git a/include/meevax/kernel/number.hpp b/include/meevax/kernel/number.hpp index 44ba7e280..bdade114e 100644 --- a/include/meevax/kernel/number.hpp +++ b/include/meevax/kernel/number.hpp @@ -234,6 +234,7 @@ inline namespace kernel { type_index<1>(typeid(ratio )), application() }, { type_index<1>(typeid(float )), application() }, { type_index<1>(typeid(double )), application() }, + // { type_index<1>(typeid(complex )), application() }, }; return apply.at(type_index<1>(x.type()))(x); @@ -285,7 +286,7 @@ inline namespace kernel struct inexact { template - auto operator ()(T const& x) const -> decltype(auto) + auto operator ()(T&& x) const -> decltype(auto) { if constexpr (std::is_same_v, complex>) { diff --git a/include/meevax/kernel/object.hpp b/include/meevax/kernel/object.hpp index 3d4ca3d72..afe3cab7f 100644 --- a/include/meevax/kernel/object.hpp +++ b/include/meevax/kernel/object.hpp @@ -58,7 +58,7 @@ inline namespace kernel template auto make(T&& x) { - return value_type::allocate::type>(std::forward(x)); + return value_type::allocate>(std::forward(x)); } } // namespace kernel } // namespace meevax diff --git a/include/meevax/memory/nan_boxing_pointer.hpp b/include/meevax/memory/nan_boxing_pointer.hpp index 36d24179f..94a4b7025 100644 --- a/include/meevax/memory/nan_boxing_pointer.hpp +++ b/include/meevax/memory/nan_boxing_pointer.hpp @@ -45,9 +45,9 @@ inline namespace memory typename T_0b111 = std::integral_constant> struct nan_boxing_pointer { - using element_type = typename std::decay::type; + using element_type = std::decay_t; - using pointer = typename std::add_pointer::type; + using pointer = std::add_pointer_t; pointer data; @@ -131,14 +131,14 @@ inline namespace memory template auto as() const { - if constexpr (std::is_same::type>::value) + if constexpr (std::is_same_v, float64>) { return bit_cast(data); } else { - return bit_cast::type>( - static_cast::type)>>( + return bit_cast>( + static_cast)>>( reinterpret_cast(data) & mask_payload)); } } @@ -161,7 +161,7 @@ inline namespace memory template auto is() const noexcept { - return type() == typeid(typename std::decay::type); + return type() == typeid(std::decay_t); } auto signature() const noexcept diff --git a/include/meevax/memory/tagged_pointer.hpp b/include/meevax/memory/tagged_pointer.hpp index eae8f41f7..896dc5421 100644 --- a/include/meevax/memory/tagged_pointer.hpp +++ b/include/meevax/memory/tagged_pointer.hpp @@ -87,15 +87,15 @@ inline namespace memory template auto as() const { - return bit_cast::type>( - static_cast::type)>>( + return bit_cast>( + static_cast)>>( reinterpret_cast(simple_pointer::data) >> 32)); } template auto is() const noexcept { - return type() == typeid(typename std::decay::type); + return type() == typeid(std::decay_t); } constexpr auto tag() const noexcept @@ -109,7 +109,7 @@ inline namespace memory { #define DEFINE(TAG) \ case TAG: \ - return typeid(typename std::decay::type) + return typeid(std::decay_t) DEFINE(0b001); DEFINE(0b010); diff --git a/include/meevax/type_traits/underlying_cast.hpp b/include/meevax/type_traits/underlying_cast.hpp index 6e4f4bf2f..f9f3d6052 100644 --- a/include/meevax/type_traits/underlying_cast.hpp +++ b/include/meevax/type_traits/underlying_cast.hpp @@ -26,13 +26,13 @@ inline namespace type_traits template )> constexpr auto underlying_cast(T x) { - return static_cast::type>(x); + return static_cast>(x); } template constexpr auto underlying_decrement(T && value) { - return typename std::decay::type(underlying_cast(value) - 1); + return std::decay_t(underlying_cast(value) - 1); } } // namespace type_traits } // namespace meevax diff --git a/include/meevax/utility/overload.hpp b/include/meevax/utility/overload.hpp index 9f7044c98..4323d1027 100644 --- a/include/meevax/utility/overload.hpp +++ b/include/meevax/utility/overload.hpp @@ -34,7 +34,7 @@ inline namespace utility overloads(Ts&&...) -> overloads; template - constexpr auto overload(Ts&&... xs) -> overloads::type> + constexpr auto overload(Ts&&... xs) -> overloads> { return { std::forward(xs)... }; } From fea84442e8ce9ef9ae86587f6367f253ca4901a5 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Sun, 4 Sep 2022 21:25:16 +0900 Subject: [PATCH 09/23] Update definition of `is_finite` to be the negation of `is_infinite` Signed-off-by: yamacir-kit --- README.md | 6 ++-- VERSION | 2 +- include/meevax/kernel/number.hpp | 60 +++++++++++++++++--------------- 3 files changed, 35 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 680784de5..a719ff874 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.217.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.218.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.217_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.218_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` @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.217 +Meevax Lisp System, version 0.4.218 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 59729f62c..e5a5b4f6a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.217 +0.4.218 diff --git a/include/meevax/kernel/number.hpp b/include/meevax/kernel/number.hpp index bdade114e..89d7b4b86 100644 --- a/include/meevax/kernel/number.hpp +++ b/include/meevax/kernel/number.hpp @@ -420,43 +420,32 @@ inline namespace kernel } }; - struct is_finite + struct is_infinite { template constexpr auto operator ()(T&& x) const { if constexpr (std::is_same_v, complex>) { - return apply(x.real()) and apply(x.imaginary()); + return apply(x.real()) or apply(x.imaginary()); } else if constexpr (std::is_floating_point_v>) { - return not std::isinf(x); + return std::isinf(x); } else { - return true; + return false; } } }; - struct is_infinite + struct is_finite { template constexpr auto operator ()(T&& x) const { - if constexpr (std::is_same_v, complex>) - { - return apply(x.real()) or apply(x.imaginary()); - } - else if constexpr (std::is_floating_point_v>) - { - return std::isinf(x); - } - else - { - return false; - } + return not std::invoke(is_infinite(), std::forward(x)); } }; @@ -483,7 +472,7 @@ inline namespace kernel struct sqrt { template - constexpr auto operator ()(T&& x) const + constexpr auto operator ()(T&& x) const -> decltype(auto) { if constexpr (std::is_same_v, complex>) { @@ -509,17 +498,31 @@ inline namespace kernel struct expt { - template - auto operator ()(T const& x, U const& y) const -> decltype(auto) + template + constexpr auto operator ()(Base&& base, Exponent&& exponent) const -> decltype(auto) { - return std::pow(inexact_cast(x), inexact_cast(y)); + if constexpr (std::is_same_v, exact_integer> and + std::is_same_v, exact_integer>) + { + exact_integer result {}; + mpz_pow_ui(result.value, base.value, static_cast(exponent)); + return result; + } + else + { + return std::pow(inexact_cast(std::forward(base)), + inexact_cast(std::forward(exponent))); + } } + }; - auto operator ()(exact_integer const& base, exact_integer const& exponent) const + struct atan2 + { + template + auto operator ()(T&& x, U&& y) const { - exact_integer result {}; - mpz_pow_ui(result.value, base.value, static_cast(exponent)); - return result; + return std::atan2(inexact_cast(std::forward(x)), + inexact_cast(std::forward(y))); } }; @@ -558,17 +561,16 @@ inline namespace kernel #define DEFINE(CMATH) \ struct CMATH \ { \ - template \ - auto operator ()(Ts&&... xs) const \ + template \ + auto operator ()(T&& x) const \ { \ - return std::CMATH(inexact_cast(std::forward(xs))...); \ + return std::CMATH(inexact_cast(std::forward(x))); \ } \ } DEFINE(sin); DEFINE(asin); DEFINE(sinh); DEFINE(asinh); DEFINE(cos); DEFINE(acos); DEFINE(cosh); DEFINE(acosh); DEFINE(tan); DEFINE(atan); DEFINE(tanh); DEFINE(atanh); - DEFINE(atan2); DEFINE(exp); DEFINE(log); From cc68470500c290ce031042ddb1abe080ce18fc13 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Sun, 4 Sep 2022 22:02:26 +0900 Subject: [PATCH 10/23] Update `application` to support `complex` Signed-off-by: yamacir-kit --- README.md | 6 +++--- VERSION | 2 +- include/meevax/kernel/error.hpp | 2 +- include/meevax/kernel/number.hpp | 20 ++++++++++++++------ 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index a719ff874..0c98f6b4c 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.218.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.219.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.218_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.219_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` @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.218 +Meevax Lisp System, version 0.4.219 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index e5a5b4f6a..a5ca32021 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.218 +0.4.219 diff --git a/include/meevax/kernel/error.hpp b/include/meevax/kernel/error.hpp index 3f030f119..7b5e35b4b 100644 --- a/include/meevax/kernel/error.hpp +++ b/include/meevax/kernel/error.hpp @@ -97,7 +97,7 @@ inline namespace kernel catch (std::exception const& error) { - std::cerr << "; error" << error.what() << std::endl; + std::cerr << "; error " << std::quoted(error.what()) << std::endl; return underlying_cast(exit_status::failure); } diff --git a/include/meevax/kernel/number.hpp b/include/meevax/kernel/number.hpp index 89d7b4b86..7398f7bfc 100644 --- a/include/meevax/kernel/number.hpp +++ b/include/meevax/kernel/number.hpp @@ -234,7 +234,7 @@ inline namespace kernel { type_index<1>(typeid(ratio )), application() }, { type_index<1>(typeid(float )), application() }, { type_index<1>(typeid(double )), application() }, - // { type_index<1>(typeid(complex )), application() }, + { type_index<1>(typeid(complex )), application() }, }; return apply.at(type_index<1>(x.type()))(x); @@ -499,7 +499,7 @@ inline namespace kernel struct expt { template - constexpr auto operator ()(Base&& base, Exponent&& exponent) const -> decltype(auto) + auto operator ()(Base&& base, Exponent&& exponent) const -> decltype(auto) { if constexpr (std::is_same_v, exact_integer> and std::is_same_v, exact_integer>) @@ -546,7 +546,8 @@ inline namespace kernel } \ else \ { \ - throw std::invalid_argument("not a real number"); \ + return complex(apply(x.real()), \ + apply(x.imaginary())); \ } \ } \ } @@ -561,10 +562,17 @@ inline namespace kernel #define DEFINE(CMATH) \ struct CMATH \ { \ - template \ - auto operator ()(T&& x) const \ + template \ + auto operator ()(Number&& number) const \ { \ - return std::CMATH(inexact_cast(std::forward(x))); \ + if constexpr (std::is_same_v, complex>) \ + { \ + return std::CMATH(static_cast>(std::forward(number))); \ + } \ + else \ + { \ + return std::CMATH(inexact_cast(std::forward(number))); \ + } \ } \ } From 262f3617b334ba7a3d944a3598fd4de730549a46 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Sun, 4 Sep 2022 23:18:59 +0900 Subject: [PATCH 11/23] Fix `complex` external representation Signed-off-by: yamacir-kit --- README.md | 6 +- VERSION | 2 +- include/meevax/kernel/number.hpp | 150 ++++++++++++++++--------------- src/kernel/complex.cpp | 19 +++- src/kernel/library.cpp | 41 +++++---- 5 files changed, 117 insertions(+), 101 deletions(-) diff --git a/README.md b/README.md index 0c98f6b4c..dde00e1ff 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.219.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.220.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.219_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.220_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` @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.219 +Meevax Lisp System, version 0.4.220 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index a5ca32021..778a064ac 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.219 +0.4.220 diff --git a/include/meevax/kernel/number.hpp b/include/meevax/kernel/number.hpp index 7398f7bfc..223398e4c 100644 --- a/include/meevax/kernel/number.hpp +++ b/include/meevax/kernel/number.hpp @@ -181,32 +181,93 @@ inline namespace kernel auto operator /(const_reference, const_reference) -> value_type; auto operator %(const_reference, const_reference) -> value_type; + using plus = std::plus; + + using minus = std::minus; + + using multiplies = std::multiplies; + + using divides = std::divides; + + struct modulus + { + template + auto operator ()(T&& x, U&& y) const + { + if constexpr (std::is_floating_point_v> and + std::is_floating_point_v>) + { + return std::fmod(x, y); + } + else + { + return x % y; + } + } + }; + + struct equal_to + { + template + auto operator ()(T&& x, U&& y) const + { + if constexpr (std::is_floating_point_v> and + std::is_floating_point_v>) + { + if (std::isnan(x) and std::isnan(y)) + { + return true; + } + else if (std::isinf(x) or std::isinf(y)) + { + return x == y; + } + else + { + return std::abs(x - y) <= std::numeric_limits() - std::declval())>::epsilon(); + } + } + else + { + return x == y; + } + } + }; + + using less = std::less; + + using less_equal = std::less_equal; + + using greater = std::greater; + + using greater_equal = std::greater_equal; + template struct application { static inline constexpr F f {}; template - auto finish(T&& z) -> decltype(auto) + auto finish(T&& x) -> decltype(auto) { - if constexpr (std::is_same_v, value_type>) + if constexpr (std::is_same_v, value_type>) { - return std::forward(z); + return std::forward(x); } - else if constexpr (std::is_same_v, ratio>) + else if constexpr (std::is_same_v, ratio>) { - if (z.denominator() == 1) + if (x.denominator() == 1) { - return make(z.numerator()); + return make(x.numerator()); } else { - return make(std::forward(z)); + return make(std::forward(x)); } } else { - return make(std::forward(z)); + return make(std::forward(x)); } } @@ -305,67 +366,6 @@ inline namespace kernel } inline constexpr inexact_cast; - using plus = std::plus; - - using minus = std::minus; - - using multiplies = std::multiplies; - - using divides = std::divides; - - struct modulus - { - template - auto operator ()(T&& x, U&& y) const - { - if constexpr (std::is_floating_point_v> and std::is_floating_point_v>) - { - return std::fmod(x, y); - } - else - { - return x % y; - } - } - }; - - struct equal_to - { - template - auto operator ()(T&& x, U&& y) const - { - if constexpr (std::is_floating_point_v> and std::is_floating_point_v>) - { - if (std::isnan(x) and std::isnan(y)) - { - return true; - } - else if (std::isinf(x) or std::isinf(y)) - { - return x == y; - } - else - { - return std::abs(x - y) <= std::numeric_limits() - std::declval())>::epsilon(); - } - } - else - { - return x == y; - } - } - }; - - using not_equal_to = std::not_equal_to; - - using less = std::less; - - using less_equal = std::less_equal; - - using greater = std::greater; - - using greater_equal = std::greater_equal; - struct is_complex { template @@ -562,16 +562,18 @@ inline namespace kernel #define DEFINE(CMATH) \ struct CMATH \ { \ - template \ - auto operator ()(Number&& number) const \ + template \ + auto operator ()(T&& x) const \ { \ - if constexpr (std::is_same_v, complex>) \ + if constexpr (std::is_same_v, complex>) \ { \ - return std::CMATH(static_cast>(std::forward(number))); \ + auto result = std::CMATH(static_cast>(std::forward(x))); \ + return complex(make(result.real()), \ + make(result.imag())); \ } \ else \ { \ - return std::CMATH(inexact_cast(std::forward(number))); \ + return std::CMATH(inexact_cast(std::forward(x))); \ } \ } \ } diff --git a/src/kernel/complex.cpp b/src/kernel/complex.cpp index 22fe9b37c..fcb374949 100644 --- a/src/kernel/complex.cpp +++ b/src/kernel/complex.cpp @@ -25,8 +25,10 @@ inline namespace kernel { if (std::smatch result; std::regex_match(token, result, pattern())) { + auto&& i = result.str(2); + std::get<0>(*this) = string_to_real(result.str(1), radix); - std::get<1>(*this) = string_to_real(result.str(2), radix); + std::get<1>(*this) = string_to_real(not i.empty() and i[0] == '+' ? i.substr(1) : i, radix); } else { @@ -61,7 +63,20 @@ inline namespace kernel auto operator <<(std::ostream & os, complex const& z) -> std::ostream & { - return os << z.real() << cyan(apply(e0, z.imaginary()).as() ? "+" : "") << z.imaginary() << cyan("i"); + os << z.real(); + + if (apply(e0, z.imaginary()).as()) + { + return os; + } + else if (apply(e0, z.imaginary()).as()) + { + return os << cyan("+") << z.imaginary() << cyan("i"); + } + else + { + return os << z.imaginary() << cyan("i"); + } } } // namespace kernel } // namespace meevax diff --git a/src/kernel/library.cpp b/src/kernel/library.cpp index 998786f97..e3e8ef6f2 100644 --- a/src/kernel/library.cpp +++ b/src/kernel/library.cpp @@ -534,38 +534,37 @@ inline namespace kernel }) == std::end(xs); \ }) - DEFINE(= , equal_to ); - DEFINE(!=, std::not_equal_to ); - DEFINE(< , std::less ); - DEFINE(<=, std::less_equal ); - DEFINE(> , std::greater ); - DEFINE(>=, std::greater_equal); + DEFINE(= , equal_to ); + DEFINE(< , less ); + DEFINE(<=, less_equal ); + DEFINE(> , greater ); + DEFINE(>=, greater_equal); #undef DEFINE library.define("+", [](let const& xs) { - return std::accumulate(std::begin(xs), std::end(xs), e0, std::plus()); + return std::accumulate(std::begin(xs), std::end(xs), e0, plus()); }); library.define("*", [](let const& xs) { - return std::accumulate(std::begin(xs), std::end(xs), e1, std::multiplies()); + return std::accumulate(std::begin(xs), std::end(xs), e1, multiplies()); }); #define DEFINE(SYMBOL, FUNCTION, BASIS) \ library.define(SYMBOL, [](let const& xs) \ { \ - return cdr(xs).is() ? std::accumulate(std::begin(cdr(xs)), std::end(xs), car(xs), [](auto&& a, auto&& b) \ + return cdr(xs).is() ? std::accumulate(std::next(std::begin(xs)), std::end(xs), car(xs), [](auto&& a, auto&& b) \ { \ - return FUNCTION(a, b); \ + return FUNCTION()(a, b); \ }) \ - : FUNCTION(BASIS, car(xs)); \ + : FUNCTION()(BASIS, car(xs)); \ }) - DEFINE("-", std::minus (), e0); - DEFINE("/", std::divides(), e1); - DEFINE("%", std::modulus(), e1); + DEFINE("-", minus , e0); + DEFINE("/", divides, e1); + DEFINE("%", modulus, e1); #undef DEFINE @@ -1064,16 +1063,16 @@ inline namespace kernel return std::adjacent_find( \ std::begin(xs), std::end(xs), [](let const& a, let const& b) \ { \ - return not COMPARE(a.as_const().codepoints, \ - b.as_const().codepoints); \ + return not COMPARE()(a.as_const().codepoints, \ + b.as_const().codepoints); \ }) == std::end(xs); \ } - library.define("string=?", STRING_COMPARE(std::equal_to ())); - library.define("string())); - library.define("string<=?", STRING_COMPARE(std::less_equal ())); - library.define("string>?", STRING_COMPARE(std::greater ())); - library.define("string>=?", STRING_COMPARE(std::greater_equal())); + library.define("string=?", STRING_COMPARE(equal_to )); + library.define("string("string<=?", STRING_COMPARE(less_equal )); + library.define("string>?", STRING_COMPARE(greater )); + library.define("string>=?", STRING_COMPARE(greater_equal)); #undef STRING_COMPARE From 324a9d46ac35cfb1107fc88b1a3cc53952302cc1 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Sun, 4 Sep 2022 23:37:27 +0900 Subject: [PATCH 12/23] Rename `complex::imaginary` to `complex::imag` Signed-off-by: yamacir-kit --- README.md | 6 +++--- VERSION | 2 +- include/meevax/kernel/complex.hpp | 2 +- include/meevax/kernel/number.hpp | 21 +++++++++++---------- src/kernel/complex.cpp | 14 +++++++------- 5 files changed, 23 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index dde00e1ff..6f655260a 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.220.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.221.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.220_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.221_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` @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.220 +Meevax Lisp System, version 0.4.221 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 778a064ac..1e0628d57 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.220 +0.4.221 diff --git a/include/meevax/kernel/complex.hpp b/include/meevax/kernel/complex.hpp index 252547288..98aa6ba45 100644 --- a/include/meevax/kernel/complex.hpp +++ b/include/meevax/kernel/complex.hpp @@ -33,7 +33,7 @@ inline namespace kernel explicit complex(std::string const&, int = 10); - auto imaginary() const noexcept -> const_reference; + auto imag() const noexcept -> const_reference; static auto pattern() -> std::regex const&; diff --git a/include/meevax/kernel/number.hpp b/include/meevax/kernel/number.hpp index 223398e4c..7fdeb4266 100644 --- a/include/meevax/kernel/number.hpp +++ b/include/meevax/kernel/number.hpp @@ -250,11 +250,11 @@ inline namespace kernel template auto finish(T&& x) -> decltype(auto) { - if constexpr (std::is_same_v, value_type>) + if constexpr (std::is_same_v, value_type>) { return std::forward(x); } - else if constexpr (std::is_same_v, ratio>) + else if constexpr (std::is_same_v, ratio>) { if (x.denominator() == 1) { @@ -327,12 +327,12 @@ inline namespace kernel template auto operator ()(T&& x) const -> decltype(auto) { - if constexpr (std::is_same_v, complex>) + if constexpr (std::is_same_v, complex>) { return complex(apply(x.real()), - apply(x.imaginary())); + apply(x.imag())); } - else if constexpr (std::is_floating_point_v>) + else if constexpr (std::is_floating_point_v>) { return ratio(std::forward(x)); } @@ -352,7 +352,7 @@ inline namespace kernel if constexpr (std::is_same_v, complex>) { return complex(apply(x.real()), - apply(x.imaginary())); + apply(x.imag())); } else if constexpr (std::is_floating_point_v>) { @@ -395,7 +395,8 @@ inline namespace kernel } else { - return std::is_same_v, exact_integer> or std::is_same_v, ratio>; + return std::is_same_v, exact_integer> or + std::is_same_v, ratio>; } } }; @@ -427,7 +428,7 @@ inline namespace kernel { if constexpr (std::is_same_v, complex>) { - return apply(x.real()) or apply(x.imaginary()); + return apply(x.real()) or apply(x.imag()); } else if constexpr (std::is_floating_point_v>) { @@ -456,7 +457,7 @@ inline namespace kernel { if constexpr (std::is_same_v, complex>) { - return apply(x.real()) or apply(x.imaginary()); + return apply(x.real()) or apply(x.imag()); } else if constexpr (std::is_floating_point_v>) { @@ -547,7 +548,7 @@ inline namespace kernel else \ { \ return complex(apply(x.real()), \ - apply(x.imaginary())); \ + apply(x.imag())); \ } \ } \ } diff --git a/src/kernel/complex.cpp b/src/kernel/complex.cpp index fcb374949..42325c13f 100644 --- a/src/kernel/complex.cpp +++ b/src/kernel/complex.cpp @@ -36,7 +36,7 @@ inline namespace kernel } } - auto complex::imaginary() const noexcept -> const_reference + auto complex::imag() const noexcept -> const_reference { return second; } @@ -55,27 +55,27 @@ inline namespace kernel complex::operator std::complex() { assert(apply(real())); - assert(apply(imaginary())); + assert(apply(imag())); return std::complex(apply(real()).as(), - apply(imaginary()).as()); + apply(imag()).as()); } auto operator <<(std::ostream & os, complex const& z) -> std::ostream & { os << z.real(); - if (apply(e0, z.imaginary()).as()) + if (apply(e0, z.imag()).as()) { return os; } - else if (apply(e0, z.imaginary()).as()) + else if (apply(e0, z.imag()).as()) { - return os << cyan("+") << z.imaginary() << cyan("i"); + return os << cyan("+") << z.imag() << cyan("i"); } else { - return os << z.imaginary() << cyan("i"); + return os << z.imag() << cyan("i"); } } } // namespace kernel From c514577cab09671080b4ca05d20daa3da6e9072c Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Tue, 6 Sep 2022 00:37:10 +0900 Subject: [PATCH 13/23] Update `application::finish` to return real-part if imag-part is zero Signed-off-by: yamacir-kit --- README.md | 6 +++--- VERSION | 2 +- include/meevax/kernel/number.hpp | 11 +++++++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6f655260a..83a479a43 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.221.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.222.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.221_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.222_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` @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.221 +Meevax Lisp System, version 0.4.222 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 1e0628d57..ec524e1e0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.221 +0.4.222 diff --git a/include/meevax/kernel/number.hpp b/include/meevax/kernel/number.hpp index 7fdeb4266..472223cc3 100644 --- a/include/meevax/kernel/number.hpp +++ b/include/meevax/kernel/number.hpp @@ -254,6 +254,17 @@ inline namespace kernel { return std::forward(x); } + else if constexpr (std::is_same_v, complex>) + { + if (x.imag() == e0) + { + return make(x.real()); + } + else + { + return make(std::forward(x)); + } + } else if constexpr (std::is_same_v, ratio>) { if (x.denominator() == 1) From fda499e81ec273fa7d7e743b4d58fd14f348b8f4 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Sun, 11 Sep 2022 08:07:14 +0900 Subject: [PATCH 14/23] Support complex four arithmetic operations Signed-off-by: yamacir-kit --- README.md | 6 +++--- VERSION | 2 +- include/meevax/kernel/number.hpp | 6 ++++++ src/kernel/number.cpp | 7 ++++++- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 83a479a43..aa5849fd3 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.222.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.223.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.222_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.223_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` @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.222 +Meevax Lisp System, version 0.4.223 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index ec524e1e0..4a9b1e7ab 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.222 +0.4.223 diff --git a/include/meevax/kernel/number.hpp b/include/meevax/kernel/number.hpp index 472223cc3..307518cc6 100644 --- a/include/meevax/kernel/number.hpp +++ b/include/meevax/kernel/number.hpp @@ -175,6 +175,12 @@ inline namespace kernel auto operator > (double, ratio const&) -> bool; auto operator >=(double, ratio const&) -> bool; + auto operator + (complex const&, complex const&) -> complex; + auto operator - (complex const&, complex const&) -> complex; + auto operator * (complex const&, complex const&) -> complex; + auto operator / (complex const&, complex const&) -> complex; + auto operator % (complex const&, complex const&) -> complex; + auto operator +(const_reference, const_reference) -> value_type; auto operator -(const_reference, const_reference) -> value_type; auto operator *(const_reference, const_reference) -> value_type; diff --git a/src/kernel/number.cpp b/src/kernel/number.cpp index 2ab4bfabf..b70f604bb 100644 --- a/src/kernel/number.cpp +++ b/src/kernel/number.cpp @@ -14,7 +14,6 @@ limitations under the License. */ -#include #include namespace meevax @@ -165,6 +164,12 @@ inline namespace kernel auto operator > (double a, ratio const& b) -> bool { return a > inexact_cast(b); } auto operator >=(double a, ratio const& b) -> bool { return a >= inexact_cast(b); } + auto operator + (complex const& a, complex const& b) -> complex { return complex(a.real() + b.real(), a.imag() + b.imag()); } + auto operator - (complex const& a, complex const& b) -> complex { return complex(a.real() - b.real(), a.imag() - b.imag()); } + auto operator * (complex const& a, complex const& b) -> complex { return complex(a.real() * b.real() - a.imag() * b.imag(), a.imag() * b.real() + a.real() * b.imag()); } + auto operator / (complex const& a, complex const& b) -> complex { auto x = a.real() * b.real() + a.imag() * b.imag(); auto y = a.imag() * b.real() - a.real() * b.imag(); auto d = b.real() * b.real() + b.imag() * b.imag(); return complex(x / d, y / d); } + auto operator % (complex const& , complex const& ) -> complex { throw std::invalid_argument("unsupported operation"); } + auto operator +(const_reference x, const_reference y) -> value_type { return apply(x, y); } auto operator -(const_reference x, const_reference y) -> value_type { return apply(x, y); } auto operator *(const_reference x, const_reference y) -> value_type { return apply(x, y); } From d978c54d99c3be23347c0e52ec0828c57a1729e6 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Mon, 12 Sep 2022 23:53:08 +0900 Subject: [PATCH 15/23] Update binary arithmetic operations to support `complex` Signed-off-by: yamacir-kit --- README.md | 6 +- VERSION | 2 +- include/meevax/kernel/number.hpp | 148 +++++++++++++++++++++++++++---- src/kernel/number.cpp | 112 +++++++++++++++++++++-- 4 files changed, 244 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index aa5849fd3..197133c50 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.223.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.224.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.223_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.224_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` @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.223 +Meevax Lisp System, version 0.4.224 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 4a9b1e7ab..bd68ae9b8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.223 +0.4.224 diff --git a/include/meevax/kernel/number.hpp b/include/meevax/kernel/number.hpp index 307518cc6..76cf6410b 100644 --- a/include/meevax/kernel/number.hpp +++ b/include/meevax/kernel/number.hpp @@ -79,6 +79,18 @@ inline namespace kernel auto operator > (exact_integer const&, double) -> bool; auto operator >=(exact_integer const&, double) -> bool; + auto operator * (exact_integer const&, complex const&) -> complex; + auto operator + (exact_integer const&, complex const&) -> complex; + auto operator - (exact_integer const&, complex const&) -> complex; + auto operator / (exact_integer const&, complex const&) -> complex; + auto operator % (exact_integer const&, complex const&) -> complex; + auto operator ==(exact_integer const&, complex const&) -> bool; + auto operator !=(exact_integer const&, complex const&) -> bool; + auto operator < (exact_integer const&, complex const&) -> bool; + auto operator <=(exact_integer const&, complex const&) -> bool; + auto operator > (exact_integer const&, complex const&) -> bool; + auto operator >=(exact_integer const&, complex const&) -> bool; + auto operator * (ratio const&, exact_integer const&) -> ratio; auto operator + (ratio const&, exact_integer const&) -> ratio; auto operator - (ratio const&, exact_integer const&) -> ratio; @@ -127,6 +139,18 @@ inline namespace kernel auto operator > (ratio const&, double) -> bool; auto operator >=(ratio const&, double) -> bool; + auto operator + (ratio const&, complex const&) -> complex; + auto operator - (ratio const&, complex const&) -> complex; + auto operator * (ratio const&, complex const&) -> complex; + auto operator / (ratio const&, complex const&) -> complex; + auto operator % (ratio const&, complex const&) -> complex; + auto operator ==(ratio const&, complex const&) -> bool; + auto operator !=(ratio const&, complex const&) -> bool; + auto operator < (ratio const&, complex const&) -> bool; + auto operator <=(ratio const&, complex const&) -> bool; + auto operator > (ratio const&, complex const&) -> bool; + auto operator >=(ratio const&, complex const&) -> bool; + auto operator + (float, exact_integer const&) -> float; auto operator - (float, exact_integer const&) -> float; auto operator * (float, exact_integer const&) -> float; @@ -151,6 +175,18 @@ inline namespace kernel auto operator > (float, ratio const&) -> bool; auto operator >=(float, ratio const&) -> bool; + auto operator + (float, complex const&) -> complex; + auto operator - (float, complex const&) -> complex; + auto operator * (float, complex const&) -> complex; + auto operator / (float, complex const&) -> complex; + auto operator % (float, complex const&) -> complex; + auto operator ==(float, complex const&) -> bool; + auto operator !=(float, complex const&) -> bool; + auto operator < (float, complex const&) -> bool; + auto operator <=(float, complex const&) -> bool; + auto operator > (float, complex const&) -> bool; + auto operator >=(float, complex const&) -> bool; + auto operator + (double, exact_integer const&) -> double; auto operator - (double, exact_integer const&) -> double; auto operator * (double, exact_integer const&) -> double; @@ -175,17 +211,83 @@ inline namespace kernel auto operator > (double, ratio const&) -> bool; auto operator >=(double, ratio const&) -> bool; + auto operator + (double, complex const&) -> complex; + auto operator - (double, complex const&) -> complex; + auto operator * (double, complex const&) -> complex; + auto operator / (double, complex const&) -> complex; + auto operator % (double, complex const&) -> complex; + auto operator ==(double, complex const&) -> bool; + auto operator !=(double, complex const&) -> bool; + auto operator < (double, complex const&) -> bool; + auto operator <=(double, complex const&) -> bool; + auto operator > (double, complex const&) -> bool; + auto operator >=(double, complex const&) -> bool; + auto operator + (complex const&, complex const&) -> complex; auto operator - (complex const&, complex const&) -> complex; auto operator * (complex const&, complex const&) -> complex; auto operator / (complex const&, complex const&) -> complex; auto operator % (complex const&, complex const&) -> complex; - - auto operator +(const_reference, const_reference) -> value_type; - auto operator -(const_reference, const_reference) -> value_type; - auto operator *(const_reference, const_reference) -> value_type; - auto operator /(const_reference, const_reference) -> value_type; - auto operator %(const_reference, const_reference) -> value_type; + auto operator ==(complex const&, complex const&) -> bool; + auto operator !=(complex const&, complex const&) -> bool; + auto operator < (complex const&, complex const&) -> bool; + auto operator <=(complex const&, complex const&) -> bool; + auto operator > (complex const&, complex const&) -> bool; + auto operator >=(complex const&, complex const&) -> bool; + + auto operator + (complex const&, float) -> complex; + auto operator - (complex const&, float) -> complex; + auto operator * (complex const&, float) -> complex; + auto operator / (complex const&, float) -> complex; + auto operator % (complex const&, float) -> complex; + auto operator ==(complex const&, float) -> bool; + auto operator !=(complex const&, float) -> bool; + auto operator < (complex const&, float) -> bool; + auto operator <=(complex const&, float) -> bool; + auto operator > (complex const&, float) -> bool; + auto operator >=(complex const&, float) -> bool; + + auto operator + (complex const&, double) -> complex; + auto operator - (complex const&, double) -> complex; + auto operator * (complex const&, double) -> complex; + auto operator / (complex const&, double) -> complex; + auto operator % (complex const&, double) -> complex; + auto operator ==(complex const&, double) -> bool; + auto operator !=(complex const&, double) -> bool; + auto operator < (complex const&, double) -> bool; + auto operator <=(complex const&, double) -> bool; + auto operator > (complex const&, double) -> bool; + auto operator >=(complex const&, double) -> bool; + + auto operator + (complex const&, ratio const&) -> complex; + auto operator - (complex const&, ratio const&) -> complex; + auto operator * (complex const&, ratio const&) -> complex; + auto operator / (complex const&, ratio const&) -> complex; + auto operator % (complex const&, ratio const&) -> complex; + auto operator ==(complex const&, ratio const&) -> bool; + auto operator !=(complex const&, ratio const&) -> bool; + auto operator < (complex const&, ratio const&) -> bool; + auto operator <=(complex const&, ratio const&) -> bool; + auto operator > (complex const&, ratio const&) -> bool; + auto operator >=(complex const&, ratio const&) -> bool; + + auto operator + (complex const&, exact_integer const&) -> complex; + auto operator - (complex const&, exact_integer const&) -> complex; + auto operator * (complex const&, exact_integer const&) -> complex; + auto operator / (complex const&, exact_integer const&) -> complex; + auto operator % (complex const&, exact_integer const&) -> complex; + auto operator ==(complex const&, exact_integer const&) -> bool; + auto operator !=(complex const&, exact_integer const&) -> bool; + auto operator < (complex const&, exact_integer const&) -> bool; + auto operator <=(complex const&, exact_integer const&) -> bool; + auto operator > (complex const&, exact_integer const&) -> bool; + auto operator >=(complex const&, exact_integer const&) -> bool; + + auto operator + (const_reference, const_reference) -> value_type; + auto operator - (const_reference, const_reference) -> value_type; + auto operator * (const_reference, const_reference) -> value_type; + auto operator / (const_reference, const_reference) -> value_type; + auto operator % (const_reference, const_reference) -> value_type; using plus = std::plus; @@ -328,10 +430,11 @@ inline namespace kernel std::function > apply { - APPLY(exact_integer, exact_integer), APPLY(exact_integer, ratio), APPLY(exact_integer, float), APPLY(exact_integer, double), - APPLY(ratio, exact_integer), APPLY(ratio, ratio), APPLY(ratio, float), APPLY(ratio, double), - APPLY(float, exact_integer), APPLY(float, ratio), APPLY(float, float), APPLY(float, double), - APPLY(double, exact_integer), APPLY(double, ratio), APPLY(double, float), APPLY(double, double), + APPLY(exact_integer, exact_integer), APPLY(exact_integer, ratio), APPLY(exact_integer, float), APPLY(exact_integer, double), APPLY(exact_integer, complex), + APPLY(ratio, exact_integer), APPLY(ratio, ratio), APPLY(ratio, float), APPLY(ratio, double), APPLY(ratio, complex), + APPLY(float, exact_integer), APPLY(float, ratio), APPLY(float, float), APPLY(float, double), APPLY(float, complex), + APPLY(double, exact_integer), APPLY(double, ratio), APPLY(double, float), APPLY(double, double), APPLY(double, complex), + APPLY(complex, exact_integer), APPLY(complex, ratio), APPLY(complex, float), APPLY(complex, double), APPLY(complex, complex), }; #undef APPLY @@ -519,8 +622,14 @@ inline namespace kernel template auto operator ()(Base&& base, Exponent&& exponent) const -> decltype(auto) { - if constexpr (std::is_same_v, exact_integer> and - std::is_same_v, exact_integer>) + if constexpr (std::is_same_v, complex> or + std::is_same_v, complex>) + { + throw std::invalid_argument("unsupported operation"); // TODO + return e0; + } + else if constexpr (std::is_same_v, exact_integer> and + std::is_same_v, exact_integer>) { exact_integer result {}; mpz_pow_ui(result.value, base.value, static_cast(exponent)); @@ -537,10 +646,19 @@ inline namespace kernel struct atan2 { template - auto operator ()(T&& x, U&& y) const + auto operator ()(T&& x, U&& y) const -> decltype(auto) { - return std::atan2(inexact_cast(std::forward(x)), - inexact_cast(std::forward(y))); + if constexpr (std::is_same_v, complex> or + std::is_same_v, complex>) + { + throw std::invalid_argument("unsupported operation"); + return e0; // dummy return value. + } + else + { + return std::atan2(inexact_cast(std::forward(x)), + inexact_cast(std::forward(y))); + } } }; diff --git a/src/kernel/number.cpp b/src/kernel/number.cpp index b70f604bb..2f360aaac 100644 --- a/src/kernel/number.cpp +++ b/src/kernel/number.cpp @@ -68,6 +68,18 @@ inline namespace kernel auto operator > (exact_integer const& a, double b) -> bool { return mpz_cmp_d(a.value, b) > 0; } auto operator >=(exact_integer const& a, double b) -> bool { return mpz_cmp_d(a.value, b) >= 0; } + auto operator + (exact_integer const& a, complex const& b) -> complex { return complex(make(a), e0) + b; } + auto operator - (exact_integer const& a, complex const& b) -> complex { return complex(make(a), e0) - b; } + auto operator * (exact_integer const& a, complex const& b) -> complex { return complex(make(a), e0) * b; } + auto operator / (exact_integer const& a, complex const& b) -> complex { return complex(make(a), e0) / b; } + auto operator % (exact_integer const& , complex const& ) -> complex { throw std::invalid_argument("unsupported operation"); } + auto operator ==(exact_integer const& a, complex const& b) -> bool { return complex(make(a), e0) == b; } + auto operator !=(exact_integer const& a, complex const& b) -> bool { return complex(make(a), e0) != b; } + auto operator < (exact_integer const& , complex const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator <=(exact_integer const& , complex const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator > (exact_integer const& , complex const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator >=(exact_integer const& , complex const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator + (ratio const& a, exact_integer const& b) -> ratio { ratio q; mpq_add(q.value, a.value, ratio(b).value); return q; } auto operator - (ratio const& a, exact_integer const& b) -> ratio { ratio q; mpq_sub(q.value, a.value, ratio(b).value); return q; } auto operator * (ratio const& a, exact_integer const& b) -> ratio { ratio q; mpq_mul(q.value, a.value, ratio(b).value); return q; } @@ -116,6 +128,18 @@ inline namespace kernel auto operator > (ratio const& a, double b) -> bool { return inexact_cast(a) > b; } auto operator >=(ratio const& a, double b) -> bool { return inexact_cast(a) >= b; } + auto operator + (ratio const& a, complex const& b) -> complex { return complex(make(a), e0) + b; } + auto operator - (ratio const& a, complex const& b) -> complex { return complex(make(a), e0) - b; } + auto operator * (ratio const& a, complex const& b) -> complex { return complex(make(a), e0) * b; } + auto operator / (ratio const& a, complex const& b) -> complex { return complex(make(a), e0) / b; } + auto operator % (ratio const& , complex const& ) -> complex { throw std::invalid_argument("unsupported operation"); } + auto operator ==(ratio const& a, complex const& b) -> bool { return complex(make(a), e0) == b; } + auto operator !=(ratio const& a, complex const& b) -> bool { return complex(make(a), e0) != b; } + auto operator < (ratio const& , complex const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator <=(ratio const& , complex const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator > (ratio const& , complex const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator >=(ratio const& , complex const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator + (float a, exact_integer const& b) -> float { return a + inexact_cast(b); } auto operator - (float a, exact_integer const& b) -> float { return a - inexact_cast(b); } auto operator * (float a, exact_integer const& b) -> float { return a * inexact_cast(b); } @@ -140,6 +164,18 @@ inline namespace kernel auto operator > (float a, ratio const& b) -> bool { return a > inexact_cast(b); } auto operator >=(float a, ratio const& b) -> bool { return a >= inexact_cast(b); } + auto operator + (float a, complex const& b) -> complex { return complex(make(a), e0) + b; } + auto operator - (float a, complex const& b) -> complex { return complex(make(a), e0) - b; } + auto operator * (float a, complex const& b) -> complex { return complex(make(a), e0) * b; } + auto operator / (float a, complex const& b) -> complex { return complex(make(a), e0) / b; } + auto operator % (float , complex const& ) -> complex { throw std::invalid_argument("unsupported operation"); } + auto operator ==(float a, complex const& b) -> bool { return complex(make(a), e0) == b; } + auto operator !=(float a, complex const& b) -> bool { return complex(make(a), e0) != b; } + auto operator < (float , complex const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator <=(float , complex const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator > (float , complex const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator >=(float , complex const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator + (double a, exact_integer const& b) -> double { return a + inexact_cast(b); } auto operator - (double a, exact_integer const& b) -> double { return a - inexact_cast(b); } auto operator * (double a, exact_integer const& b) -> double { return a * inexact_cast(b); } @@ -164,16 +200,82 @@ inline namespace kernel auto operator > (double a, ratio const& b) -> bool { return a > inexact_cast(b); } auto operator >=(double a, ratio const& b) -> bool { return a >= inexact_cast(b); } + auto operator + (double a, complex const& b) -> complex { return complex(make(a), e0) + b; } + auto operator - (double a, complex const& b) -> complex { return complex(make(a), e0) - b; } + auto operator * (double a, complex const& b) -> complex { return complex(make(a), e0) * b; } + auto operator / (double a, complex const& b) -> complex { return complex(make(a), e0) / b; } + auto operator % (double , complex const& ) -> complex { throw std::invalid_argument("unsupported operation"); } + auto operator ==(double a, complex const& b) -> bool { return complex(make(a), e0) == b; } + auto operator !=(double a, complex const& b) -> bool { return complex(make(a), e0) != b; } + auto operator < (double , complex const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator <=(double , complex const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator > (double , complex const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator >=(double , complex const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator + (complex const& a, complex const& b) -> complex { return complex(a.real() + b.real(), a.imag() + b.imag()); } auto operator - (complex const& a, complex const& b) -> complex { return complex(a.real() - b.real(), a.imag() - b.imag()); } auto operator * (complex const& a, complex const& b) -> complex { return complex(a.real() * b.real() - a.imag() * b.imag(), a.imag() * b.real() + a.real() * b.imag()); } auto operator / (complex const& a, complex const& b) -> complex { auto x = a.real() * b.real() + a.imag() * b.imag(); auto y = a.imag() * b.real() - a.real() * b.imag(); auto d = b.real() * b.real() + b.imag() * b.imag(); return complex(x / d, y / d); } auto operator % (complex const& , complex const& ) -> complex { throw std::invalid_argument("unsupported operation"); } + auto operator ==(complex const& a, complex const& b) -> bool { return apply(a.real(), b.real()) and apply(a.imag(), b.imag()); } + auto operator !=(complex const& a, complex const& b) -> bool { return not (a == b); } + auto operator < (complex const& , complex const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator <=(complex const& , complex const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator > (complex const& , complex const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator >=(complex const& , complex const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + + auto operator + (complex const& a, float b) -> complex { return a + complex(make(b), e0); } + auto operator - (complex const& a, float b) -> complex { return a - complex(make(b), e0); } + auto operator * (complex const& a, float b) -> complex { return a * complex(make(b), e0); } + auto operator / (complex const& a, float b) -> complex { return a / complex(make(b), e0); } + auto operator % (complex const& , float ) -> complex { throw std::invalid_argument("unsupported operation"); } + auto operator ==(complex const& a, float b) -> bool { return a == complex(make(b), e0); } + auto operator !=(complex const& a, float b) -> bool { return a != complex(make(b), e0); } + auto operator < (complex const& , float ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator <=(complex const& , float ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator > (complex const& , float ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator >=(complex const& , float ) -> bool { throw std::invalid_argument("unsupported operation"); } + + auto operator + (complex const& a, double b) -> complex { return a + complex(make(b), e0); } + auto operator - (complex const& a, double b) -> complex { return a - complex(make(b), e0); } + auto operator * (complex const& a, double b) -> complex { return a * complex(make(b), e0); } + auto operator / (complex const& a, double b) -> complex { return a / complex(make(b), e0); } + auto operator % (complex const& , double ) -> complex { throw std::invalid_argument("unsupported operation"); } + auto operator ==(complex const& a, double b) -> bool { return a == complex(make(b), e0); } + auto operator !=(complex const& a, double b) -> bool { return a != complex(make(b), e0); } + auto operator < (complex const& , double ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator <=(complex const& , double ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator > (complex const& , double ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator >=(complex const& , double ) -> bool { throw std::invalid_argument("unsupported operation"); } + + auto operator + (complex const& a, ratio const& b) -> complex { return a + complex(make(b), e0); } + auto operator - (complex const& a, ratio const& b) -> complex { return a - complex(make(b), e0); } + auto operator * (complex const& a, ratio const& b) -> complex { return a * complex(make(b), e0); } + auto operator / (complex const& a, ratio const& b) -> complex { return a / complex(make(b), e0); } + auto operator % (complex const& , ratio const& ) -> complex { throw std::invalid_argument("unsupported operation"); } + auto operator ==(complex const& a, ratio const& b) -> bool { return a == complex(make(b), e0); } + auto operator !=(complex const& a, ratio const& b) -> bool { return a != complex(make(b), e0); } + auto operator < (complex const& , ratio const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator <=(complex const& , ratio const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator > (complex const& , ratio const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator >=(complex const& , ratio const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + + auto operator + (complex const& a, exact_integer const& b) -> complex { return a + complex(make(b), e0); } + auto operator - (complex const& a, exact_integer const& b) -> complex { return a - complex(make(b), e0); } + auto operator * (complex const& a, exact_integer const& b) -> complex { return a * complex(make(b), e0); } + auto operator / (complex const& a, exact_integer const& b) -> complex { return a / complex(make(b), e0); } + auto operator % (complex const& , exact_integer const& ) -> complex { throw std::invalid_argument("unsupported operation"); } + auto operator ==(complex const& a, exact_integer const& b) -> bool { return a == complex(make(b), e0); } + auto operator !=(complex const& a, exact_integer const& b) -> bool { return a != complex(make(b), e0); } + auto operator < (complex const& , exact_integer const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator <=(complex const& , exact_integer const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator > (complex const& , exact_integer const& ) -> bool { throw std::invalid_argument("unsupported operation"); } + auto operator >=(complex const& , exact_integer const& ) -> bool { throw std::invalid_argument("unsupported operation"); } - auto operator +(const_reference x, const_reference y) -> value_type { return apply(x, y); } - auto operator -(const_reference x, const_reference y) -> value_type { return apply(x, y); } - auto operator *(const_reference x, const_reference y) -> value_type { return apply(x, y); } - auto operator /(const_reference x, const_reference y) -> value_type { return apply(x, y); } - auto operator %(const_reference x, const_reference y) -> value_type { return apply(x, y); } + auto operator + (const_reference x, const_reference y) -> value_type { return apply(x, y); } + auto operator - (const_reference x, const_reference y) -> value_type { return apply(x, y); } + auto operator * (const_reference x, const_reference y) -> value_type { return apply(x, y); } + auto operator / (const_reference x, const_reference y) -> value_type { return apply(x, y); } + auto operator % (const_reference x, const_reference y) -> value_type { return apply(x, y); } } // namespace kernel } // namespace meevax From 71faa222d11f66f2abab0c9212febd5347a0b2e1 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Tue, 13 Sep 2022 00:50:29 +0900 Subject: [PATCH 16/23] Fix `is_real` and `is_integer` to work correctly Signed-off-by: yamacir-kit --- README.md | 6 +++--- VERSION | 2 +- include/meevax/kernel/number.hpp | 19 +++++++++++++++---- src/kernel/complex.cpp | 2 +- test/r7rs.ss | 12 ++++++------ 5 files changed, 26 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 197133c50..68030d3f7 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.224.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.225.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.224_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.225_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` @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.224 +Meevax Lisp System, version 0.4.225 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index bd68ae9b8..c05ea64e5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.224 +0.4.225 diff --git a/include/meevax/kernel/number.hpp b/include/meevax/kernel/number.hpp index 76cf6410b..886b96f98 100644 --- a/include/meevax/kernel/number.hpp +++ b/include/meevax/kernel/number.hpp @@ -498,9 +498,16 @@ inline namespace kernel struct is_real { template - constexpr auto operator ()(T&&) const + constexpr auto operator ()(T&& x) const { - return not std::is_same_v, complex>; + if constexpr (std::is_same_v, complex>) + { + return apply(x.imag(), e0).template as(); + } + else + { + return true; + } } }; @@ -524,9 +531,13 @@ inline namespace kernel struct is_integer { template - auto operator ()(T&& x) const + constexpr auto operator ()(T&& x) const { - if constexpr (std::is_floating_point_v>) + if constexpr (std::is_same_v, complex>) + { + return apply(x.imag(), e0).template as() and apply(x.real()).template as(); + } + else if constexpr (std::is_floating_point_v>) { return x == std::trunc(x); } diff --git a/src/kernel/complex.cpp b/src/kernel/complex.cpp index 42325c13f..8e30da2a1 100644 --- a/src/kernel/complex.cpp +++ b/src/kernel/complex.cpp @@ -65,7 +65,7 @@ inline namespace kernel { os << z.real(); - if (apply(e0, z.imag()).as()) + if (apply(z.imag(), e0).as()) { return os; } diff --git a/test/r7rs.ss b/test/r7rs.ss index 3fa3da2af..4f6659226 100644 --- a/test/r7rs.ss +++ b/test/r7rs.ss @@ -438,7 +438,7 @@ ; (define range ; (case-lambda ; ((e) (range 0 e)) -; ((b e) (do ((r ’() (cons e r)) +; ((b e) (do ((r '() (cons e r)) ; (e (- e 1) (- e 1))) ; ((< e b) r))))) @@ -826,15 +826,15 @@ ; ---- 6.2.6. ------------------------------------------------------------------ -; (check (complex? 3+4i) => #t) +(check (complex? 3+4i) => #t) (check (complex? 3) => #t) (check (real? 3) => #t) -; (check (real? -2.5+0i) => #t) +(check (real? -2.5+0i) => #t) -; (check (real? -2.5+0.0i) => #t) +(check (real? -2.5+0.0i) => #t) (check (real? #e1e10) => #t) @@ -850,7 +850,7 @@ (check (rational? 6/3) => #t) -; (check (integer? 3+0i) => #t) +(check (integer? 3+0i) => #t) (check (integer? 3.0) => #t) @@ -1555,4 +1555,4 @@ (check-report) -(exit (check-passed? 383)) +(exit (check-passed? 387)) From e16700c7a90cfcc366850ddfbdb720ed4c4618b1 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Tue, 13 Sep 2022 01:50:11 +0900 Subject: [PATCH 17/23] Fix complex I/O to accept infinity and NaN Signed-off-by: yamacir-kit --- README.md | 6 ++--- VERSION | 2 +- include/meevax/kernel/number.hpp | 6 +++-- include/meevax/memory/nan_boxing_pointer.hpp | 6 ++--- src/kernel/complex.cpp | 23 +++++++++++++------- src/kernel/exact_integer.cpp | 2 +- test/r7rs.ss | 10 ++++----- 7 files changed, 32 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 68030d3f7..46dbc96a7 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.225.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.226.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.225_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.226_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` @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.225 +Meevax Lisp System, version 0.4.226 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index c05ea64e5..b376a3cc8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.225 +0.4.226 diff --git a/include/meevax/kernel/number.hpp b/include/meevax/kernel/number.hpp index 886b96f98..f67d8d495 100644 --- a/include/meevax/kernel/number.hpp +++ b/include/meevax/kernel/number.hpp @@ -559,7 +559,8 @@ inline namespace kernel { if constexpr (std::is_same_v, complex>) { - return apply(x.real()) or apply(x.imag()); + return apply(x.real()).template as() or + apply(x.imag()).template as(); } else if constexpr (std::is_floating_point_v>) { @@ -588,7 +589,8 @@ inline namespace kernel { if constexpr (std::is_same_v, complex>) { - return apply(x.real()) or apply(x.imag()); + return apply(x.real()).template as() or + apply(x.imag()).template as(); } else if constexpr (std::is_floating_point_v>) { diff --git a/include/meevax/memory/nan_boxing_pointer.hpp b/include/meevax/memory/nan_boxing_pointer.hpp index 94a4b7025..7067effc9 100644 --- a/include/meevax/memory/nan_boxing_pointer.hpp +++ b/include/meevax/memory/nan_boxing_pointer.hpp @@ -221,15 +221,15 @@ inline namespace memory default: if (auto value = as(); std::isnan(value)) { - return os << yellow("+nan.0"); + return os << cyan("+nan.0"); } else if (std::isinf(value)) { - return os << yellow(0 < value ? '+' : '-', "inf.0"); + return os << cyan(0 < value ? '+' : '-', "inf.0"); } else { - return os << std::fixed << std::setprecision(17) << yellow(value); + return os << std::fixed << std::setprecision(17) << cyan(value); } } } diff --git a/src/kernel/complex.cpp b/src/kernel/complex.cpp index 8e30da2a1..145c2254f 100644 --- a/src/kernel/complex.cpp +++ b/src/kernel/complex.cpp @@ -25,10 +25,8 @@ inline namespace kernel { if (std::smatch result; std::regex_match(token, result, pattern())) { - auto&& i = result.str(2); - std::get<0>(*this) = string_to_real(result.str(1), radix); - std::get<1>(*this) = string_to_real(not i.empty() and i[0] == '+' ? i.substr(1) : i, radix); + std::get<1>(*this) = string_to_real(result.str(2), radix); } else { @@ -69,13 +67,22 @@ inline namespace kernel { return os; } - else if (apply(e0, z.imag()).as()) - { - return os << cyan("+") << z.imag() << cyan("i"); - } else { - return os << z.imag() << cyan("i"); + auto explicitly_signed = [](auto const& number) + { + switch (auto const s = lexical_cast(number); s[0]) + { + case '+': + case '-': + return s; + + default: + return "+" + s; + } + }; + + return os << cyan(explicitly_signed(z.imag()), "i"); } } } // namespace kernel diff --git a/src/kernel/exact_integer.cpp b/src/kernel/exact_integer.cpp index 3821fd2a4..8ef3c69fd 100644 --- a/src/kernel/exact_integer.cpp +++ b/src/kernel/exact_integer.cpp @@ -73,7 +73,7 @@ inline namespace kernel exact_integer::exact_integer(std::string const& s, int radix) { - if (mpz_init_set_str(value, s.c_str(), radix)) + if (mpz_init_set_str(value, (s.at(0) == '+' ? s.substr(1) : s).c_str(), radix)) { mpz_clear(value); throw std::invalid_argument("not a integer"); diff --git a/test/r7rs.ss b/test/r7rs.ss index 4f6659226..ced304e7c 100644 --- a/test/r7rs.ss +++ b/test/r7rs.ss @@ -872,7 +872,7 @@ (check (finite? +inf.0) => #f) -; (check (finite? 3.0+inf.0i) => #f) +(check (finite? 3.0+inf.0i) => #f) (check (infinite? 3) => #f) @@ -880,15 +880,15 @@ (check (infinite? +nan.0) => #f) -; (check (infinite? 3.0+inf.0i) => #t) +(check (infinite? 3.0+inf.0i) => #t) (check (nan? +nan.0) => #t) (check (nan? 32) => #f) -; (check (nan? +nan.0+5.0i) => #t) +(check (nan? +nan.0+5.0i) => #t) -; (check (nan? 1+2i) => #f) +(check (nan? 1+2i) => #f) (check (zero? 0/1) => #t) @@ -1555,4 +1555,4 @@ (check-report) -(exit (check-passed? 387)) +(exit (check-passed? 391)) From fd3a017ccb2b654ec5a29e157a1b3cd5aa98c814 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Tue, 13 Sep 2022 02:55:39 +0900 Subject: [PATCH 18/23] Rename `application::finish` to `canonicalize` Signed-off-by: yamacir-kit --- README.md | 6 +++--- VERSION | 2 +- include/meevax/kernel/complex.hpp | 2 ++ include/meevax/kernel/number.hpp | 20 +++++++------------- src/kernel/complex.cpp | 18 ++++++++++++++---- src/kernel/number.cpp | 6 +++--- 6 files changed, 30 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 46dbc96a7..f93bcb968 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.226.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.227.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.226_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.227_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` @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.226 +Meevax Lisp System, version 0.4.227 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index b376a3cc8..9bc5ef719 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.226 +0.4.227 diff --git a/include/meevax/kernel/complex.hpp b/include/meevax/kernel/complex.hpp index 98aa6ba45..c08ff3c56 100644 --- a/include/meevax/kernel/complex.hpp +++ b/include/meevax/kernel/complex.hpp @@ -33,6 +33,8 @@ inline namespace kernel explicit complex(std::string const&, int = 10); + auto canonicalize() const -> value_type; + auto imag() const noexcept -> const_reference; static auto pattern() -> std::regex const&; diff --git a/include/meevax/kernel/number.hpp b/include/meevax/kernel/number.hpp index f67d8d495..24ac0f81b 100644 --- a/include/meevax/kernel/number.hpp +++ b/include/meevax/kernel/number.hpp @@ -356,7 +356,7 @@ inline namespace kernel static inline constexpr F f {}; template - auto finish(T&& x) -> decltype(auto) + auto canonicalize(T&& x) -> decltype(auto) { if constexpr (std::is_same_v, value_type>) { @@ -364,14 +364,7 @@ inline namespace kernel } else if constexpr (std::is_same_v, complex>) { - if (x.imag() == e0) - { - return make(x.real()); - } - else - { - return make(std::forward(x)); - } + return x.canonicalize(); } else if constexpr (std::is_same_v, ratio>) { @@ -392,13 +385,14 @@ inline namespace kernel auto operator ()(const_reference x) -> value_type { - return finish(f(x.as>>())); + return canonicalize(f(x.as>>())); } - auto operator ()(const_reference x, const_reference y) -> value_type + auto operator ()(const_reference x, + const_reference y) -> value_type { - return finish(f(x.as>>(), - y.as>>())); + return canonicalize(f(x.as>>(), + y.as>>())); } }; diff --git a/src/kernel/complex.cpp b/src/kernel/complex.cpp index 145c2254f..30c17d3ae 100644 --- a/src/kernel/complex.cpp +++ b/src/kernel/complex.cpp @@ -34,6 +34,18 @@ inline namespace kernel } } + auto complex::canonicalize() const -> value_type + { + if (apply(imag(), e0).as()) + { + return real(); + } + else + { + return make(*this); + } + } + auto complex::imag() const noexcept -> const_reference { return second; @@ -61,11 +73,9 @@ inline namespace kernel auto operator <<(std::ostream & os, complex const& z) -> std::ostream & { - os << z.real(); - if (apply(z.imag(), e0).as()) { - return os; + return os << z.real(); } else { @@ -82,7 +92,7 @@ inline namespace kernel } }; - return os << cyan(explicitly_signed(z.imag()), "i"); + return os << z.real() << cyan(explicitly_signed(z.imag()), "i"); } } } // namespace kernel diff --git a/src/kernel/number.cpp b/src/kernel/number.cpp index 2f360aaac..d0f102538 100644 --- a/src/kernel/number.cpp +++ b/src/kernel/number.cpp @@ -36,7 +36,7 @@ inline namespace kernel auto operator - (exact_integer const& a, ratio const& b) -> ratio { ratio q; mpq_sub(q.value, ratio(a).value, b.value); return q; } auto operator * (exact_integer const& a, ratio const& b) -> ratio { ratio q; mpq_mul(q.value, ratio(a).value, b.value); return q; } auto operator / (exact_integer const& a, ratio const& b) -> ratio { ratio q; mpq_div(q.value, ratio(a).value, b.value); return q; } - auto operator % (exact_integer const& , ratio const& ) -> ratio { throw error(make("unsupported operation"), unit); } + auto operator % (exact_integer const& , ratio const& ) -> ratio { throw std::invalid_argument("unsupported operation"); } auto operator ==(exact_integer const& a, ratio const& b) -> bool { return mpq_cmp_z(b.value, a.value) == 0; } auto operator !=(exact_integer const& a, ratio const& b) -> bool { return mpq_cmp_z(b.value, a.value) != 0; } auto operator < (exact_integer const& a, ratio const& b) -> bool { return mpq_cmp_z(b.value, a.value) > 0; } @@ -84,7 +84,7 @@ inline namespace kernel auto operator - (ratio const& a, exact_integer const& b) -> ratio { ratio q; mpq_sub(q.value, a.value, ratio(b).value); return q; } auto operator * (ratio const& a, exact_integer const& b) -> ratio { ratio q; mpq_mul(q.value, a.value, ratio(b).value); return q; } auto operator / (ratio const& a, exact_integer const& b) -> ratio { ratio q; mpq_div(q.value, a.value, ratio(b).value); return q; } - auto operator % (ratio const& , exact_integer const& ) -> ratio { throw error(make("unsupported operation"), unit); } + auto operator % (ratio const& , exact_integer const& ) -> ratio { throw std::invalid_argument("unsupported operation"); } auto operator ==(ratio const& a, exact_integer const& b) -> bool { return mpq_cmp_z(a.value, b.value) == 0; } auto operator !=(ratio const& a, exact_integer const& b) -> bool { return mpq_cmp_z(a.value, b.value) != 0; } auto operator < (ratio const& a, exact_integer const& b) -> bool { return mpq_cmp_z(a.value, b.value) < 0; } @@ -96,7 +96,7 @@ inline namespace kernel auto operator - (ratio const& a, ratio const& b) -> ratio { ratio q; mpq_sub(q.value, a.value, b.value); return q; } auto operator * (ratio const& a, ratio const& b) -> ratio { ratio q; mpq_mul(q.value, a.value, b.value); return q; } auto operator / (ratio const& a, ratio const& b) -> ratio { ratio q; mpq_div(q.value, a.value, b.value); return q; } - auto operator % (ratio const& , ratio const& ) -> ratio { throw error(make("unsupported operation"), unit); } + auto operator % (ratio const& , ratio const& ) -> ratio { throw std::invalid_argument("unsupported operation"); } auto operator ==(ratio const& a, ratio const& b) -> bool { return mpq_cmp(a.value, b.value) == 0; } auto operator !=(ratio const& a, ratio const& b) -> bool { return mpq_cmp(a.value, b.value) != 0; } auto operator < (ratio const& a, ratio const& b) -> bool { return mpq_cmp(a.value, b.value) < 0; } From 60cd0c049ed28d461d0aff52f03b83ce29e3fa0e Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Wed, 14 Sep 2022 02:35:20 +0900 Subject: [PATCH 19/23] Fix procedure `expt` to treat complex correctly Signed-off-by: yamacir-kit --- README.md | 6 ++-- VERSION | 2 +- basis/r7rs.ss | 13 +------ include/meevax/kernel/number.hpp | 59 +++++++++++++++++++------------- src/main.cpp | 11 +++++- 5 files changed, 51 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index f93bcb968..0e1de7d71 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.227.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.228.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.227_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.228_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` @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.227 +Meevax Lisp System, version 0.4.228 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 9bc5ef719..b250cf026 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.227 +0.4.228 diff --git a/basis/r7rs.ss b/basis/r7rs.ss index 7ab11c823..14ea8ebe2 100644 --- a/basis/r7rs.ss +++ b/basis/r7rs.ss @@ -433,18 +433,7 @@ (define-library (scheme inexact) (import (only (meevax inexact) finite? infinite? nan?) (only (scheme r5rs) exp log sin cos tan asin acos atan sqrt)) - (export finite? - infinite? - nan? - exp - log - sin - cos - tan - asin - acos - atan - sqrt)) + (export finite? infinite? nan? exp log sin cos tan asin acos atan sqrt)) (define-library (scheme complex) (export make-rectangular diff --git a/include/meevax/kernel/number.hpp b/include/meevax/kernel/number.hpp index 24ac0f81b..d2e15b38a 100644 --- a/include/meevax/kernel/number.hpp +++ b/include/meevax/kernel/number.hpp @@ -436,6 +436,23 @@ inline namespace kernel return apply.at(type_index<2>(x.type(), y.type()))(x, y); } + template + auto inexact_cast(T&& x) -> decltype(auto) + { + if constexpr (std::is_same_v, complex>) + { + return std::complex(std::forward(x)); + } + else if constexpr (std::is_floating_point_v>) + { + return std::forward(x); + } + else + { + return static_cast(std::forward(x)); + } + } + struct exact { template @@ -455,8 +472,7 @@ inline namespace kernel return std::forward(x); } } - } - inline constexpr exact_cast; + }; struct inexact { @@ -468,17 +484,12 @@ inline namespace kernel return complex(apply(x.real()), apply(x.imag())); } - else if constexpr (std::is_floating_point_v>) - { - return std::forward(x); - } else { - return static_cast(std::forward(x)); + return inexact_cast(std::forward(x)); } } - } - inline constexpr inexact_cast; + }; struct is_complex { @@ -626,26 +637,28 @@ inline namespace kernel struct expt { - template - auto operator ()(Base&& base, Exponent&& exponent) const -> decltype(auto) + template + auto operator ()(T&& x, U&& y) const -> decltype(auto) { - if constexpr (std::is_same_v, complex> or - std::is_same_v, complex>) + if constexpr (std::is_same_v, complex> or + std::is_same_v, complex>) { - throw std::invalid_argument("unsupported operation"); // TODO - return e0; + auto const z = std::pow(inexact_cast(std::forward(x)), + inexact_cast(std::forward(y))); + return complex(make(z.real()), + make(z.imag())); } - else if constexpr (std::is_same_v, exact_integer> and - std::is_same_v, exact_integer>) + else if constexpr (std::is_same_v, exact_integer> and + std::is_same_v, exact_integer>) { exact_integer result {}; - mpz_pow_ui(result.value, base.value, static_cast(exponent)); + mpz_pow_ui(result.value, x.value, static_cast(y)); return result; } else { - return std::pow(inexact_cast(std::forward(base)), - inexact_cast(std::forward(exponent))); + return std::pow(inexact_cast(std::forward(x)), + inexact_cast(std::forward(y))); } } }; @@ -710,9 +723,9 @@ inline namespace kernel { \ if constexpr (std::is_same_v, complex>) \ { \ - auto result = std::CMATH(static_cast>(std::forward(x))); \ - return complex(make(result.real()), \ - make(result.imag())); \ + auto const z = std::CMATH(inexact_cast(std::forward(x))); \ + return complex(make(z.real()), \ + make(z.imag())); \ } \ else \ { \ diff --git a/src/main.cpp b/src/main.cpp index 1588f98a1..f527bca40 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -33,7 +33,16 @@ auto main(int const argc, char const* const* const argv) -> int if (main.interactive) { main.display_version(); - main.import_("(scheme r5rs)"); + main.import_("(scheme base)"); + main.import_("(scheme char)"); + main.import_("(scheme cxr)"); + main.import_("(scheme eval)"); + main.import_("(scheme inexact)"); + main.import_("(scheme lazy)"); + main.import_("(scheme load)"); + main.import_("(scheme process-context)"); + main.import_("(scheme read)"); + main.import_("(scheme write)"); } while (main.interactive and main.char_ready()) From d40d30430e3422f98ec462680e950960963f0151 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Wed, 14 Sep 2022 03:13:44 +0900 Subject: [PATCH 20/23] Update procedure `sqrt` to return complex if negative number given Signed-off-by: yamacir-kit --- README.md | 6 ++--- VERSION | 2 +- include/meevax/kernel/number.hpp | 38 ++++++++++++++++---------------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 0e1de7d71..b6e532a2a 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.228.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.229.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.228_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.229_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` @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.228 +Meevax Lisp System, version 0.4.229 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index b250cf026..5fb240097 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.228 +0.4.229 diff --git a/include/meevax/kernel/number.hpp b/include/meevax/kernel/number.hpp index d2e15b38a..afafdb2ad 100644 --- a/include/meevax/kernel/number.hpp +++ b/include/meevax/kernel/number.hpp @@ -615,22 +615,25 @@ inline namespace kernel { if constexpr (std::is_same_v, complex>) { - return std::sqrt(static_cast>(std::forward(x))); - } - else if constexpr (std::is_same_v, exact_integer>) - { - if (auto&& [s, r] = exact_integer_sqrt(x); r == 0) - { - return make(s); - } - else - { - return make(std::sqrt(inexact_cast(x))); - } + auto const z = std::sqrt(inexact_cast(std::forward(x))); + return complex(make(z.real()), make(z.imag())); } else { - return std::sqrt(inexact_cast(x)); + auto sqrt = [](auto&& x) + { + if constexpr (std::is_same_v, exact_integer>) + { + auto const [s, r] = exact_integer_sqrt(x); + return r == 0 ? make(s) : make(std::sqrt(inexact_cast(x))); + } + else + { + return make(std::sqrt(inexact_cast(x))); + } + }; + + return x < exact_integer(0) ? make(e0, sqrt(exact_integer(0) - x)) : sqrt(x); } } }; @@ -645,8 +648,7 @@ inline namespace kernel { auto const z = std::pow(inexact_cast(std::forward(x)), inexact_cast(std::forward(y))); - return complex(make(z.real()), - make(z.imag())); + return complex(make(z.real()), make(z.imag())); } else if constexpr (std::is_same_v, exact_integer> and std::is_same_v, exact_integer>) @@ -702,8 +704,7 @@ inline namespace kernel } \ else \ { \ - return complex(apply(x.real()), \ - apply(x.imag())); \ + return complex(apply(x.real()), apply(x.imag())); \ } \ } \ } @@ -724,8 +725,7 @@ inline namespace kernel if constexpr (std::is_same_v, complex>) \ { \ auto const z = std::CMATH(inexact_cast(std::forward(x))); \ - return complex(make(z.real()), \ - make(z.imag())); \ + return complex(make(z.real()), make(z.imag())); \ } \ else \ { \ From 70bbc7da5ab36d14ea554c8fc405b66bc159eee0 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Wed, 14 Sep 2022 23:19:55 +0900 Subject: [PATCH 21/23] Support standard library `(scheme complex)` Signed-off-by: yamacir-kit --- README.md | 6 +++--- VERSION | 2 +- basis/r7rs.ss | 26 +++++++++++++++++++------- include/meevax/kernel/number.hpp | 8 ++++---- src/kernel/library.cpp | 25 +++++++++++++++++++++++++ src/main.cpp | 1 + 6 files changed, 53 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index b6e532a2a..1ba4d0014 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.229.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.230.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.229_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.230_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` @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.229 +Meevax Lisp System, version 0.4.230 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 5fb240097..3e3534c19 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.229 +0.4.230 diff --git a/basis/r7rs.ss b/basis/r7rs.ss index 14ea8ebe2..0be4d47f6 100644 --- a/basis/r7rs.ss +++ b/basis/r7rs.ss @@ -436,13 +436,25 @@ (export finite? infinite? nan? exp log sin cos tan asin acos atan sqrt)) (define-library (scheme complex) - (export make-rectangular - make-polar - real-part - imag-part - angle - ) - ) + (import (meevax complex) + (scheme base) + (scheme inexact)) + + (export make-rectangular make-polar real-part imag-part magnitude angle) + + (begin (define (make-polar magnitude angle) + (make-rectangular (* magnitude (cos angle)) + (* magnitude (sin angle)))) + + (define (magnitude z) + (let ((re (real-part z)) + (im (imag-part z))) + (sqrt (+ (* re re) + (* im im))))) + + (define (angle z) + (atan (imag-part z) + (real-part z))))) (define-library (scheme cxr) (import (meevax pair)) diff --git a/include/meevax/kernel/number.hpp b/include/meevax/kernel/number.hpp index afafdb2ad..bac05f62b 100644 --- a/include/meevax/kernel/number.hpp +++ b/include/meevax/kernel/number.hpp @@ -436,12 +436,12 @@ inline namespace kernel return apply.at(type_index<2>(x.type(), y.type()))(x, y); } - template - auto inexact_cast(T&& x) -> decltype(auto) + template )> + auto inexact_cast(U&& x) -> decltype(auto) { if constexpr (std::is_same_v, complex>) { - return std::complex(std::forward(x)); + return std::complex(std::forward(x)); } else if constexpr (std::is_floating_point_v>) { @@ -449,7 +449,7 @@ inline namespace kernel } else { - return static_cast(std::forward(x)); + return static_cast(std::forward(x)); } } diff --git a/src/kernel/library.cpp b/src/kernel/library.cpp index e3e8ef6f2..f0c5f99b0 100644 --- a/src/kernel/library.cpp +++ b/src/kernel/library.cpp @@ -59,6 +59,31 @@ inline namespace kernel library.export_("char-codepoint"); }); + define_library("(meevax complex)", [](library & library) + { + library.define("make-rectangular", [](let const& xs) + { + assert(apply(car(xs))); + assert(apply(cadr(xs))); + + return make(car(xs), cadr(xs)); + }); + + library.define("real-part", [](let const& xs) + { + return car(xs).as().real(); + }); + + library.define("imag-part", [](let const& xs) + { + return car(xs).as().imag(); + }); + + library.export_("make-rectangular"); + library.export_("real-part"); + library.export_("imag-part"); + }); + define_library("(meevax context)", [](library & library) { library.define("emergency-exit", [](let const& xs) diff --git a/src/main.cpp b/src/main.cpp index f527bca40..89f9d6682 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -35,6 +35,7 @@ auto main(int const argc, char const* const* const argv) -> int main.display_version(); main.import_("(scheme base)"); main.import_("(scheme char)"); + main.import_("(scheme complex)"); main.import_("(scheme cxr)"); main.import_("(scheme eval)"); main.import_("(scheme inexact)"); From 252b1e6c8e193ad0556d9052f0600a67b1de0b4f Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Thu, 15 Sep 2022 00:18:42 +0900 Subject: [PATCH 22/23] Update `complex` to support polar form and pure imaginary number literals Signed-off-by: yamacir-kit --- README.md | 6 +++--- VERSION | 2 +- include/meevax/kernel/complex.hpp | 2 -- src/kernel/complex.cpp | 24 +++++++++++++++--------- src/kernel/number.cpp | 2 +- test/r7rs.ss | 4 ++-- 6 files changed, 22 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 1ba4d0014..faf473275 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.230.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.231.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.230_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.231_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` @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.230 +Meevax Lisp System, version 0.4.231 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 3e3534c19..5942fea1a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.230 +0.4.231 diff --git a/include/meevax/kernel/complex.hpp b/include/meevax/kernel/complex.hpp index c08ff3c56..6c6698342 100644 --- a/include/meevax/kernel/complex.hpp +++ b/include/meevax/kernel/complex.hpp @@ -37,8 +37,6 @@ inline namespace kernel auto imag() const noexcept -> const_reference; - static auto pattern() -> std::regex const&; - auto real() const noexcept -> const_reference; explicit operator std::complex(); diff --git a/src/kernel/complex.cpp b/src/kernel/complex.cpp index 30c17d3ae..e571547c7 100644 --- a/src/kernel/complex.cpp +++ b/src/kernel/complex.cpp @@ -23,10 +23,22 @@ inline namespace kernel { complex::complex(std::string const& token, int radix) { - if (std::smatch result; std::regex_match(token, result, pattern())) + std::regex static const rectangular { R"(([+-]?.*)([+-].*)i)" }; + + std::regex static const polar { R"(([+-]?.*)@([+-]?.*))" }; + + if (std::smatch result; std::regex_match(token, result, rectangular)) + { + std::get<0>(*this) = string_to_real(result[1].length() == 0 ? "0" : result.str(1), radix); + std::get<1>(*this) = string_to_real(result[2].length() == 1 ? result.str(2) + "1" : result.str(2), radix); + } + else if (std::regex_match(token, result, polar)) { - std::get<0>(*this) = string_to_real(result.str(1), radix); - std::get<1>(*this) = string_to_real(result.str(2), radix); + auto const magnitude = string_to_real(result.str(1), radix); + auto const angle = string_to_real(result.str(2), radix); + + std::get<0>(*this) = magnitude * apply(angle); + std::get<1>(*this) = magnitude * apply(angle); } else { @@ -51,12 +63,6 @@ inline namespace kernel return second; } - auto complex::pattern() -> std::regex const& - { - std::regex static const pattern { R"(([+-]?.*)([+-].*)[ij])" }; - return pattern; - } - auto complex::real() const noexcept -> const_reference { return first; diff --git a/src/kernel/number.cpp b/src/kernel/number.cpp index d0f102538..126ad3649 100644 --- a/src/kernel/number.cpp +++ b/src/kernel/number.cpp @@ -217,7 +217,7 @@ inline namespace kernel auto operator * (complex const& a, complex const& b) -> complex { return complex(a.real() * b.real() - a.imag() * b.imag(), a.imag() * b.real() + a.real() * b.imag()); } auto operator / (complex const& a, complex const& b) -> complex { auto x = a.real() * b.real() + a.imag() * b.imag(); auto y = a.imag() * b.real() - a.real() * b.imag(); auto d = b.real() * b.real() + b.imag() * b.imag(); return complex(x / d, y / d); } auto operator % (complex const& , complex const& ) -> complex { throw std::invalid_argument("unsupported operation"); } - auto operator ==(complex const& a, complex const& b) -> bool { return apply(a.real(), b.real()) and apply(a.imag(), b.imag()); } + auto operator ==(complex const& a, complex const& b) -> bool { return apply(a.real(), b.real()).as() and apply(a.imag(), b.imag()).as(); } auto operator !=(complex const& a, complex const& b) -> bool { return not (a == b); } auto operator < (complex const& , complex const& ) -> bool { throw std::invalid_argument("unsupported operation"); } auto operator <=(complex const& , complex const& ) -> bool { throw std::invalid_argument("unsupported operation"); } diff --git a/test/r7rs.ss b/test/r7rs.ss index ced304e7c..3b59e0e64 100644 --- a/test/r7rs.ss +++ b/test/r7rs.ss @@ -982,7 +982,7 @@ (check (sqrt 9) => 3) -; (check (sqrt -1) => +i) +(check (sqrt -1) => +i) ; (check (exact-integer-sqrt 4) => #,(values 2 0)) @@ -1555,4 +1555,4 @@ (check-report) -(exit (check-passed? 391)) +(exit (check-passed? 392)) From 931b88558b345a266e6a28d13b33e30c6bb2c3dc Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Thu, 15 Sep 2022 00:24:31 +0900 Subject: [PATCH 23/23] Add `exact-complex` to list of the feature identifiers Signed-off-by: yamacir-kit --- README.md | 6 +++--- VERSION | 2 +- configure/version.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index faf473275..72b3eb067 100644 --- a/README.md +++ b/README.md @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |:-------------------|:-- -| `all` (default) | Build shared-library `libmeevax.0.4.231.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.232.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.231_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.232_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` @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's ## Usage ``` -Meevax Lisp System, version 0.4.231 +Meevax Lisp System, version 0.4.232 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 5942fea1a..2a4561f41 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.231 +0.4.232 diff --git a/configure/version.cpp b/configure/version.cpp index 9cb1d7bb5..bb65dc8da 100644 --- a/configure/version.cpp +++ b/configure/version.cpp @@ -61,7 +61,7 @@ inline namespace kernel let static const features = list( make("r4rs"), make("exact-closed"), - // make("exact-complex"), + make("exact-complex"), make("ieee-float"), // make("full-unicode"), make("ratios"),