From 4fdfbd3485303bfa30a672cb62a365d89d527e48 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Sun, 14 Aug 2022 11:30:39 +0900 Subject: [PATCH 01/11] Update ratio constructor to use GMP function Signed-off-by: yamacir-kit --- README.md | 6 +++--- VERSION | 2 +- include/meevax/kernel/ratio.hpp | 6 +++++- src/kernel/ratio.cpp | 18 +++++++----------- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 000eb59e2..ce5805b5c 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.197.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.198.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.197_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.198_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.197 +Meevax Lisp System, version 0.4.198 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 3b43aa39c..9f134a40d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.197 +0.4.198 diff --git a/include/meevax/kernel/ratio.hpp b/include/meevax/kernel/ratio.hpp index c90daacf9..d3f1a5fed 100644 --- a/include/meevax/kernel/ratio.hpp +++ b/include/meevax/kernel/ratio.hpp @@ -17,6 +17,8 @@ #ifndef INCLUDED_MEEVAX_KERNEL_RATIO_HPP #define INCLUDED_MEEVAX_KERNEL_RATIO_HPP +#include + #include namespace meevax @@ -27,9 +29,11 @@ inline namespace kernel { using pair::pair; + mpq_t value; + explicit ratio(double); - explicit ratio(external_representation const&, int = 0); + explicit ratio(external_representation const&, int = 10); auto denominator() const -> const_reference; diff --git a/src/kernel/ratio.cpp b/src/kernel/ratio.cpp index 2a968ca65..79dce502f 100644 --- a/src/kernel/ratio.cpp +++ b/src/kernel/ratio.cpp @@ -24,7 +24,6 @@ inline namespace kernel { ratio::ratio(double x) { - mpq_t value; mpq_init(value); mpq_set_d(value, x); @@ -39,19 +38,16 @@ inline namespace kernel { std::regex static const pattern { "([+-]?[0-9a-f]+)/([0-9a-f]+)" }; - if (std::smatch result; std::regex_match(token, result, pattern)) + if (mpq_init(value); not std::regex_match(token, pattern) or mpq_set_str(value, token.c_str(), radix)) { - auto n = exact_integer(result.str(1), radix); - - numerator() = make(n); - - auto d = exact_integer(result.str(2), radix); - - denominator() = make(d); + mpq_clear(value); + throw error(); } - else + else // TEMPORARY!!! { - throw error(); + numerator() = make(mpq_numref(value)); + denominator() = make(mpq_denref(value)); + mpq_clear(value); } } From 4104afc0d12618c09678b3e2241539aeaeb3f558 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Sun, 14 Aug 2022 12:13:51 +0900 Subject: [PATCH 02/11] Update procedure `(numerator|denominator)` to use `ratio-(numerator|denominator)` instead of `(car|cdr)` Signed-off-by: yamacir-kit --- README.md | 6 +++--- VERSION | 2 +- basis/r4rs.ss | 7 ++++--- src/kernel/library.cpp | 12 ++++++++++++ 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index ce5805b5c..01bda4a36 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.198.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.199.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.198_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.199_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.198 +Meevax Lisp System, version 0.4.199 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 9f134a40d..9d43f8919 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.198 +0.4.199 diff --git a/basis/r4rs.ss b/basis/r4rs.ss index 71e161739..f9d21a52f 100644 --- a/basis/r4rs.ss +++ b/basis/r4rs.ss @@ -1,6 +1,6 @@ (define-library (scheme r4rs) (import (meevax inexact) - (only (meevax number) exact-integer? expt exact inexact ratio?) + (only (meevax number) exact-integer? expt exact inexact ratio? ratio-numerator ratio-denominator) (only (meevax port) get-ready? standard-input-port standard-output-port) (only (meevax string) string-copy) (only (meevax syntax) define-syntax) @@ -71,12 +71,13 @@ ,body))))))) (define (numerator x) - (cond ((ratio? x) (car x)) + (cond ((ratio? x) (ratio-numerator x)) ((exact? x) x) (else (inexact (numerator (exact x)))))) (define (denominator x) - (cond ((exact? x) (if (ratio? x) (cdr x) 1)) + (cond ((ratio? x) (ratio-denominator x)) + ((exact? x) 1) ((integer? x) 1.0) (else (inexact (denominator (exact x)))))) diff --git a/src/kernel/library.cpp b/src/kernel/library.cpp index ffc2b1213..cd0cb8110 100644 --- a/src/kernel/library.cpp +++ b/src/kernel/library.cpp @@ -569,6 +569,16 @@ inline namespace kernel #undef DEFINE + library.define("ratio-numerator", [](let const& xs) + { + return car(xs).as().numerator(); + }); + + library.define("ratio-denominator", [](let const& xs) + { + return car(xs).as().denominator(); + }); + library.define("floor", [](let const& xs) { return apply(car(xs)); @@ -648,6 +658,8 @@ inline namespace kernel library.export_("-"); library.export_("/"); library.export_("%"); + library.export_("ratio-numerator"); + library.export_("ratio-denominator"); library.export_("floor"); library.export_("ceiling"); library.export_("truncate"); From a431ed6c7db9076f9b8cf3755c94aee108a271dc Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Sun, 14 Aug 2022 12:42:54 +0900 Subject: [PATCH 03/11] Update base class `pair` of `ratio` to protected Signed-off-by: yamacir-kit --- README.md | 6 +++--- VERSION | 2 +- include/meevax/kernel/ratio.hpp | 2 +- src/kernel/number.cpp | 14 +++++++------- src/kernel/ratio.cpp | 3 +-- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 01bda4a36..402e145f7 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.199.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.200.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.199_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.200_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.199 +Meevax Lisp System, version 0.4.200 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 9d43f8919..1abe58b1d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.199 +0.4.200 diff --git a/include/meevax/kernel/ratio.hpp b/include/meevax/kernel/ratio.hpp index d3f1a5fed..d09406e19 100644 --- a/include/meevax/kernel/ratio.hpp +++ b/include/meevax/kernel/ratio.hpp @@ -25,7 +25,7 @@ namespace meevax { inline namespace kernel { - struct ratio : public virtual pair + struct ratio : protected virtual pair { using pair::pair; diff --git a/src/kernel/number.cpp b/src/kernel/number.cpp index 2fc627752..cb77c3dc5 100644 --- a/src/kernel/number.cpp +++ b/src/kernel/number.cpp @@ -33,9 +33,9 @@ inline namespace kernel auto operator > (exact_integer const& a, exact_integer const& b) -> bool { return mpz_cmp(a.value, b.value) > 0; } auto operator >=(exact_integer const& a, exact_integer const& b) -> bool { return mpz_cmp(a.value, b.value) >= 0; } - auto operator * (exact_integer const& a, ratio const& b) -> ratio { return ratio(make(a * b.numerator().as()), cdr(b)); } - auto operator + (exact_integer const& a, ratio const& b) -> ratio { return ratio(make(a * b.denominator().as() + b.numerator().as()), cdr(b)); } - auto operator - (exact_integer const& a, ratio const& b) -> ratio { return ratio(make(a * b.denominator().as() - b.numerator().as()), cdr(b)); } + auto operator * (exact_integer const& a, ratio const& b) -> ratio { return ratio(make(a * b.numerator().as()), b.denominator()); } + auto operator + (exact_integer const& a, ratio const& b) -> ratio { return ratio(make(a * b.denominator().as() + b.numerator().as()), b.denominator()); } + auto operator - (exact_integer const& a, ratio const& b) -> ratio { return ratio(make(a * b.denominator().as() - b.numerator().as()), b.denominator()); } auto operator / (exact_integer const& a, ratio const& b) -> ratio { return a * b.invert(); } auto operator % (exact_integer const& , ratio const& ) -> ratio { throw error(make("unsupported operation"), unit); } auto operator !=(exact_integer const& a, ratio const& b) -> bool { auto const x = b.reduce(); return std::invoke(is_integer(), x) and a != x.numerator().as(); } @@ -69,10 +69,10 @@ 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 * (ratio const& a, exact_integer const& b) -> ratio { return ratio(make(a.numerator().as() * b), cdr(a)); } - auto operator + (ratio const& a, exact_integer const& b) -> ratio { return ratio(make(a.numerator().as() + a.denominator().as() * b), cdr(a)); } - auto operator - (ratio const& a, exact_integer const& b) -> ratio { return ratio(make(a.numerator().as() - a.denominator().as() * b), cdr(a)); } - auto operator / (ratio const& a, exact_integer const& b) -> ratio { return ratio(car(a), make(a.denominator().as() * b)); } + auto operator * (ratio const& a, exact_integer const& b) -> ratio { return ratio(make(a.numerator().as() * b), a.denominator()); } + auto operator + (ratio const& a, exact_integer const& b) -> ratio { return ratio(make(a.numerator().as() + a.denominator().as() * b), a.denominator()); } + auto operator - (ratio const& a, exact_integer const& b) -> ratio { return ratio(make(a.numerator().as() - a.denominator().as() * b), a.denominator()); } + auto operator / (ratio const& a, exact_integer const& b) -> ratio { return ratio(a.numerator(), make(a.denominator().as() * b)); } auto operator % (ratio const& , exact_integer const& ) -> ratio { throw error(make("unsupported operation"), unit); } auto operator !=(ratio const& a, exact_integer const& b) -> bool { auto const x = a.reduce(); return std::invoke(is_integer(), x) and x.numerator().as() != b; } auto operator < (ratio const& a, exact_integer const& b) -> bool { auto const x = a.reduce(); return std::invoke(is_integer(), x) and x.numerator().as() < b; } diff --git a/src/kernel/ratio.cpp b/src/kernel/ratio.cpp index 79dce502f..7b470055c 100644 --- a/src/kernel/ratio.cpp +++ b/src/kernel/ratio.cpp @@ -28,7 +28,6 @@ inline namespace kernel mpq_set_d(value, x); numerator() = make(mpq_numref(value)); - denominator() = make(mpq_denref(value)); mpq_clear(value); @@ -107,7 +106,7 @@ inline namespace kernel { if (auto x = reduce(); is_integer()(x)) { - return car(x); + return x.numerator(); } else { From c4a11b9154d718debb8209c9948fdc3abf24d49a Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Sun, 14 Aug 2022 21:17:22 +0900 Subject: [PATCH 04/11] Remove inheriting constructor Signed-off-by: yamacir-kit --- README.md | 6 +++--- VERSION | 2 +- include/meevax/kernel/ratio.hpp | 8 ++++++-- src/kernel/ratio.cpp | 14 +++++++++++++- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 402e145f7..ac84196d7 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.200.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.201.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.200_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.201_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.200 +Meevax Lisp System, version 0.4.201 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 1abe58b1d..3f72cf6e3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.200 +0.4.201 diff --git a/include/meevax/kernel/ratio.hpp b/include/meevax/kernel/ratio.hpp index d09406e19..7a6179b16 100644 --- a/include/meevax/kernel/ratio.hpp +++ b/include/meevax/kernel/ratio.hpp @@ -27,10 +27,14 @@ inline namespace kernel { struct ratio : protected virtual pair { - using pair::pair; - mpq_t value; + ratio(); + + ratio(ratio const&); + + ratio(const_reference, const_reference); + explicit ratio(double); explicit ratio(external_representation const&, int = 10); diff --git a/src/kernel/ratio.cpp b/src/kernel/ratio.cpp index 7b470055c..2053cf951 100644 --- a/src/kernel/ratio.cpp +++ b/src/kernel/ratio.cpp @@ -22,6 +22,18 @@ namespace meevax { inline namespace kernel { + ratio::ratio() + : pair {} + {} + + ratio::ratio(ratio const& q) + : pair { static_cast(q) } + {} + + ratio::ratio(const_reference x, const_reference y) + : pair { x, y } + {} + ratio::ratio(double x) { mpq_init(value); @@ -98,7 +110,7 @@ inline namespace kernel } else { - return *this; + return ratio(*this); } } From 2fc544d33e3ec9ec67ac591e392a56f5faaa3039 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Mon, 15 Aug 2022 01:14:48 +0900 Subject: [PATCH 05/11] Add non-default destructor to `ratio` Signed-off-by: yamacir-kit --- README.md | 6 +++--- VERSION | 2 +- include/meevax/kernel/ratio.hpp | 2 ++ src/kernel/ratio.cpp | 28 +++++++++++++++++++++------- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index ac84196d7..925eef633 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.201.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.202.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.201_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.202_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.201 +Meevax Lisp System, version 0.4.202 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 3f72cf6e3..91169f453 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.201 +0.4.202 diff --git a/include/meevax/kernel/ratio.hpp b/include/meevax/kernel/ratio.hpp index 7a6179b16..0bd0ff4fb 100644 --- a/include/meevax/kernel/ratio.hpp +++ b/include/meevax/kernel/ratio.hpp @@ -39,6 +39,8 @@ inline namespace kernel explicit ratio(external_representation const&, int = 10); + ~ratio(); + auto denominator() const -> const_reference; auto denominator() -> reference; diff --git a/src/kernel/ratio.cpp b/src/kernel/ratio.cpp index 2053cf951..27faf4386 100644 --- a/src/kernel/ratio.cpp +++ b/src/kernel/ratio.cpp @@ -23,16 +23,27 @@ namespace meevax inline namespace kernel { ratio::ratio() - : pair {} - {} + { + mpq_init(value); + } ratio::ratio(ratio const& q) : pair { static_cast(q) } - {} + { + mpq_init(value); + mpq_set_num(value, q.numerator().as().value); + mpq_set_den(value, q.denominator().as().value); + mpq_canonicalize(value); + } ratio::ratio(const_reference x, const_reference y) : pair { x, y } - {} + { + mpq_init(value); + mpq_set_num(value, x.as().value); + mpq_set_den(value, y.as().value); + mpq_canonicalize(value); + } ratio::ratio(double x) { @@ -41,8 +52,6 @@ inline namespace kernel numerator() = make(mpq_numref(value)); denominator() = make(mpq_denref(value)); - - mpq_clear(value); } ratio::ratio(external_representation const& token, int radix) @@ -56,12 +65,17 @@ inline namespace kernel } else // TEMPORARY!!! { + mpq_canonicalize(value); numerator() = make(mpq_numref(value)); denominator() = make(mpq_denref(value)); - mpq_clear(value); } } + ratio::~ratio() + { + mpq_clear(value); + } + auto ratio::denominator() const -> const_reference { return second; From fcd340c0bd0ed61360ac08d8e3e71ae6227b277a Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Mon, 15 Aug 2022 12:08:56 +0900 Subject: [PATCH 06/11] Update `ratio` constructor to call `mpq_canonicalize` Signed-off-by: yamacir-kit --- README.md | 6 +++--- VERSION | 2 +- include/meevax/kernel/ratio.hpp | 4 +--- src/kernel/number.cpp | 24 +++++++++++----------- src/kernel/ratio.cpp | 36 +++++++-------------------------- 5 files changed, 24 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index 925eef633..605127380 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.202.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.203.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.202_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.203_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.202 +Meevax Lisp System, version 0.4.203 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 91169f453..4567fc8f8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.202 +0.4.203 diff --git a/include/meevax/kernel/ratio.hpp b/include/meevax/kernel/ratio.hpp index 0bd0ff4fb..0e3ff8cec 100644 --- a/include/meevax/kernel/ratio.hpp +++ b/include/meevax/kernel/ratio.hpp @@ -33,7 +33,7 @@ inline namespace kernel ratio(ratio const&); - ratio(const_reference, const_reference); + explicit ratio(const_reference, const_reference); explicit ratio(double); @@ -51,8 +51,6 @@ inline namespace kernel auto numerator() -> reference; - auto reduce() const -> ratio; - auto simple() const -> value_type; explicit operator double() const; diff --git a/src/kernel/number.cpp b/src/kernel/number.cpp index cb77c3dc5..9916df6d0 100644 --- a/src/kernel/number.cpp +++ b/src/kernel/number.cpp @@ -38,12 +38,12 @@ inline namespace kernel auto operator - (exact_integer const& a, ratio const& b) -> ratio { return ratio(make(a * b.denominator().as() - b.numerator().as()), b.denominator()); } auto operator / (exact_integer const& a, ratio const& b) -> ratio { return a * b.invert(); } auto operator % (exact_integer const& , ratio const& ) -> ratio { throw error(make("unsupported operation"), unit); } - auto operator !=(exact_integer const& a, ratio const& b) -> bool { auto const x = b.reduce(); return std::invoke(is_integer(), x) and a != x.numerator().as(); } - auto operator < (exact_integer const& a, ratio const& b) -> bool { auto const x = b.reduce(); return std::invoke(is_integer(), x) and a < x.numerator().as(); } - auto operator <=(exact_integer const& a, ratio const& b) -> bool { auto const x = b.reduce(); return std::invoke(is_integer(), x) and a <= x.numerator().as(); } - auto operator ==(exact_integer const& a, ratio const& b) -> bool { auto const x = b.reduce(); return std::invoke(is_integer(), x) and a == x.numerator().as(); } - auto operator > (exact_integer const& a, ratio const& b) -> bool { auto const x = b.reduce(); return std::invoke(is_integer(), x) and a > x.numerator().as(); } - auto operator >=(exact_integer const& a, ratio const& b) -> bool { auto const x = b.reduce(); return std::invoke(is_integer(), x) and a >= x.numerator().as(); } + auto operator !=(exact_integer const& a, ratio const& b) -> bool { auto const x = ratio(b); return std::invoke(is_integer(), x) and a != x.numerator().as(); } + auto operator < (exact_integer const& a, ratio const& b) -> bool { auto const x = ratio(b); return std::invoke(is_integer(), x) and a < x.numerator().as(); } + auto operator <=(exact_integer const& a, ratio const& b) -> bool { auto const x = ratio(b); return std::invoke(is_integer(), x) and a <= x.numerator().as(); } + auto operator ==(exact_integer const& a, ratio const& b) -> bool { auto const x = ratio(b); return std::invoke(is_integer(), x) and a == x.numerator().as(); } + auto operator > (exact_integer const& a, ratio const& b) -> bool { auto const x = ratio(b); return std::invoke(is_integer(), x) and a > x.numerator().as(); } + auto operator >=(exact_integer const& a, ratio const& b) -> bool { auto const x = ratio(b); return std::invoke(is_integer(), x) and a >= x.numerator().as(); } auto operator + (exact_integer const& a, float b) -> float { return inexact_cast(a) + b; } auto operator - (exact_integer const& a, float b) -> float { return inexact_cast(a) - b; } @@ -74,12 +74,12 @@ inline namespace kernel auto operator - (ratio const& a, exact_integer const& b) -> ratio { return ratio(make(a.numerator().as() - a.denominator().as() * b), a.denominator()); } auto operator / (ratio const& a, exact_integer const& b) -> ratio { return ratio(a.numerator(), make(a.denominator().as() * b)); } auto operator % (ratio const& , exact_integer const& ) -> ratio { throw error(make("unsupported operation"), unit); } - auto operator !=(ratio const& a, exact_integer const& b) -> bool { auto const x = a.reduce(); return std::invoke(is_integer(), x) and x.numerator().as() != b; } - auto operator < (ratio const& a, exact_integer const& b) -> bool { auto const x = a.reduce(); return std::invoke(is_integer(), x) and x.numerator().as() < b; } - auto operator <=(ratio const& a, exact_integer const& b) -> bool { auto const x = a.reduce(); return std::invoke(is_integer(), x) and x.numerator().as() <= b; } - auto operator ==(ratio const& a, exact_integer const& b) -> bool { auto const x = a.reduce(); return std::invoke(is_integer(), x) and x.numerator().as() == b; } - auto operator > (ratio const& a, exact_integer const& b) -> bool { auto const x = a.reduce(); return std::invoke(is_integer(), x) and x.numerator().as() > b; } - auto operator >=(ratio const& a, exact_integer const& b) -> bool { auto const x = a.reduce(); return std::invoke(is_integer(), x) and x.numerator().as() >= b; } + auto operator !=(ratio const& a, exact_integer const& b) -> bool { auto const x = ratio(a); return std::invoke(is_integer(), x) and x.numerator().as() != b; } + auto operator < (ratio const& a, exact_integer const& b) -> bool { auto const x = ratio(a); return std::invoke(is_integer(), x) and x.numerator().as() < b; } + auto operator <=(ratio const& a, exact_integer const& b) -> bool { auto const x = ratio(a); return std::invoke(is_integer(), x) and x.numerator().as() <= b; } + auto operator ==(ratio const& a, exact_integer const& b) -> bool { auto const x = ratio(a); return std::invoke(is_integer(), x) and x.numerator().as() == b; } + auto operator > (ratio const& a, exact_integer const& b) -> bool { auto const x = ratio(a); return std::invoke(is_integer(), x) and x.numerator().as() > b; } + auto operator >=(ratio const& a, exact_integer const& b) -> bool { auto const x = ratio(a); return std::invoke(is_integer(), x) and x.numerator().as() >= b; } auto operator + (ratio const& a, ratio const& b) -> ratio { return ratio(make(a.numerator().as() * b.denominator().as() + b.numerator().as() * a.denominator().as()), make(a.denominator().as() * b.denominator().as())); } auto operator - (ratio const& a, ratio const& b) -> ratio { return ratio(make(a.numerator().as() * b.denominator().as() - b.numerator().as() * a.denominator().as()), make(a.denominator().as() * b.denominator().as())); } diff --git a/src/kernel/ratio.cpp b/src/kernel/ratio.cpp index 27faf4386..796f7e8ff 100644 --- a/src/kernel/ratio.cpp +++ b/src/kernel/ratio.cpp @@ -34,15 +34,20 @@ inline namespace kernel mpq_set_num(value, q.numerator().as().value); mpq_set_den(value, q.denominator().as().value); mpq_canonicalize(value); + + numerator() = make(mpq_numref(value)); + denominator() = make(mpq_denref(value)); } ratio::ratio(const_reference x, const_reference y) - : pair { x, y } { mpq_init(value); mpq_set_num(value, x.as().value); mpq_set_den(value, y.as().value); mpq_canonicalize(value); + + numerator() = make(mpq_numref(value)); + denominator() = make(mpq_denref(value)); } ratio::ratio(double x) @@ -101,36 +106,9 @@ inline namespace kernel return first; } - auto ratio::reduce() const -> ratio - { - auto gcd = [](exact_integer const& a, exact_integer const& b) - { - exact_integer n; - mpz_gcd(n.value, a.value, b.value); - return n; - }; - - auto div = [](exact_integer const& a, exact_integer const& b) - { - exact_integer n; - mpz_div(n.value, a.value, b.value); - return n; - }; - - if (auto x = gcd(numerator().as(), denominator().as()); x != 1) - { - return ratio(make(div(numerator().as(), x)), - make(div(denominator().as(), x))); - } - else - { - return ratio(*this); - } - } - auto ratio::simple() const -> value_type { - if (auto x = reduce(); is_integer()(x)) + if (auto x = ratio(*this); is_integer()(x)) { return x.numerator(); } From 987c60cddc17ec0c031c107194baffca5c498898 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Mon, 15 Aug 2022 12:28:07 +0900 Subject: [PATCH 07/11] Remove non-const `ratio::(numerator|denominator)` Signed-off-by: yamacir-kit --- README.md | 6 +++--- VERSION | 2 +- include/meevax/kernel/ratio.hpp | 4 ---- src/kernel/ratio.cpp | 26 ++++++++------------------ 4 files changed, 12 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 605127380..a12835317 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.203.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.204.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.203_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.204_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.203 +Meevax Lisp System, version 0.4.204 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 4567fc8f8..16680e764 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.203 +0.4.204 diff --git a/include/meevax/kernel/ratio.hpp b/include/meevax/kernel/ratio.hpp index 0e3ff8cec..54755623c 100644 --- a/include/meevax/kernel/ratio.hpp +++ b/include/meevax/kernel/ratio.hpp @@ -43,14 +43,10 @@ inline namespace kernel auto denominator() const -> const_reference; - auto denominator() -> reference; - auto invert() const -> ratio; auto numerator() const -> const_reference; - auto numerator() -> reference; - auto simple() const -> value_type; explicit operator double() const; diff --git a/src/kernel/ratio.cpp b/src/kernel/ratio.cpp index 796f7e8ff..497dbff17 100644 --- a/src/kernel/ratio.cpp +++ b/src/kernel/ratio.cpp @@ -35,8 +35,8 @@ inline namespace kernel mpq_set_den(value, q.denominator().as().value); mpq_canonicalize(value); - numerator() = make(mpq_numref(value)); - denominator() = make(mpq_denref(value)); + first = make(mpq_numref(value)); + second = make(mpq_denref(value)); } ratio::ratio(const_reference x, const_reference y) @@ -46,8 +46,8 @@ inline namespace kernel mpq_set_den(value, y.as().value); mpq_canonicalize(value); - numerator() = make(mpq_numref(value)); - denominator() = make(mpq_denref(value)); + first = make(mpq_numref(value)); + second = make(mpq_denref(value)); } ratio::ratio(double x) @@ -55,8 +55,8 @@ inline namespace kernel mpq_init(value); mpq_set_d(value, x); - numerator() = make(mpq_numref(value)); - denominator() = make(mpq_denref(value)); + first = make(mpq_numref(value)); + second = make(mpq_denref(value)); } ratio::ratio(external_representation const& token, int radix) @@ -71,8 +71,8 @@ inline namespace kernel else // TEMPORARY!!! { mpq_canonicalize(value); - numerator() = make(mpq_numref(value)); - denominator() = make(mpq_denref(value)); + first = make(mpq_numref(value)); + second = make(mpq_denref(value)); } } @@ -86,11 +86,6 @@ inline namespace kernel return second; } - auto ratio::denominator() -> reference - { - return second; - } - auto ratio::invert() const -> ratio { return ratio(denominator(), numerator()); @@ -101,11 +96,6 @@ inline namespace kernel return first; } - auto ratio::numerator() -> reference - { - return first; - } - auto ratio::simple() const -> value_type { if (auto x = ratio(*this); is_integer()(x)) From c053a58db28835aa1b278d7fc06bb333c2e35f97 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Mon, 15 Aug 2022 15:11:37 +0900 Subject: [PATCH 08/11] Remove member function `ratio::simple` Signed-off-by: yamacir-kit --- README.md | 6 ++--- VERSION | 2 +- include/meevax/kernel/exact_integer.hpp | 2 +- include/meevax/kernel/number.hpp | 32 ++++++++++++++----------- include/meevax/kernel/ratio.hpp | 6 ++--- include/meevax/kernel/reader.hpp | 2 +- src/kernel/exact_integer.cpp | 4 ++-- src/kernel/ratio.cpp | 16 ++----------- test/numerical-operations.ss | 20 ++++++++-------- test/sicp-1.ss | 4 ++-- 10 files changed, 42 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index a12835317..cc530372b 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.204.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.205.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.204_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.205_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.204 +Meevax Lisp System, version 0.4.205 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 16680e764..bdca12ed5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.204 +0.4.205 diff --git a/include/meevax/kernel/exact_integer.hpp b/include/meevax/kernel/exact_integer.hpp index 37c6a7af3..261666dd9 100644 --- a/include/meevax/kernel/exact_integer.hpp +++ b/include/meevax/kernel/exact_integer.hpp @@ -31,7 +31,7 @@ inline namespace kernel explicit exact_integer() noexcept; - explicit exact_integer(mpz_t) noexcept; + explicit exact_integer(mpz_t const) noexcept; exact_integer(exact_integer const&) noexcept; diff --git a/include/meevax/kernel/number.hpp b/include/meevax/kernel/number.hpp index 4f60e492c..8e3957d7f 100644 --- a/include/meevax/kernel/number.hpp +++ b/include/meevax/kernel/number.hpp @@ -195,7 +195,14 @@ inline namespace kernel } else if constexpr (std::is_same_v, ratio>) { - return z.simple(); + if (auto i = exact_integer(mpq_denref(z.value)); i == 1) + { + return z.numerator(); + } + else + { + return make(std::forward(z)); + } } else { @@ -256,21 +263,18 @@ inline namespace kernel struct exact { template - auto operator ()(T const& x) const -> decltype(auto) - { - return ratio(x).simple(); - } - - auto operator ()(exact_integer const& x) const -> auto const& - { - return x; - } - - auto operator ()(ratio const& x) const -> auto const& + auto operator ()(T&& x) const -> decltype(auto) { - return x; + if constexpr (std::is_floating_point_v>) + { + return ratio(std::forward(x)); + } + else + { + return std::forward(x); + } } - }; + } inline constexpr exact_cast; struct inexact { diff --git a/include/meevax/kernel/ratio.hpp b/include/meevax/kernel/ratio.hpp index 54755623c..d2982933a 100644 --- a/include/meevax/kernel/ratio.hpp +++ b/include/meevax/kernel/ratio.hpp @@ -41,13 +41,11 @@ inline namespace kernel ~ratio(); - auto denominator() const -> const_reference; + auto denominator() const -> value_type; auto invert() const -> ratio; - auto numerator() const -> const_reference; - - auto simple() const -> value_type; + auto numerator() const -> value_type; explicit operator double() const; }; diff --git a/include/meevax/kernel/reader.hpp b/include/meevax/kernel/reader.hpp index 20056d882..d9a564e71 100644 --- a/include/meevax/kernel/reader.hpp +++ b/include/meevax/kernel/reader.hpp @@ -244,7 +244,7 @@ inline namespace kernel { try { - return ratio(token, radix).simple(); + return make(ratio(token, radix)); } catch (...) { diff --git a/src/kernel/exact_integer.cpp b/src/kernel/exact_integer.cpp index 4c3f34b83..240a4a6d2 100644 --- a/src/kernel/exact_integer.cpp +++ b/src/kernel/exact_integer.cpp @@ -31,9 +31,9 @@ inline namespace kernel mpz_init(value); } - exact_integer::exact_integer(mpz_t given) noexcept + exact_integer::exact_integer(mpz_t const z) noexcept { - mpz_init_set(value, given); + mpz_init_set(value, z); } exact_integer::exact_integer(exact_integer const& given) noexcept diff --git a/src/kernel/ratio.cpp b/src/kernel/ratio.cpp index 497dbff17..563dc876d 100644 --- a/src/kernel/ratio.cpp +++ b/src/kernel/ratio.cpp @@ -81,7 +81,7 @@ inline namespace kernel mpq_clear(value); } - auto ratio::denominator() const -> const_reference + auto ratio::denominator() const -> value_type { return second; } @@ -91,23 +91,11 @@ inline namespace kernel return ratio(denominator(), numerator()); } - auto ratio::numerator() const -> const_reference + auto ratio::numerator() const -> value_type { return first; } - auto ratio::simple() const -> value_type - { - if (auto x = ratio(*this); is_integer()(x)) - { - return x.numerator(); - } - else - { - return make(x); - } - } - ratio::operator double() const { return static_cast(numerator().as()) / static_cast(denominator().as()); diff --git a/test/numerical-operations.ss b/test/numerical-operations.ss index ef0855fdc..6073cce74 100644 --- a/test/numerical-operations.ss +++ b/test/numerical-operations.ss @@ -38,7 +38,7 @@ (let ((x (* 2 1/2))) - (check x => 1) + (check x (=> =) 1) (check (number? x) => #t) (check (complex? x) => #t) @@ -52,7 +52,7 @@ (let ((x (+ 1/3 1/3 1/3))) - (check x => 1) + (check x (=> =) 1) (check (number? x) => #t) (check (complex? x) => #t) @@ -64,17 +64,17 @@ (check (inexact? x) => #f) ) -(check (+ 1 1.0) => 2.0) -(check (+ 1.0 1 ) => 2.0) +(check (+ 1 1.0) (=> =) 2.0) +(check (+ 1.0 1 ) (=> =) 2.0) -(check (+ 1 1/2) => 3/2) -(check (+ 1.0 1/2) => 1.5) +(check (+ 1 1/2) (=> =) 3/2) +(check (+ 1.0 1/2) (=> =) 1.5) -(check (+ 1/2 1 ) => 3/2) -(check (+ 1/2 1.0) => 1.5) +(check (+ 1/2 1 ) (=> =) 3/2) +(check (+ 1/2 1.0) (=> =) 1.5) -(check (* 2 1/2) => 1 ) -(check (* 2.0 1/2) => 1.0) +(check (* 2 1/2) (=> =) 1 ) +(check (* 2.0 1/2) (=> =) 1.0) (check (modulo 13 4) => 1) (check (modulo -13 4) => 3) diff --git a/test/sicp-1.ss b/test/sicp-1.ss index 65dc0b89d..c7bb91687 100644 --- a/test/sicp-1.ss +++ b/test/sicp-1.ss @@ -16,7 +16,7 @@ (check (* 5 99) => 495) -(check (/ 10 5) => 2) +(check (/ 10 5) (=> =) 2) (check (+ 2.7 10) => 12.7) @@ -114,7 +114,7 @@ (check (- 9 1) => 8) -(check (/ 6 2) => 3) +(check (/ 6 2) (=> =) 3) (check (+ (* 2 4) (- 4 6)) => 6) From 5df86a29ab8ecb5c33216b8b9f4fc52ba361014d Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Mon, 15 Aug 2022 18:49:21 +0900 Subject: [PATCH 09/11] Remove `ratio`'s base class `pair` Signed-off-by: yamacir-kit --- README.md | 6 +++--- VERSION | 2 +- include/meevax/kernel/ratio.hpp | 4 +++- src/kernel/ratio.cpp | 26 ++++++++++---------------- 4 files changed, 17 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index cc530372b..f91c223bb 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.205.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.206.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.205_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.206_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.205 +Meevax Lisp System, version 0.4.206 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index bdca12ed5..93d22aa62 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.205 +0.4.206 diff --git a/include/meevax/kernel/ratio.hpp b/include/meevax/kernel/ratio.hpp index d2982933a..2a58dbc15 100644 --- a/include/meevax/kernel/ratio.hpp +++ b/include/meevax/kernel/ratio.hpp @@ -25,7 +25,7 @@ namespace meevax { inline namespace kernel { - struct ratio : protected virtual pair + struct ratio { mpq_t value; @@ -33,6 +33,8 @@ inline namespace kernel ratio(ratio const&); + ratio(ratio &&); + explicit ratio(const_reference, const_reference); explicit ratio(double); diff --git a/src/kernel/ratio.cpp b/src/kernel/ratio.cpp index 563dc876d..d25ee680f 100644 --- a/src/kernel/ratio.cpp +++ b/src/kernel/ratio.cpp @@ -27,16 +27,18 @@ inline namespace kernel mpq_init(value); } - ratio::ratio(ratio const& q) - : pair { static_cast(q) } + ratio::ratio(ratio const& other) { mpq_init(value); - mpq_set_num(value, q.numerator().as().value); - mpq_set_den(value, q.denominator().as().value); + mpq_set(value, other.value); mpq_canonicalize(value); + } - first = make(mpq_numref(value)); - second = make(mpq_denref(value)); + ratio::ratio(ratio && other) + { + mpq_init(value); + mpq_swap(value, other.value); + mpq_canonicalize(value); } ratio::ratio(const_reference x, const_reference y) @@ -45,18 +47,12 @@ inline namespace kernel mpq_set_num(value, x.as().value); mpq_set_den(value, y.as().value); mpq_canonicalize(value); - - first = make(mpq_numref(value)); - second = make(mpq_denref(value)); } ratio::ratio(double x) { mpq_init(value); mpq_set_d(value, x); - - first = make(mpq_numref(value)); - second = make(mpq_denref(value)); } ratio::ratio(external_representation const& token, int radix) @@ -71,8 +67,6 @@ inline namespace kernel else // TEMPORARY!!! { mpq_canonicalize(value); - first = make(mpq_numref(value)); - second = make(mpq_denref(value)); } } @@ -83,7 +77,7 @@ inline namespace kernel auto ratio::denominator() const -> value_type { - return second; + return make(mpq_denref(value)); } auto ratio::invert() const -> ratio @@ -93,7 +87,7 @@ inline namespace kernel auto ratio::numerator() const -> value_type { - return first; + return make(mpq_numref(value)); } ratio::operator double() const From ad67f242fb6af97b41310a7cee9137fcc0a32014 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Mon, 15 Aug 2022 22:35:49 +0900 Subject: [PATCH 10/11] Update rational arithmetic operations Signed-off-by: yamacir-kit --- README.md | 6 +-- VERSION | 2 +- include/meevax/kernel/ratio.hpp | 6 +-- src/kernel/exact_integer.cpp | 10 ++--- src/kernel/number.cpp | 74 ++++++++++++++++----------------- src/kernel/ratio.cpp | 26 ++++++++---- test/numerical-operations.ss | 2 +- 7 files changed, 67 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index f91c223bb..83e04d3fb 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.206.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.207.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.206_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.207_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.206 +Meevax Lisp System, version 0.4.207 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 93d22aa62..3e33edbc5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.206 +0.4.207 diff --git a/include/meevax/kernel/ratio.hpp b/include/meevax/kernel/ratio.hpp index 2a58dbc15..d4d97163d 100644 --- a/include/meevax/kernel/ratio.hpp +++ b/include/meevax/kernel/ratio.hpp @@ -35,7 +35,9 @@ inline namespace kernel ratio(ratio &&); - explicit ratio(const_reference, const_reference); + explicit ratio(exact_integer const&); + + explicit ratio(exact_integer const&, exact_integer const&); explicit ratio(double); @@ -45,8 +47,6 @@ inline namespace kernel auto denominator() const -> value_type; - auto invert() const -> ratio; - auto numerator() const -> value_type; explicit operator double() const; diff --git a/src/kernel/exact_integer.cpp b/src/kernel/exact_integer.cpp index 240a4a6d2..62ab132cb 100644 --- a/src/kernel/exact_integer.cpp +++ b/src/kernel/exact_integer.cpp @@ -36,15 +36,15 @@ inline namespace kernel mpz_init_set(value, z); } - exact_integer::exact_integer(exact_integer const& given) noexcept + exact_integer::exact_integer(exact_integer const& other) noexcept { - mpz_init_set(value, given.value); + mpz_init_set(value, other.value); } - exact_integer::exact_integer(exact_integer && rhs) noexcept + exact_integer::exact_integer(exact_integer && other) noexcept { - *value = *rhs.value; - mpz_init(rhs.value); + mpz_init(value); + mpz_swap(value, other.value); } exact_integer::exact_integer(int rhs) diff --git a/src/kernel/number.cpp b/src/kernel/number.cpp index 9916df6d0..06cdd5220 100644 --- a/src/kernel/number.cpp +++ b/src/kernel/number.cpp @@ -24,26 +24,26 @@ inline namespace kernel auto operator + (exact_integer const& a, exact_integer const& b) -> exact_integer { exact_integer n; mpz_add(n.value, a.value, b.value); return n; } auto operator - (exact_integer const& a, exact_integer const& b) -> exact_integer { exact_integer n; mpz_sub(n.value, a.value, b.value); return n; } auto operator * (exact_integer const& a, exact_integer const& b) -> exact_integer { exact_integer n; mpz_mul(n.value, a.value, b.value); return n; } - auto operator / (exact_integer const& a, exact_integer const& b) -> ratio { return ratio(make(a), make(b)); } + auto operator / (exact_integer const& a, exact_integer const& b) -> ratio { return ratio(a, b); } auto operator % (exact_integer const& a, exact_integer const& b) -> exact_integer { exact_integer n; mpz_tdiv_r(n.value, a.value, b.value); return n; } + auto operator ==(exact_integer const& a, exact_integer const& b) -> bool { return mpz_cmp(a.value, b.value) == 0; } auto operator !=(exact_integer const& a, exact_integer const& b) -> bool { return mpz_cmp(a.value, b.value) != 0; } auto operator < (exact_integer const& a, exact_integer const& b) -> bool { return mpz_cmp(a.value, b.value) < 0; } auto operator <=(exact_integer const& a, exact_integer const& b) -> bool { return mpz_cmp(a.value, b.value) <= 0; } - auto operator ==(exact_integer const& a, exact_integer const& b) -> bool { return mpz_cmp(a.value, b.value) == 0; } auto operator > (exact_integer const& a, exact_integer const& b) -> bool { return mpz_cmp(a.value, b.value) > 0; } auto operator >=(exact_integer const& a, exact_integer const& b) -> bool { return mpz_cmp(a.value, b.value) >= 0; } - auto operator * (exact_integer const& a, ratio const& b) -> ratio { return ratio(make(a * b.numerator().as()), b.denominator()); } - auto operator + (exact_integer const& a, ratio const& b) -> ratio { return ratio(make(a * b.denominator().as() + b.numerator().as()), b.denominator()); } - auto operator - (exact_integer const& a, ratio const& b) -> ratio { return ratio(make(a * b.denominator().as() - b.numerator().as()), b.denominator()); } - auto operator / (exact_integer const& a, ratio const& b) -> ratio { return a * b.invert(); } + auto operator + (exact_integer const& a, ratio const& b) -> ratio { ratio q; mpq_add(q.value, ratio(a).value, b.value); return q; } + 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& a, ratio const& b) -> bool { auto const x = ratio(b); return std::invoke(is_integer(), x) and a != x.numerator().as(); } - auto operator < (exact_integer const& a, ratio const& b) -> bool { auto const x = ratio(b); return std::invoke(is_integer(), x) and a < x.numerator().as(); } - auto operator <=(exact_integer const& a, ratio const& b) -> bool { auto const x = ratio(b); return std::invoke(is_integer(), x) and a <= x.numerator().as(); } - auto operator ==(exact_integer const& a, ratio const& b) -> bool { auto const x = ratio(b); return std::invoke(is_integer(), x) and a == x.numerator().as(); } - auto operator > (exact_integer const& a, ratio const& b) -> bool { auto const x = ratio(b); return std::invoke(is_integer(), x) and a > x.numerator().as(); } - auto operator >=(exact_integer const& a, ratio const& b) -> bool { auto const x = ratio(b); return std::invoke(is_integer(), x) and a >= x.numerator().as(); } + 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; } + 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; } auto operator + (exact_integer const& a, float b) -> float { return inexact_cast(a) + b; } auto operator - (exact_integer const& a, float b) -> float { return inexact_cast(a) - b; } @@ -69,29 +69,29 @@ 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 * (ratio const& a, exact_integer const& b) -> ratio { return ratio(make(a.numerator().as() * b), a.denominator()); } - auto operator + (ratio const& a, exact_integer const& b) -> ratio { return ratio(make(a.numerator().as() + a.denominator().as() * b), a.denominator()); } - auto operator - (ratio const& a, exact_integer const& b) -> ratio { return ratio(make(a.numerator().as() - a.denominator().as() * b), a.denominator()); } - auto operator / (ratio const& a, exact_integer const& b) -> ratio { return ratio(a.numerator(), make(a.denominator().as() * b)); } + 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; } + 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& a, exact_integer const& b) -> bool { auto const x = ratio(a); return std::invoke(is_integer(), x) and x.numerator().as() != b; } - auto operator < (ratio const& a, exact_integer const& b) -> bool { auto const x = ratio(a); return std::invoke(is_integer(), x) and x.numerator().as() < b; } - auto operator <=(ratio const& a, exact_integer const& b) -> bool { auto const x = ratio(a); return std::invoke(is_integer(), x) and x.numerator().as() <= b; } - auto operator ==(ratio const& a, exact_integer const& b) -> bool { auto const x = ratio(a); return std::invoke(is_integer(), x) and x.numerator().as() == b; } - auto operator > (ratio const& a, exact_integer const& b) -> bool { auto const x = ratio(a); return std::invoke(is_integer(), x) and x.numerator().as() > b; } - auto operator >=(ratio const& a, exact_integer const& b) -> bool { auto const x = ratio(a); return std::invoke(is_integer(), x) and x.numerator().as() >= b; } - - auto operator + (ratio const& a, ratio const& b) -> ratio { return ratio(make(a.numerator().as() * b.denominator().as() + b.numerator().as() * a.denominator().as()), make(a.denominator().as() * b.denominator().as())); } - auto operator - (ratio const& a, ratio const& b) -> ratio { return ratio(make(a.numerator().as() * b.denominator().as() - b.numerator().as() * a.denominator().as()), make(a.denominator().as() * b.denominator().as())); } - auto operator * (ratio const& a, ratio const& b) -> ratio { return ratio(make(a.numerator().as() * b.numerator().as()), make(a.denominator().as() * b.denominator().as())); } - auto operator / (ratio const& a, ratio const& b) -> ratio { return a * b.invert(); } + 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; } + 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; } + + auto operator + (ratio const& a, ratio const& b) -> ratio { ratio q; mpq_add(q.value, a.value, b.value); return q; } + 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& a, ratio const& b) -> bool { return (a.numerator().as() * b.denominator().as()) == (b.numerator().as() * a.denominator().as()); } - auto operator !=(ratio const& a, ratio const& b) -> bool { return (a.numerator().as() * b.denominator().as()) != (b.numerator().as() * a.denominator().as()); } - auto operator < (ratio const& a, ratio const& b) -> bool { return (a.numerator().as() * b.denominator().as()) < (b.numerator().as() * a.denominator().as()); } - auto operator <=(ratio const& a, ratio const& b) -> bool { return (a.numerator().as() * b.denominator().as()) <= (b.numerator().as() * a.denominator().as()); } - auto operator > (ratio const& a, ratio const& b) -> bool { return (a.numerator().as() * b.denominator().as()) > (b.numerator().as() * a.denominator().as()); } - auto operator >=(ratio const& a, ratio const& b) -> bool { return (a.numerator().as() * b.denominator().as()) >= (b.numerator().as() * a.denominator().as()); } + 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; } + 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; } auto operator + (ratio const& a, float b) -> float { return inexact_cast(a) + b; } auto operator - (ratio const& a, float b) -> float { return inexact_cast(a) - b; } @@ -148,10 +148,10 @@ inline namespace kernel auto operator % (double a, exact_integer const& b) -> double { return std::remainder(a, inexact_cast(b)); } auto operator ==(double a, exact_integer const& b) -> bool { return mpz_cmp_d(b.value, a) == 0; } auto operator !=(double a, exact_integer const& b) -> bool { return mpz_cmp_d(b.value, a) != 0; } - auto operator < (double a, exact_integer const& b) -> bool { return a < inexact_cast(b); } - auto operator <=(double a, exact_integer const& b) -> bool { return a <= inexact_cast(b); } - auto operator > (double a, exact_integer const& b) -> bool { return a > inexact_cast(b); } - auto operator >=(double a, exact_integer const& b) -> bool { return a >= inexact_cast(b); } + auto operator < (double a, exact_integer const& b) -> bool { return mpz_cmp_d(b.value, a) > 0; } + auto operator <=(double a, exact_integer const& b) -> bool { return mpz_cmp_d(b.value, a) >= 0; } + auto operator > (double a, exact_integer const& b) -> bool { return mpz_cmp_d(b.value, a) < 0; } + auto operator >=(double a, exact_integer const& b) -> bool { return mpz_cmp_d(b.value, a) <= 0; } auto operator + (double a, ratio const& b) -> double { return a + inexact_cast(b); } auto operator - (double a, ratio const& b) -> double { return a - inexact_cast(b); } diff --git a/src/kernel/ratio.cpp b/src/kernel/ratio.cpp index d25ee680f..06a1192b1 100644 --- a/src/kernel/ratio.cpp +++ b/src/kernel/ratio.cpp @@ -41,11 +41,17 @@ inline namespace kernel mpq_canonicalize(value); } - ratio::ratio(const_reference x, const_reference y) + ratio::ratio(exact_integer const& z) { mpq_init(value); - mpq_set_num(value, x.as().value); - mpq_set_den(value, y.as().value); + mpq_set_z(value, z.value); + } + + ratio::ratio(exact_integer const& n, exact_integer const& d) + { + mpq_init(value); + mpq_set_num(value, n.value); + mpq_set_den(value, d.value); mpq_canonicalize(value); } @@ -80,11 +86,6 @@ inline namespace kernel return make(mpq_denref(value)); } - auto ratio::invert() const -> ratio - { - return ratio(denominator(), numerator()); - } - auto ratio::numerator() const -> value_type { return make(mpq_numref(value)); @@ -97,7 +98,14 @@ inline namespace kernel auto operator <<(std::ostream & os, ratio const& datum) -> std::ostream & { - return os << datum.numerator() << cyan("/") << datum.denominator(); + auto free = [](char * data) + { + void (*free)(void *, std::size_t); + mp_get_memory_functions(nullptr, nullptr, &free); + std::invoke(free, static_cast(data), std::strlen(data) + 1); + }; + + return os << cyan(std::unique_ptr(mpq_get_str(nullptr, 10, datum.value), free).get()); } } // namespace kernel } // namespace meevax diff --git a/test/numerical-operations.ss b/test/numerical-operations.ss index 6073cce74..4e5ae4dd9 100644 --- a/test/numerical-operations.ss +++ b/test/numerical-operations.ss @@ -24,7 +24,7 @@ (let ((x (+ 1 1/2))) - (check x => 3/2) + (check x (=> =) 3/2) (check (number? x) => #t) (check (complex? x) => #t) From 265005f8b2ec27a4031228d688d1655751e8a790 Mon Sep 17 00:00:00 2001 From: yamacir-kit Date: Tue, 16 Aug 2022 00:27:14 +0900 Subject: [PATCH 11/11] Update `ratio::(numerator|denominator)` to be return `exact_integer` Signed-off-by: yamacir-kit --- README.md | 6 ++--- VERSION | 2 +- include/meevax/kernel/exact_integer.hpp | 18 +++++++-------- include/meevax/kernel/number.hpp | 6 ++--- include/meevax/kernel/ratio.hpp | 9 ++++---- src/kernel/exact_integer.cpp | 29 ++++++++++--------------- src/kernel/library.cpp | 4 ++-- src/kernel/ratio.cpp | 16 +++++++------- 8 files changed, 41 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 83e04d3fb..409ef7a61 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.207.so` and executable `meevax`. +| `all` (default) | Build shared-library `libmeevax.0.4.208.so` and executable `meevax`. | `test` | Test executable `meevax`. -| `package` | Generate debian package `meevax_0.4.207_amd64.deb`. +| `package` | Generate debian package `meevax_0.4.208_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.207 +Meevax Lisp System, version 0.4.208 Usage: meevax [OPTION...] [FILE...] diff --git a/VERSION b/VERSION index 3e33edbc5..cab5b51e7 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.207 +0.4.208 diff --git a/include/meevax/kernel/exact_integer.hpp b/include/meevax/kernel/exact_integer.hpp index 261666dd9..daba883ea 100644 --- a/include/meevax/kernel/exact_integer.hpp +++ b/include/meevax/kernel/exact_integer.hpp @@ -29,13 +29,15 @@ inline namespace kernel { mpz_t value; - explicit exact_integer() noexcept; - - explicit exact_integer(mpz_t const) noexcept; + exact_integer() noexcept; exact_integer(exact_integer const&) noexcept; - explicit exact_integer(exact_integer &&) noexcept; + exact_integer(exact_integer &&) noexcept; + + ~exact_integer(); + + explicit exact_integer(mpz_t const) noexcept; explicit exact_integer(int); @@ -47,18 +49,12 @@ inline namespace kernel explicit exact_integer(external_representation const&, int = 0); - ~exact_integer(); - auto operator=(exact_integer const&) -> exact_integer &; auto operator=(exact_integer &&) noexcept -> exact_integer &; auto operator=(external_representation const&) -> exact_integer &; - auto swap(exact_integer &) noexcept -> void; - - explicit operator bool() const; - operator int() const; operator signed long() const; @@ -68,6 +64,8 @@ inline namespace kernel explicit operator float() const; explicit operator double() const; + + explicit operator bool() const; }; auto operator ==(exact_integer const&, int const) -> bool; diff --git a/include/meevax/kernel/number.hpp b/include/meevax/kernel/number.hpp index 8e3957d7f..0363d66ff 100644 --- a/include/meevax/kernel/number.hpp +++ b/include/meevax/kernel/number.hpp @@ -195,9 +195,9 @@ inline namespace kernel } else if constexpr (std::is_same_v, ratio>) { - if (auto i = exact_integer(mpq_denref(z.value)); i == 1) + if (z.denominator() == 1) { - return z.numerator(); + return make(z.numerator()); } else { @@ -380,7 +380,7 @@ inline namespace kernel } else if constexpr (std::is_same_v, ratio>) { - return x.denominator().template as() == 1; + return x.denominator() == 1; } else { diff --git a/include/meevax/kernel/ratio.hpp b/include/meevax/kernel/ratio.hpp index d4d97163d..1b6a04d5f 100644 --- a/include/meevax/kernel/ratio.hpp +++ b/include/meevax/kernel/ratio.hpp @@ -18,7 +18,6 @@ #define INCLUDED_MEEVAX_KERNEL_RATIO_HPP #include - #include namespace meevax @@ -35,6 +34,8 @@ inline namespace kernel ratio(ratio &&); + ~ratio(); + explicit ratio(exact_integer const&); explicit ratio(exact_integer const&, exact_integer const&); @@ -43,11 +44,9 @@ inline namespace kernel explicit ratio(external_representation const&, int = 10); - ~ratio(); - - auto denominator() const -> value_type; + auto denominator() const -> exact_integer; - auto numerator() const -> value_type; + auto numerator() const -> exact_integer; explicit operator double() const; }; diff --git a/src/kernel/exact_integer.cpp b/src/kernel/exact_integer.cpp index 62ab132cb..38e20a53d 100644 --- a/src/kernel/exact_integer.cpp +++ b/src/kernel/exact_integer.cpp @@ -31,11 +31,6 @@ inline namespace kernel mpz_init(value); } - exact_integer::exact_integer(mpz_t const z) noexcept - { - mpz_init_set(value, z); - } - exact_integer::exact_integer(exact_integer const& other) noexcept { mpz_init_set(value, other.value); @@ -47,6 +42,16 @@ inline namespace kernel mpz_swap(value, other.value); } + exact_integer::~exact_integer() + { + mpz_clear(value); + } + + exact_integer::exact_integer(mpz_t const z) noexcept + { + mpz_init_set(value, z); + } + exact_integer::exact_integer(int rhs) : exact_integer(static_cast(rhs)) {} @@ -75,20 +80,15 @@ inline namespace kernel } } - exact_integer::~exact_integer() - { - mpz_clear(value); - } - auto exact_integer::operator=(exact_integer const& rhs) -> exact_integer & { mpz_set(value, rhs.value); return *this; } - auto exact_integer::operator=(exact_integer && rhs) noexcept -> exact_integer & + auto exact_integer::operator=(exact_integer && other) noexcept -> exact_integer & { - swap(rhs); + mpz_swap(value, other.value); return *this; } @@ -104,11 +104,6 @@ inline namespace kernel } } - auto exact_integer::swap(exact_integer & rhs) noexcept -> void - { - std::swap(*value, *rhs.value); - } - exact_integer::operator bool() const { return (*value)._mp_size; diff --git a/src/kernel/library.cpp b/src/kernel/library.cpp index cd0cb8110..e4bb7750d 100644 --- a/src/kernel/library.cpp +++ b/src/kernel/library.cpp @@ -571,12 +571,12 @@ inline namespace kernel library.define("ratio-numerator", [](let const& xs) { - return car(xs).as().numerator(); + return make(car(xs).as().numerator()); }); library.define("ratio-denominator", [](let const& xs) { - return car(xs).as().denominator(); + return make(car(xs).as().denominator()); }); library.define("floor", [](let const& xs) diff --git a/src/kernel/ratio.cpp b/src/kernel/ratio.cpp index 06a1192b1..fc5880337 100644 --- a/src/kernel/ratio.cpp +++ b/src/kernel/ratio.cpp @@ -63,14 +63,14 @@ inline namespace kernel ratio::ratio(external_representation const& token, int radix) { - std::regex static const pattern { "([+-]?[0-9a-f]+)/([0-9a-f]+)" }; + // std::regex static const pattern { "([+-]?[0-9a-f]+)/([0-9a-f]+)" }; - if (mpq_init(value); not std::regex_match(token, pattern) or mpq_set_str(value, token.c_str(), radix)) + if (mpq_init(value); mpq_set_str(value, token.c_str(), radix)) { mpq_clear(value); throw error(); } - else // TEMPORARY!!! + else { mpq_canonicalize(value); } @@ -81,19 +81,19 @@ inline namespace kernel mpq_clear(value); } - auto ratio::denominator() const -> value_type + auto ratio::denominator() const -> exact_integer { - return make(mpq_denref(value)); + return exact_integer(mpq_denref(value)); } - auto ratio::numerator() const -> value_type + auto ratio::numerator() const -> exact_integer { - return make(mpq_numref(value)); + return exact_integer(mpq_numref(value)); } ratio::operator double() const { - return static_cast(numerator().as()) / static_cast(denominator().as()); + return mpq_get_d(value); } auto operator <<(std::ostream & os, ratio const& datum) -> std::ostream &