forked from pmichaud/pmtcl
/
string.pm
133 lines (124 loc) · 3.92 KB
/
string.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
our sub string(*@args) {
if +@args < 1 {
error('wrong # args: should be "string subcommand ?argument ...?"');
}
my @opts := <bytelength compare equal first index is last length map match range repeat replace reverse tolower totitle toupper trim trimleft trimright wordend wordstart>;
my $cmd := _tcl::select_option(@opts, @args.shift(), 'subcommand');
if $cmd eq 'bytelength' {
if +@args != 1 {
error('wrong # args: should be "string bytelength string"');
}
return pir::bytelength__is(~@args[0]);
} elsif $cmd eq 'compare' {
if +@args == 3 {
@args.shift; # assuming -nocase here.
my $s1 := pir::upcase(@args[0]);
my $s2 := pir::upcase(@args[1]);
if ($s1 eq $s2) {
return 0;
} elsif ($s1 lt $s2) {
return -1;
} else {
return 1;
}
} else {
return '';
}
} elsif $cmd eq 'equal' {
return '';
} elsif $cmd eq 'first' {
if +@args < 2 || +@args > 3 {
error('wrong # args: should be "string first needleString haystackString ?startIndex?"');
}
my $needle := @args[0];
my $haystack := @args[1];
# XXX getIndex
my $index := @args[2]; # defaults to 0
if $index < 0 { $index := 0};
return pir::index__issi($haystack, $needle, $index);
} elsif $cmd eq 'index' {
return '';
} elsif $cmd eq 'is' {
return '';
} elsif $cmd eq 'last' {
if +@args > 3 || +@args < 2 {
error('wrong # args: should be "string last needleString haystackString ?startIndex?"');
}
my $needle := @args[0];
my $haystack := @args[1];
my $start_pos := pir::length__is($haystack);
if +@args ==3 {
# XXX getIndex
my $index := @args[2];
if $index < $start_pos {
$start_pos := $index;
}
}
# XXX This algorithm loops through from string start -
# Does parrot provide a more natural way to do this?
my $cur_pos := pir::index__issi($haystack, $needle, 0);
if $cur_pos > $start_pos || $cur_pos < 0 {
return -1;
}
my $test_pos;
while $cur_pos >= 0 && $cur_pos <= $start_pos {
$test_pos := $cur_pos;
$cur_pos := pir::index__issi($haystack, $needle, ($cur_pos+1));
}
return($test_pos);
} elsif $cmd eq 'length' {
return '';
} elsif $cmd eq 'map' {
return '';
} elsif $cmd eq 'match' {
return '';
} elsif $cmd eq 'range' {
return '';
} elsif $cmd eq 'repeat' {
return '';
} elsif $cmd eq 'replace' {
return '';
} elsif $cmd eq 'reverse' {
return '';
} elsif $cmd eq 'tolower' {
return '';
} elsif $cmd eq 'totitle' {
return '';
} elsif $cmd eq 'toupper' {
return pir::upcase(@args[0]);
} elsif $cmd eq 'trim' {
return '';
} elsif $cmd eq 'trimleft' {
return '';
} elsif $cmd eq 'trimright' {
return '';
} elsif $cmd eq 'wordend' {
return '';
} elsif $cmd eq 'wordstart' {
return '';
}
}
module _tcl {
our sub string_trim($string) {
Q:PIR {
.include 'cclass.pasm'
.local string str
$P0 = find_lex '$string'
str = $P0
.local int lpos, rpos
rpos = length str
lpos = find_not_cclass .CCLASS_WHITESPACE, str, 0, rpos
rtrim_loop:
unless rpos > lpos goto rtrim_done
dec rpos
$I0 = is_cclass .CCLASS_WHITESPACE, str, rpos
if $I0 goto rtrim_loop
rtrim_done:
inc rpos
$I0 = rpos - lpos
$S0 = substr str, lpos, $I0
%r = box $S0
};
}
}
# vim: filetype=perl6: