ref: e29104d6edc5f4a756db90d9b31428192db99f9e
parent: bf6a03689f1e9f9a50ed1a9316dbfc058365143b
author: Ori Bernstein <ori@eigenstate.org>
date: Mon May 2 07:23:55 EDT 2016
Add 'splititer' string iterator.
--- a/lib/std/striter.myr
+++ b/lib/std/striter.myr
@@ -1,6 +1,8 @@
use "die"
use "types"
use "utf"
+use "strfind"
+use "option"
pkg std =
type chariter = struct
@@ -7,9 +9,16 @@
rest : byte[:]
;;
+ type splititer = struct
+ rest : byte[:]
+ split : byte[:]
+ ;;
+
impl iterable chariter -> char
+ impl iterable splititer -> byte[:]
const bychar : (str : byte[:] -> chariter)
+ const bysplit : (str : byte[:], split : byte[:] -> splititer)
;;
impl iterable chariter -> char =
@@ -27,5 +36,30 @@
const bychar = {str
-> [.rest = str]
+}
+
+impl iterable splititer -> byte[:] =
+ __iternext__ = {si, sp
+ match std.strfind(si.rest, si.split)
+ | `Some off:
+ sp# = si.rest[:off]
+ si.rest = si.rest[off + si.split.len:]
+ -> true
+ | `None:
+ if si.rest.len > 0
+ sp# = si.rest
+ si.rest = ""
+ -> true
+ ;;
+ ;;
+ -> false
+ }
+
+ __iterfin__ = {ci, c
+ }
+;;
+
+const bysplit = {str, split
+ -> [.rest = str, .split = split]
}
--- /dev/null
+++ b/lib/std/test/striter.myr
@@ -1,0 +1,19 @@
+use std
+
+const main = {
+ var chars = ['a', 'b', 'c']
+ var splits = ["foo", "+bar"]
+ var i
+
+ i = 0
+ for c in std.bychar("abc")
+ std.assert(chars[i++] == c, "wrong char")
+ ;;
+ std.assert(i == chars.len, "wrong split count")
+
+ i = 0
+ for sp in std.bysplit("foo+++bar", "++")
+ std.assert(std.streq(splits[i++], sp), "wrong split {}", sp)
+ ;;
+ std.assert(i == splits.len, "wrong split count")
+}