diff --git a/src/core.c/Exception.pm6 b/src/core.c/Exception.pm6 index 12cbb22e741..0fccfd4257c 100644 --- a/src/core.c/Exception.pm6 +++ b/src/core.c/Exception.pm6 @@ -91,6 +91,10 @@ my class Exception { method is-compile-time(--> False) { } method message() { ... } + + method UPGRADE-RAT(Int $nu, Int $de) { + die "Upgrading of Rat $nu / $de not allowed" + } } my class X::SecurityPolicy is Exception {} @@ -398,6 +402,11 @@ my class CX::Take does X::Control { } my class CX::Warn does X::Control { has $.message; + + method UPGRADE-RAT(Int $nu, Int $de) is raw { + warn "Downgrading Rat $nu / $de to Num"; + nqp::p6box_n(nqp::div_In($nu,$de)) + } } my class CX::Succeed does X::Control { method message() { "" } diff --git a/src/core.c/Failure.pm6 b/src/core.c/Failure.pm6 index 629dcc53b0a..176d433fea1 100644 --- a/src/core.c/Failure.pm6 +++ b/src/core.c/Failure.pm6 @@ -130,6 +130,9 @@ my class Failure is Nil { method STORE(Failure:D: *@) { self!throw() } + method UPGRADE-RAT(Int $nu, Int $de) { + Failure.new("Upgrading of Rat $nu / $de not allowed") + } } proto sub fail(|) {*}; diff --git a/src/core.c/Num.pm6 b/src/core.c/Num.pm6 index 6150a2901b1..ee501f58a5f 100644 --- a/src/core.c/Num.pm6 +++ b/src/core.c/Num.pm6 @@ -283,6 +283,10 @@ my class Num does Real { # declared in BOOTSTRAP ?? $i !! self } + + method UPGRADE-RAT(\nu, \de) is raw { + nqp::p6box_n(nqp::div_In(nu,de)) # downgrade to float + } } my constant tau = 6.28318_53071_79586_476e0; diff --git a/src/core.c/Rat.pm6 b/src/core.c/Rat.pm6 index 6dc2e2a795a..7c61f0f64ae 100644 --- a/src/core.c/Rat.pm6 +++ b/src/core.c/Rat.pm6 @@ -40,6 +40,13 @@ my class FatRat is Cool does Rational[Int, Int] { multi method raku(FatRat:D: --> Str:D) { "FatRat.new($!numerator, $!denominator)"; } + + method UPGRADE-RAT(\nu, \de) is raw { + nqp::p6bindattrinvres( + nqp::p6bindattrinvres(nqp::create(FatRat),FatRat,'$!numerator',nu), + FatRat,'$!denominator',de + ) + } } # NORMALIZE two integer values and create a Rat/FatRat/float from them. @@ -72,6 +79,9 @@ sub DIVIDE_NUMBERS( ) } +# Initialize the $*RAT-OVERFLOW dynamic var so that it can be used +PROCESS::<$RAT-OVERFLOW> = Num; + # ALL RATIONALS MUST BE NORMALIZED, however in some operations we cannot # ever get a non-normalized Rational, if we start with a normalized Rational. # For such cases, we can use this routine, to bypass normalization step, @@ -83,7 +93,7 @@ multi sub CREATE_RATIONAL_FROM_INTS(Int:D $nu, Int:D $de, Any, Any) is raw { nqp::p6bindattrinvres(nqp::create(Rat),Rat,'$!numerator',$nu), Rat,'$!denominator',$de ) - !! nqp::p6box_n(nqp::div_In($nu,$de)) # downgrade to float + !! $*RAT-OVERFLOW.UPGRADE-RAT($nu, $de) } # already a FatRat, so keep that diff --git a/t/08-performance/05-processkeys.t b/t/08-performance/05-processkeys.t index 346207c2f30..c261ec3a542 100644 --- a/t/08-performance/05-processkeys.t +++ b/t/08-performance/05-processkeys.t @@ -13,6 +13,7 @@ my $allowed = ( Q{$PID}, Q{$RAKU}, Q{$RAKUDO_MODULE_DEBUG}, + Q{$RAT-OVERFLOW}, Q{$REPO}, Q{$SCHEDULER}, Q{$SPEC},