-
Notifications
You must be signed in to change notification settings - Fork 0
/
iterators.jai
71 lines (55 loc) · 1.86 KB
/
iterators.jai
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/// Iterator interface map, filter, collect utilities
/// If the parameter is constant, this allows iterators to be passed to procedures
Iterator :: #type (value: *$T, body: Code, flags: For_Flags);
/// Iterates over a string by rune. Declares 'it_offset' (offset to start of codepoint in string) in the body's scope.
iter_runes :: (to_iterate: *string, body: Code, flags: For_Flags) #expand {
if !<<to_iterate then return;
byte_index := 0;
byte_offset := 0;
str := <<to_iterate;
width := str.data;
while str.count {
r, status := utf8_next_character(*str);
if status != .CONVERSION_OK then break;
`it := r;
`it_index := byte_index;
`it_offset := byte_offset;
#insert body;
byte_offset += str.data - width;
width = str.data;
byte_index += 1;
}
}
/// Here for consistency.
iter_ascii :: (to_iterate: *string, body: Code, flags: For_Flags) #expand {
if !<<to_iterate then return;
i := 0;
str := <<to_iterate;
while i < str.count {
`it := str.data[i];
`it_index := it;
#insert body;
i += 1;
}
}
/// Array utilities
collect :: (input: $I, output: *[..]$O, $iter: Iterator) #expand {
for :iter input array_add(output, it);
}
map :: (input: []$I, proc: (I) -> $O) -> []O {
output: [..]O;
for input array_add(*output, proc(it));
return output;
}
// @Todo: Remove the output parameter, have it return []O
map_iter :: (input: $I, output: *[..]$O, $iter: Iterator, proc: (O) -> $B) {
for :iter input array_add(output, proc(it));
}
filter :: (input: []$I, proc: (I) -> bool) -> []I {
output: [..]I;
for input if proc(it) array_add(*output, it);
return output;
}
filter_iter :: (input: $I, output: *[..]$O, $iter: Iterator, proc: (O) -> bool) {
for :iter input if proc(it) array_add(output, it);
}