Skip to content

Commit c726cd5

Browse files
committed
add nqp::eqat to jvm and parrot.
1 parent d7151b3 commit c726cd5

File tree

4 files changed

+66
-2
lines changed

4 files changed

+66
-2
lines changed

src/vm/jvm/QAST/Compiler.nqp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2094,6 +2094,7 @@ QAST::OperationsJAST.add_core_op('substr', -> $qastcomp, $op {
20942094
!! QAST::Op.new( :op('substr3'), |@operands ));
20952095
});
20962096

2097+
QAST::OperationsJAST.map_classlib_core_op('eqat', $TYPE_OPS, 'string_equal_at', [$RT_STR, $RT_STR, $RT_INT], $RT_INT);
20972098
# ord can be on a the first char in a string or at a particular char.
20982099
QAST::OperationsJAST.map_classlib_core_op('ordfirst', $TYPE_OPS, 'ordfirst', [$RT_STR], $RT_INT);
20992100
QAST::OperationsJAST.map_classlib_core_op('ordat', $TYPE_OPS, 'ordat', [$RT_STR, $RT_INT], $RT_INT);

src/vm/jvm/runtime/org/perl6/nqp/runtime/Ops.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3095,6 +3095,23 @@ public static String substr3(String val, long offset, long length) {
30953095
return val.substring((int)offset, end);
30963096
}
30973097

3098+
// does a have b as a substring at offset?
3099+
public static long string_equal_at(String haystack, String needle, long offset) {
3100+
long haylen = haystack.length();
3101+
long needlelen = needle.length();
3102+
3103+
if (offset < 0) {
3104+
offset += haylen;
3105+
if (offset < 0) {
3106+
offset = 0;
3107+
}
3108+
}
3109+
if (haylen - offset < needlelen) {
3110+
return 0;
3111+
}
3112+
return haystack.regionMatches((int)offset, needle, 0, (int)needlelen) ? 1 : 0;
3113+
}
3114+
30983115
public static long ordfirst(String str) {
30993116
return str.codePointAt(0);
31003117
}

src/vm/parrot/QAST/Operations.nqp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1983,6 +1983,8 @@ QAST::Operations.add_core_op('substr', :inlinable(1), -> $qastcomp, $op {
19831983
!! QAST::Op.new( :op('substr3'), |@operands ));
19841984
});
19851985

1986+
QAST::Operations.add_core_pirop_mapping('eqat', 'nqp_string_equal_at', 'Issi', :inlinable(1));
1987+
19861988
# ord can be on a the first char in a string or at a particular char.
19871989
QAST::Operations.add_core_pirop_mapping('ordfirst', 'ord', 'Is', :inlinable(1));
19881990
QAST::Operations.add_core_pirop_mapping('ordat', 'ord', 'Isi', :inlinable(1));

src/vm/parrot/ops/nqp.ops

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3246,8 +3246,6 @@ inline op is_uprop(out INT, in STR, in STR, in INT) :base_core {
32463246
goto ADDRESS(handler);
32473247
#endif
32483248
}
3249-
3250-
32513249
/*
32523250

32533251
=item nqp_serialize_sc
@@ -3941,3 +3939,49 @@ inline op nqp_decode(out STR, invar PMC, in STR) {
39413939
if (elems > 0)
39423940
free(cbuffer);
39433941
}
3942+
3943+
/*
3944+
3945+
=item nqp_string_equal_at
3946+
3947+
Check if the String in $2 has the string in $3 at its offset $4.
3948+
3949+
=cut
3950+
3951+
*/
3952+
inline op nqp_string_equal_at(out INT, in STR, in STR, in INT) {
3953+
int32_t offset;
3954+
uint32_t cmp_index;
3955+
char done;
3956+
3957+
String_iter hay_iter;
3958+
String_iter needle_iter;
3959+
3960+
offset = (INTVAL)($4);
3961+
3962+
if (offset < 0) {
3963+
offset += ($2)->strlen;
3964+
if (offset < 0) {
3965+
offset = 0;
3966+
}
3967+
}
3968+
3969+
if (($2)->strlen - offset < ($3)->strlen || offset > ($2)->strlen) {
3970+
$1 = 0;
3971+
} else {
3972+
done = 0;
3973+
$1 = 1;
3974+
3975+
STRING_ITER_INIT(interp, &hay_iter);
3976+
STRING_iter_skip(interp, $2, &hay_iter, offset);
3977+
STRING_ITER_INIT(interp, &needle_iter);
3978+
3979+
for (cmp_index = 0; cmp_index < $3->strlen && !done; cmp_index++) {
3980+
if (STRING_iter_get_and_advance(interp, $2, &hay_iter)
3981+
!= STRING_iter_get_and_advance(interp, $3, &needle_iter)) {
3982+
$1 = 0;
3983+
done = 1;
3984+
}
3985+
}
3986+
}
3987+
}

0 commit comments

Comments
 (0)