Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
First shot at pure-Perl Cool.trans
It handles simple ranges and only literals as patterns.
The range unpacking is greatly inspired by (David Green)++'s p6c mail.
Also pyramidine++ for his initial implementation.
  • Loading branch information
moritz committed Jun 3, 2010
1 parent a1140cc commit 3a6b43f
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 1 deletion.
69 changes: 69 additions & 0 deletions src/core/Cool-str.pm
Expand Up @@ -133,6 +133,75 @@ augment class Cool {
pir::substr(self, $start, $len);
}

multi method trans(*@changes) {
my sub expand($s) {
return $s.list if $s ~~ Iterable|Positional;
gather for $s.comb(/ (\w) '..' (\w) | . /, :match) {
if .[0] {
take $_ for ~.[0] .. ~.[1];
} else {
take ~$_;
}
}
}

my %c;
my %prefixes;
for (@changes) -> $p {
die "$p.perl is not a Pair" unless $p ~~ Pair;
my @from = expand $p.key;
my @to = expand $p.value;
# warn "Substitution is longer than pattern\n" if @to > @from;
if @to {
@to = @to xx ceiling(@from / @to);
} else {
@to = '' xx @from;
}
for @from Z @to -> $f, $t {
if %c.exists($f) && %c{$f} ne $t {
# warn "Ambigious transliteration rule for '$f'; "
# ~ "using the first one (transliteration to '$t')";
} else {
if $f.chars > 1 {
%prefixes{$f.substr(0, 1)} //= [];
%prefixes{$f.substr(0, 1)}.push($f);
}
%c{$f} = $t;
}
}
}

# should be replaced by a proper trie implementation
# at some point
for %prefixes.keys {
%prefixes{$_}.=sort({-.chars});
}

my @res;
my $l = $.chars;
loop (my $i = 0; $i < $l; ++$i) {
my $c = $.substr($i, 1);
my $success = 0;
if %prefixes.exists($c) {
for %prefixes{$c}.list {
if self.substr($i, .chars) eq $_ {
@res.push: %c{$_};
$success = 1;
$i += .chars - 1;
last;
}
}
}
unless $success {
@res.push: %c.exists($c)
?? %c{$c}
!! $c;
}
}
@res.join: '';
}


# S32/Str says that this should always return a StrPos object
our Int multi method index($substring, $pos = 0) is export {
if ($substring.chars == 0) {
Expand Down
2 changes: 1 addition & 1 deletion t/spectest.data
Expand Up @@ -310,7 +310,7 @@ S05-modifier/pos.t
S05-modifier/repetition.t
S05-substitution/match.t
S05-substitution/subst.t
# S05-transliteration/trans.t
S05-transliteration/trans.t
# S05-transliteration/with-closure.t
S06-advanced_subroutine_features/lexical-subs.t
S06-advanced_subroutine_features/recurse.t
Expand Down

0 comments on commit 3a6b43f

Please sign in to comment.