Skip to content

Commit 80c478b

Browse files
committed
use traits for iteration
1 parent 5060631 commit 80c478b

22 files changed

Lines changed: 775 additions & 386 deletions

bench/bf.cb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ function parse(it) {
3838
let ops = arraylist::new();
3939
let c;
4040

41-
while ((c = it()) != iter::STOP) {
41+
while ((c = iter::next(it)) != iter::STOP) {
4242
if (c == '+') {
4343
arraylist::push(ops, Op{type="inc", value=1});
4444
} else if (c == '-') {
@@ -83,6 +83,6 @@ let args = argv();
8383
if (array::length(args) != 1) {
8484
println("Usage: ./cbcvm bf.cb <program>");
8585
} else {
86-
let it = array::iter(string::chars(fs::read_file(args[0])));
86+
let it = iter::iter(fs::read_file(args[0]));
8787
run(tape_new(), parse(it));
8888
}

docs/stdlib.md

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,6 @@ Find the index of the element for which `predicate` returns true. If there is no
112112

113113
A collector for converting an iterator into an array.
114114

115-
### function `iter(array)`
116-
117-
Create an iterator from array `array`.
118-
119115
### function `length(array)`
120116

121117
Get the length of array `array`.
@@ -184,10 +180,6 @@ Insert `value` at the front of `list`
184180

185181
Get the length of the list.
186182

187-
### function `iter(list)`
188-
189-
Create an iterator over `list`.
190-
191183
### function `new()`
192184

193185
Create a new, empty linked list.
@@ -393,9 +385,9 @@ Create an iterator that counts from 0 to `to`.
393385

394386
Create an iterator that counts up from `n` indefinitely.
395387

396-
### struct `collector`
388+
### trait `Collector`
397389

398-
An struct defining the required functions to convert an iterator into an arbitrary collection.
390+
A trait for converting an iterator into an arbitrary collection.
399391

400392
### object `STOP`
401393

@@ -476,10 +468,6 @@ Create an empty arraylist with default initial capacity.
476468

477469
Create an empty arraylist with the given initial capacity.
478470

479-
### function `iter(list)`
480-
481-
Create an iterator over arraylist `list`.
482-
483471
### function `from_array(len, array)`
484472

485473
Create a new arraylist from `array`. The `len` argument should be the length
@@ -518,10 +506,6 @@ Set the value of `key` in `list` to `value`.
518506
A collector for converting an iterator of
519507
entries into an assoclist.
520508

521-
### function `iter(list)`
522-
523-
Create an iterator over the entries of `list`.
524-
525509
### function `length`
526510

527511
Check the number of items in the list.
@@ -534,10 +518,6 @@ Create an empty assoclist.
534518

535519
A compact byte array type.
536520

537-
### function `iter(bytes)`
538-
539-
Create an iterator over `bytes`.
540-
541521
### object `collector`
542522

543523
A collector for converting an iterator into byte array.
@@ -711,10 +691,6 @@ Parse `str` as an integer of base `base`. Currently only works for base 10.
711691
A collector to convert an iterator of characters
712692
or strings into a string.
713693

714-
### function `iter(str)`
715-
716-
Create an iterator over the characters in `str`.
717-
718694
### function `from_bytes(bytes)`
719695

720696
Convert a byte array to a string.
@@ -884,10 +860,6 @@ Get an iterator over the keys in `map`.
884860

885861
Return the number of values in `map`.
886862

887-
### function `iter(map)`
888-
889-
Get an iterator over the key-value pairs in `map`.
890-
891863
### function `entries(map)`
892864

893865
Get an iterator over the key-value pairs in `map`.

lib/_arraylist_impl.cb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import _array;
2+
import _iter_stop;
23

34
export struct ArrayList {
45
length,
@@ -87,6 +88,8 @@ export function foreach(self, func) {
8788
let array = self.array;
8889

8990
for (let i = 0; i < len; i += 1) {
90-
func(array[i], i, self);
91+
if (func(array[i], i, self) == _iter_stop::STOP) {
92+
break;
93+
}
9194
}
9295
}

lib/_iter.cb

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,62 @@
11
import _array;
22
import _arraylist_impl;
3+
import _iter_stop;
4+
import trait;
35

4-
export let STOP = struct {};
5-
export struct collector { init, reduce, finalize }
6+
export let STOP = _iter_stop::STOP;
67

7-
export function array_iter(array) {
8-
let i = 0;
9-
let len = _array::length(array);
10-
return function array_iterator() {
11-
if (i == len) {
8+
export let Iterable = trait::new("Iterable", [trait::method("iter")]);
9+
export let Iterator = trait::new("Iterator", [trait::method("next")]);
10+
export let Collector = trait::new("Collector", [
11+
trait::method("init"),
12+
trait::method("reduce"),
13+
trait::method("finalize"),
14+
]);
15+
16+
struct ArrayCollector {}
17+
export let array_collector = ArrayCollector {};
18+
19+
trait::impl(Collector, ArrayCollector, struct {
20+
function init(self) {
21+
return _arraylist_impl::new();
22+
}
23+
24+
function reduce(self, list, item) {
25+
_arraylist_impl::push(list, item);
26+
return list;
27+
}
28+
29+
function finalize(self, list) {
30+
return _arraylist_impl::to_array(list);
31+
}
32+
});
33+
34+
trait::impl(Iterable, trait::primitive("array"), struct {
35+
function iter(self) {
36+
return ArrayIterator {
37+
i = 0,
38+
len = _array::length(self),
39+
array = self,
40+
};
41+
}
42+
});
43+
44+
struct ArrayIterator { i, len, array }
45+
46+
trait::impl(Iterable, ArrayIterator, struct {
47+
function iter(self) {
48+
return self;
49+
}
50+
});
51+
52+
trait::impl(Iterator, ArrayIterator, struct {
53+
function next(self) {
54+
if (self.i == self.len) {
1255
return STOP;
1356
}
1457

15-
let item = array[i];
16-
i += 1;
58+
let item = self.array[self.i];
59+
self.i += 1;
1760
return item;
18-
};
19-
}
20-
21-
export let array_collector = collector {
22-
init = _arraylist_impl::new,
23-
reduce = _arraylist_impl::push,
24-
finalize = _arraylist_impl::to_array,
25-
};
61+
}
62+
});

lib/_iter_stop.cb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export let STOP = struct {};

lib/array.cb

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@ doc.add(
1414
export let length = _array::length;
1515
doc.add("function", "length(array)", "Get the length of array `array`.");
1616

17-
export let iter = _iter::array_iter;
18-
19-
doc.add("function", "iter(array)", "Create an iterator from array `array`.");
20-
2117
export let collector = _iter::array_collector;
2218

2319
doc.add("object", "collector", "A collector for converting an iterator into an array.");
@@ -58,7 +54,9 @@ export function foreach(self, func) {
5854
let len = length(self);
5955

6056
for (let i = 0; i < len; i += 1) {
61-
func(self[i], i, self);
57+
if (func(self[i], i, self) == _iter::STOP) {
58+
break;
59+
}
6260
}
6361
}
6462

lib/arraylist.cb

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import _array;
22
import _arraylist_impl;
33
import docs;
44
import iter;
5+
import trait;
56

67
let doc = docs::module("arraylist", "A growable array.");
78

@@ -16,20 +17,30 @@ doc.add(
1617
of `array`.",
1718
);
1819

19-
export function iter(self) {
20-
let i = 0;
20+
trait::impl(iter::Iterable, ArrayList, struct {
21+
function iter(self) {
22+
return ArrayListIterator { list = self, i = 0 };
23+
}
24+
});
25+
26+
struct ArrayListIterator { list, i }
27+
28+
trait::impl(iter::Iterable, ArrayListIterator, struct {
29+
function iter(self) {
30+
return self;
31+
}
32+
});
2133

22-
return function arraylist_iterator() {
23-
if (i >= self.length) {
34+
trait::impl(iter::Iterator, ArrayListIterator, struct {
35+
function next(self) {
36+
if (self.i >= self.list.length) {
2437
return iter::STOP;
2538
}
26-
let val = get(self, i);
27-
i += 1;
39+
let val = get(self.list, self.i);
40+
self.i += 1;
2841
return val;
29-
};
30-
}
31-
32-
doc.add("function", "iter(list)", "Create an iterator over arraylist `list`.");
42+
}
43+
});
3344

3445
export let with_capacity = _arraylist_impl::with_capacity;
3546

@@ -84,11 +95,23 @@ doc.add(
8495
"Push `value` on to the end of `list`, growing it if necessary.",
8596
);
8697

87-
export let collector = iter::collector {
88-
init = new,
89-
reduce = push,
90-
finalize = function (list) { return list; },
91-
};
98+
struct ArrayListCollector {}
99+
export let collector = ArrayListCollector {};
100+
101+
trait::impl(iter::Collector, ArrayListCollector, struct {
102+
function init(self) {
103+
return new();
104+
}
105+
106+
function reduce(self, list, value) {
107+
push(list, value);
108+
return list;
109+
}
110+
111+
function finalize(self, list) {
112+
return list;
113+
}
114+
});
92115

93116
doc.add("object", "collector", "A collector for converting an iterator into an arraylist.");
94117

lib/assoclist.cb

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import arraylist;
22
import docs;
33
import iter;
4+
import trait;
45

56
let doc = docs::module(
67
"assoclist",
@@ -19,18 +20,23 @@ function get_entry(self, key) {
1920
});
2021
}
2122

22-
export let iter = arraylist::iter;
23+
struct AssocListCollector {}
24+
export let collector = AssocListCollector {};
2325

24-
doc.add("function", "iter(list)", "Create an iterator over the entries of `list`.");
26+
trait::impl(iter::Collector, AssocListCollector, struct {
27+
function init(self) {
28+
return new();
29+
}
2530

26-
export let collector = iter::collector {
27-
init = new,
28-
reduce = function (list, [key, value]) {
31+
function reduce(self, list, [key, value]) {
2932
set(list, key, value);
3033
return list;
31-
},
32-
finalize = function (list) { return list; },
33-
};
34+
}
35+
36+
function finalize(self, list) {
37+
return list;
38+
}
39+
});
3440

3541
doc.add("object", "collector", "A collector for converting an iterator of
3642
entries into an assoclist.");
@@ -107,4 +113,4 @@ export function entries(self) {
107113
return arraylist::to_array(self);
108114
}
109115

110-
doc.add("function", "entries(list)", "Get all entries from `list`.");
116+
doc.add("function", "entries(list)", "Get all entries from `list`.");

lib/base64.cb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export function decode_size(payload) {
3131
let len = string::length(payload);
3232
let npadding = 0;
3333
# FIXME: not ideal
34-
iter::foreach(string::iter(payload), function (c) {
34+
iter::foreach(payload, function (c) {
3535
if (c == '=') {
3636
npadding += 1;
3737
}

0 commit comments

Comments
 (0)