Skip to content

Commit

Permalink
Move the iterator logic of Str.comb(N) to RI::Ngrams
Browse files Browse the repository at this point in the history
And also make the logic a bit more general, to allow for additional
uses, such as creating ngrams of a string

No functional changes, unmeasurable performance change on Str.comb(N)
  • Loading branch information
lizmat committed Oct 9, 2022
1 parent 792418b commit e826dbd
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 63 deletions.
65 changes: 65 additions & 0 deletions src/core.c/Rakudo/Iterator.pm6
Expand Up @@ -3168,6 +3168,71 @@ class Rakudo::Iterator {
}
method NextNValues(\iterator, \times) { NextNValues.new(iterator, times) }

# Return an iterator that will produce N-grams of a given string,
# essentially a superset of capabilities that is needed for .comb(N)
# in 6.d, with 6.e allowing full access to these capabilities with
# .comb(size => step, :partial)
my class NGrams does PredictiveIterator {
has str $!str;
has Mu $!what;
has int $!size;
has int $!step;
has int $!pos;
has int $!todo;
method !SET-SELF($string, $size, $limit, $step, $partial) {
$!str = $string;
$!what := $string.WHAT;
$!size = $size < 1 ?? 1 !! $size;
$!step = $step < 1 ?? 1 !! $step;
$!pos = -$!step;
$!todo = 1 + ((nqp::chars($!str) - 1) div $!step);
$!todo = $!todo - $!size + $!step unless $partial;
$!todo = $limit
unless nqp::istype($limit,Whatever) || $limit > $!todo;
$!todo = $!todo + 1;
self
}
method new($string, $size, $limit, $step, $partial) {
$string
?? nqp::create(self)!SET-SELF($string,$size,$limit,$step,$partial)
!! Rakudo::Iterator.Empty
}
method pull-one() {
--$!todo
?? nqp::box_s(
nqp::substr($!str,($!pos = $!pos + $!step),$!size),
$!what
)
!! IterationEnd
}
method push-all(\target --> IterationEnd) {
my str $str = $!str;
my int $todo = $!todo;
my int $pos = $!pos;
my int $size = $!size;
my int $step = $!step;
my Mu $what := $!what;

nqp::while(
--$todo,
target.push(
nqp::box_s(
nqp::substr($str,($pos = $pos + $step),$size),
$what
)
)
);
$!todo = 0;
}
method count-only(--> Int:D) {
nqp::sub_i($!todo,nqp::isgt_i($!todo,0))
}
method sink-all(--> IterationEnd) { $!pos = nqp::chars($!str) }
}
method NGrams($string, $size, $limit, $step, $partial) {
NGrams.new($string, $size, $limit, $step, $partial)
}

# Return an iterator that only will return the given value once.
# Basically the same as 42 xx 1.
my class OneValue does PredictiveIterator {
Expand Down
65 changes: 2 additions & 63 deletions src/core.c/Str.pm6
Expand Up @@ -970,72 +970,11 @@ my class Str does Stringy { # declared in BOOTSTRAP
}
multi method comb(Str:D: --> Seq:D) { Seq.new(CombAll.new(self)) }

my class CombN does PredictiveIterator {
has str $!str;
has Mu $!what;
has int $!size;
has int $!pos;
has int $!todo;
method !SET-SELF($string, $size, $limit) {
$!str = $string;
$!what := $string.WHAT;
$!size = $size < 1 ?? 1 !! $size;
$!pos = -$!size;
$!todo = 1 + ((nqp::chars($!str) - 1) div $!size);
$!todo = $limit
unless nqp::istype($limit,Whatever) || $limit > $!todo;
$!todo = $!todo + 1;
self
}
method new($string, $size, $limit) {
$string
?? nqp::create(self)!SET-SELF($string, $size, $limit)
!! Rakudo::Iterator.Empty
}
method pull-one() {
--$!todo
?? nqp::box_s(
nqp::substr( #?js: NFG
$!str,
($!pos = nqp::add_i($!pos,$!size)),
$!size
),
$!what
)
!! IterationEnd
}
method push-all(\target --> IterationEnd) {
my str $str = $!str;
my int $todo = $!todo;
my int $pos = $!pos;
my int $size = $!size;
my Mu $what := $!what;

nqp::while(
--$todo,
target.push(
nqp::box_s(
nqp::substr( #?js: NFG
$str,
($pos = nqp::add_i($pos,$size)),
$size
),
$what
)
)
);
$!todo = 0;
}
method count-only(--> Int:D) {
nqp::sub_i($!todo,nqp::isgt_i($!todo,0))
}
method sink-all(--> IterationEnd) { $!pos = nqp::chars($!str) }
}

multi method comb(Str:D: Int:D $size, $limit = * --> Seq:D) {
$size <= 1 && (nqp::istype($limit,Whatever) || $limit == Inf)
?? self.comb
!! Seq.new(CombN.new(self, $size, $limit))
!! Seq.new:
Rakudo::Iterator.NGrams: self, $size, $limit, $size, True
}

my class CombPat does Iterator {
Expand Down

0 comments on commit e826dbd

Please sign in to comment.