summaryrefslogtreecommitdiff
path: root/lib/iter
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2017-12-30 19:23:12 -0800
committerOri Bernstein <ori@eigenstate.org>2017-12-30 19:23:12 -0800
commitf4a939a2cfdc00643b02c404b0acbed382964dd0 (patch)
tree107db984a46b56f0803960155dba25977df78aae /lib/iter
parentb4252aeded2d15592fe940e20f533f113000c61d (diff)
downloadmc-f4a939a2cfdc00643b02c404b0acbed382964dd0.tar.gz
Start cleaning up libstd.
minor formatting, factoring out iterutil.
Diffstat (limited to 'lib/iter')
-rw-r--r--lib/iter/bld.sub7
-rw-r--r--lib/iter/chunk.myr34
-rw-r--r--lib/iter/enum.myr30
-rw-r--r--lib/iter/ref.myr29
-rw-r--r--lib/iter/reverse.myr30
-rw-r--r--lib/iter/test/enum.myr12
-rw-r--r--lib/iter/test/reverse.myr14
-rw-r--r--lib/iter/test/zip.myr15
-rw-r--r--lib/iter/zip.myr30
9 files changed, 201 insertions, 0 deletions
diff --git a/lib/iter/bld.sub b/lib/iter/bld.sub
new file mode 100644
index 0000000..f3ba696
--- /dev/null
+++ b/lib/iter/bld.sub
@@ -0,0 +1,7 @@
+lib iter =
+ chunk.myr
+ enum.myr
+ ref.myr
+ reverse.myr
+ zip.myr
+;;
diff --git a/lib/iter/chunk.myr b/lib/iter/chunk.myr
new file mode 100644
index 0000000..5d0d68c
--- /dev/null
+++ b/lib/iter/chunk.myr
@@ -0,0 +1,34 @@
+use std
+
+pkg iter =
+ type chunkiter(@a) = struct
+ idx : std.size
+ blksz : std.size
+ sl : @a[:]
+ ;;
+
+ impl iterable chunkiter(@a) -> @a[:]
+ generic bychunk : (a : @a[:], chunk : std.size -> chunkiter(@a))
+;;
+
+generic bychunk = {a, sz
+ -> [.sl = a, .idx = 0, .blksz = sz]
+}
+
+impl iterable chunkiter(@a) -> @a[:] =
+ __iternext__ = {itp, valp
+ var len
+
+ len = std.min(itp.blksz, itp.sl.len - itp.idx)
+ if itp.idx + len == itp.sl.len
+ -> false
+ ;;
+ valp# = itp.sl[itp.idx: itp.idx + len]
+ itp.idx += itp.blksz
+ -> true
+ }
+
+ __iterfin__ = {itp, valp
+ }
+;;
+
diff --git a/lib/iter/enum.myr b/lib/iter/enum.myr
new file mode 100644
index 0000000..e59a0ae
--- /dev/null
+++ b/lib/iter/enum.myr
@@ -0,0 +1,30 @@
+use std
+
+pkg iter =
+ type enumiter(@a) = struct
+ idx : std.size
+ sl : @a[:]
+ ;;
+
+ impl iterable enumiter(@a) -> (std.size, @a)
+ generic byenum : (a : @a[:] -> enumiter(@a))
+;;
+
+generic byenum = {a
+ -> [.sl = a, .idx = 0]
+}
+
+impl iterable enumiter(@a) -> (std.size, @a) =
+ __iternext__ = {itp, valp
+ if itp.idx == itp.sl.len
+ -> false
+ ;;
+ valp# = (itp.idx, itp.sl[itp.idx])
+ itp.idx++
+ -> true
+ }
+
+ __iterfin__ = {itp, valp
+ }
+;;
+
diff --git a/lib/iter/ref.myr b/lib/iter/ref.myr
new file mode 100644
index 0000000..45813c0
--- /dev/null
+++ b/lib/iter/ref.myr
@@ -0,0 +1,29 @@
+use std
+
+pkg iter =
+ type refiter(@a) = struct
+ idx : std.size
+ sl : @a[:]
+ ;;
+ impl iterable refiter(@a) -> @a#
+ generic byref : (sl : @a[:] -> refiter(@a))
+;;
+
+generic byref = {a
+ -> [.sl = a, .idx = 0]
+}
+
+impl iterable refiter(@a) -> @a# =
+ __iternext__ = {itp, valp
+ if itp.idx == itp.sl.len
+ -> false
+ ;;
+ valp# = &itp.sl[itp.idx]
+ itp.idx++
+ -> true
+ }
+
+ __iterfin__ = {itp, valp
+ }
+;;
+
diff --git a/lib/iter/reverse.myr b/lib/iter/reverse.myr
new file mode 100644
index 0000000..3647ba6
--- /dev/null
+++ b/lib/iter/reverse.myr
@@ -0,0 +1,30 @@
+use std
+
+pkg iter =
+ type reverseiter(@a) = struct
+ sl : @a[:]
+ idx : std.size
+ ;;
+ impl iterable reverseiter(@a) -> @a
+ generic byreverse : (sl : @a[:] -> reverseiter(@a))
+;;
+
+generic byreverse = {sl
+ -> [.sl = sl, .idx = sl.len]
+}
+
+impl iterable reverseiter(@a) -> @a =
+ __iternext__ = {itp, valp
+ if itp.idx > 0
+ valp# = itp.sl[itp.idx - 1]
+ itp.idx--
+ -> true
+ else
+ -> false
+ ;;
+ }
+
+ __iterfin__ = {itp, valp
+ }
+;;
+
diff --git a/lib/iter/test/enum.myr b/lib/iter/test/enum.myr
new file mode 100644
index 0000000..5c09734
--- /dev/null
+++ b/lib/iter/test/enum.myr
@@ -0,0 +1,12 @@
+use std
+
+const main = {
+ var n
+
+ n = 0
+ for (x, i) : std.byenum([1,3,5,7,9][:])
+ std.assert(x == n, "invalid enum idx {}", x)
+ std.assert(i == n*2 + 1, "invalid enum val {}", i)
+ n++
+ ;;
+}
diff --git a/lib/iter/test/reverse.myr b/lib/iter/test/reverse.myr
new file mode 100644
index 0000000..ed4ce1c
--- /dev/null
+++ b/lib/iter/test/reverse.myr
@@ -0,0 +1,14 @@
+use std
+use iter
+
+const main = {
+ var n, l : int[:]
+
+ n = 0
+ l = [3, 2, 1, 0][:]
+ for x : iter.byreverse(l)
+ std.assert(x == n, "invalid reversed value {}, expected {}", x, n)
+ n++
+ ;;
+
+}
diff --git a/lib/iter/test/zip.myr b/lib/iter/test/zip.myr
new file mode 100644
index 0000000..57f0563
--- /dev/null
+++ b/lib/iter/test/zip.myr
@@ -0,0 +1,15 @@
+use std
+use iter
+
+const main = {
+ var n, la : int[:], lb : int[:]
+
+ n = 0
+ la = [0,2,4,6,8][:]
+ lb = [2,4][:]
+ for (a, b) : iter.byzip(la, lb)
+ std.assert(a == n*2, "invalid val from a: {}", a)
+ std.assert(b == n*2 + 2, "invalid val from b: {}", b)
+ n++
+ ;;
+}
diff --git a/lib/iter/zip.myr b/lib/iter/zip.myr
new file mode 100644
index 0000000..6e2123c
--- /dev/null
+++ b/lib/iter/zip.myr
@@ -0,0 +1,30 @@
+pkg iter =
+ type zipiter(@a, @b) = struct
+ s1 : @a[:]
+ s2 : @b[:]
+ ;;
+
+ impl iterable zipiter(@a, @b) -> (@a, @b)
+ generic byzip : (a : @a[:], b : @b[:] -> zipiter(@a, @b))
+;;
+
+generic byzip = {a, b
+ -> [.s1 = a, .s2 = b]
+}
+
+impl iterable zipiter(@a, @b) -> (@a, @b) =
+ __iternext__ = {itp, valp
+ if itp.s1.len > 0 && itp.s2.len > 0
+ valp# = (itp.s1[0], itp.s2[0])
+ itp.s1 = itp.s1[1:]
+ itp.s2 = itp.s2[1:]
+ -> true
+ else
+ -> false
+ ;;
+ }
+
+ __iterfin__ = {itp, valp
+ }
+;;
+