Skip to content

Commit

Permalink
Use new nqp::numify op for Num parsing
Browse files Browse the repository at this point in the history
- Fixes hang in parsing of nums with huge exponens
- Makes parsing of nums 80%

- Used for parsing Num literals
- Used in &val which is also used by Str.Numeric
  • Loading branch information
zoffixznet authored and AlexDaniel committed Apr 28, 2018
1 parent cc93bc9 commit 4e38bc1
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 46 deletions.
49 changes: 18 additions & 31 deletions src/Perl6/Actions.nqp
Expand Up @@ -7910,44 +7910,31 @@ class Perl6::Actions is HLL::Actions does STDActions {
}

method dec_number($/) {
my $Int := $*W.find_symbol(['Int']);
my $Num := $*W.find_symbol(['Num']);
my $parti;
my $partf;

# we build up the number in parts
if nqp::chars($<int>) {
$parti := $<int>.ast;
} else {
$parti := nqp::box_i(0, $Int);
}

if nqp::chars($<frac>) {
$partf := nqp::radix_I(10, $<frac>.Str, 0, 4, $Int);
if $<escale> { # wants a Num
make $*W.add_numeric_constant: $/, 'Num', ~$/;
} else { # wants a Rat
my $Int := $*W.find_symbol(['Int']);
my $parti;
my $partf;

$parti := nqp::mul_I($parti, $partf[1], $Int);
$parti := nqp::add_I($parti, $partf[0], $Int);
# we build up the number in parts
if nqp::chars($<int>) {
$parti := $<int>.ast;
} else {
$parti := nqp::box_i(0, $Int);
}

$partf := $partf[1];
} else {
$partf := nqp::box_i(1, $Int);
}
if nqp::chars($<frac>) {
$partf := nqp::radix_I(10, $<frac>.Str, 0, 4, $Int);

if $<escale> { # wants a Num
my num $n;
$parti := nqp::mul_I($parti, $partf[1], $Int);
$parti := nqp::add_I($parti, $partf[0], $Int);

if nqp::iseq_I($parti, nqp::box_i(0, $Int)) {
$n := 0;
$partf := $partf[1];
} else {
my $power := nqp::pow_I(nqp::box_i(10, $Int), nqp::abs_I($<escale>.ast, $Int), $Num, $Int);
$n := nqp::islt_I($<escale>.ast, nqp::box_i(0, $Int))
?? nqp::div_In($parti, nqp::mul_I($partf, $power, $Int))
!! nqp::div_In(nqp::mul_I($parti, $power, $Int), $partf);
$partf := nqp::box_i(1, $Int);
}

make $*W.add_numeric_constant($/, 'Num', $n);

} else { # wants a Rat
my $ast := $*W.add_constant('Rat', 'type_new', $parti, $partf, :nocache(1));
$ast.node($/);
make $ast;
Expand Down
19 changes: 4 additions & 15 deletions src/core/allomorphs.pm6
Expand Up @@ -308,6 +308,7 @@ multi sub val(Str:D $MAYBEVAL, :$val-or-fail) {
my int $p;

my sub parse-int-frac-exp() {
my $start-pos = $pos - nqp::istrue($neg);
# Integer part, if any
my Int $int := 0;
if nqp::isne_i($ch, 46) { # '.'
Expand Down Expand Up @@ -367,21 +368,9 @@ multi sub val(Str:D $MAYBEVAL, :$val-or-fail) {
if nqp::iseq_i($p, -1);
$pos = $p;

my $power := nqp::pow_I(10,
nqp::abs_I(nqp::atpos($parse, 0), Int), Num, Int);

if $frac {
$int := nqp::add_I(
nqp::mul_I($int, $base, Int), $frac, Int);
}
else {
$base := 1;
}
return (nqp::islt_I(nqp::atpos($parse, 0), 0)
?? nqp::div_In($int, nqp::mul_I($base, $power, Int))
!! nqp::div_In(nqp::mul_I($int, $power, Int), $base)
) # if we have a zero, handle the sign correctly
|| nqp::if(nqp::iseq_i($neg, 1), -0e0, 0e0);
# now that we're satisfied the number is in valid-ish format, use nqp's numifier
# to extract the actual num from the string.
return nqp::numify(nqp::unbox_s(nqp::substr($str, $start-pos, $pos - $start-pos)));
}

# Multiplier with exponent, if single '*' is present
Expand Down

0 comments on commit 4e38bc1

Please sign in to comment.