summaryrefslogtreecommitdiff
path: root/lib/std/strfind.myr
diff options
context:
space:
mode:
Diffstat (limited to 'lib/std/strfind.myr')
-rw-r--r--lib/std/strfind.myr51
1 files changed, 51 insertions, 0 deletions
diff --git a/lib/std/strfind.myr b/lib/std/strfind.myr
new file mode 100644
index 0000000..0ec0e85
--- /dev/null
+++ b/lib/std/strfind.myr
@@ -0,0 +1,51 @@
+use "types.use"
+use "option.use"
+
+pkg std =
+ const strfind : (haystack : byte[:], needle : byte[:] -> option(size))
+ const strrfind : (haystack : byte[:], needle : byte[:] -> option(size))
+ const strhas : (haystack : byte[:], needle : byte[:] -> bool)
+;;
+
+const strfind = {haystack, needle
+ -> strfindin(haystack, needle, 0, haystack.len)
+}
+
+const strrfind = {haystack, needle
+ -> strfindin(haystack, needle, haystack.len - 1, -1)
+}
+
+const strfindin = {haystack, needle, start, end
+ var i, j, inc : size
+
+ inc = 1
+ if start > end
+ inc = -1
+ ;;
+ for i = start; i != end; i += inc
+ /*
+ if we knew the direction we could terminate early,
+ but we allow the start and end to be passed in.
+ */
+ if i + needle.len > haystack.len
+ continue
+ ;;
+ if haystack[i] == needle[0]
+ for j = 0; j < needle.len; j++
+ if haystack[i + j] != needle[j]
+ goto nextiter
+ ;;
+ ;;
+ -> `Some i
+ ;;
+:nextiter
+ ;;
+ -> `None
+}
+
+const strhas = {haystack, needle
+ match strfind(haystack, needle)
+ | `Some _: -> true
+ | `None: -> false
+ ;;
+} \ No newline at end of file