1 #include <gc.h>
2 #include "ml_runtime.h"
3 #include <string.h>
4 #include "minilang.h"
5 #include "ml_macros.h"
6 #include "ml_iterfns.h"
7
8 //!iteratable
9
10 /****************************** Chained ******************************/
11
12 static ML_METHOD_DECL(SoloMethod, "->");
13 static ML_METHOD_DECL(DuoMethod, "=>");
14 static ML_METHOD_DECL(FilterSoloMethod, "->?");
15 static ML_METHOD_DECL(FilterDuoMethod, "=>?");
16
17 typedef struct ml_filter_t {
18 ml_type_t *Type;
19 ml_value_t *Function;
20 } ml_filter_t;
21
ml_chained_filter_call(ml_state_t * Caller,ml_filter_t * Filter,int Count,ml_value_t ** Args)22 static void ml_chained_filter_call(ml_state_t *Caller, ml_filter_t *Filter, int Count, ml_value_t **Args) {
23 return ml_call(Caller, Filter->Function, Count, Args);
24 }
25
26 ML_TYPE(FilterT, (MLFunctionT), "chained-filter",
27 //@filter
28 .call = (void *)ml_chained_filter_call
29 );
30
31 static ml_filter_t *FilterNil;
32
ML_FUNCTION(Filter)33 ML_FUNCTION(Filter) {
34 //@filter
35 //<Function?
36 //>filter
37 // Returns a filter for use in chained functions and iterators.
38 if (Count == 0) return (ml_value_t *)FilterNil;
39 ml_filter_t *Filter = new(ml_filter_t);
40 Filter->Type = FilterT;
41 Filter->Function = Args[0];
42 return (ml_value_t *)Filter;
43 }
44
45 typedef struct ml_chained_state_t {
46 ml_state_t Base;
47 ml_value_t *Value;
48 ml_value_t **Current;
49 } ml_chained_state_t;
50
51 static void ml_chained_state_value(ml_chained_state_t *State, ml_value_t *Value);
52
ml_chained_state_filter(ml_chained_state_t * State,ml_value_t * Value)53 static void ml_chained_state_filter(ml_chained_state_t *State, ml_value_t *Value) {
54 Value = ml_deref(Value);
55 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
56 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, Value);
57 ml_value_t **Entry = State->Current;
58 if (!Entry[0]) ML_CONTINUE(State->Base.Caller, State->Value);
59 State->Current = Entry + 1;
60 ml_value_t *Function = Entry[0];
61 if (ml_typeof(Function) != FilterT) {
62 State->Base.run = (void *)ml_chained_state_value;
63 }
64 return ml_call(State, Function, 1, &State->Value);
65 }
66
ml_chained_state_value(ml_chained_state_t * State,ml_value_t * Value)67 static void ml_chained_state_value(ml_chained_state_t *State, ml_value_t *Value) {
68 Value = ml_deref(Value);
69 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
70 ml_value_t **Entry = State->Current;
71 if (!Entry[0]) ML_CONTINUE(State->Base.Caller, Value);
72 State->Current = Entry + 1;
73 State->Value = Value;
74 ml_value_t *Function = Entry[0];
75 if (ml_typeof(Function) == FilterT) {
76 State->Base.run = (void *)ml_chained_state_filter;
77 }
78 return ml_call(State, Function, 1, &State->Value);
79 }
80
81 typedef struct ml_chained_function_t {
82 ml_type_t *Type;
83 ml_value_t *Entries[];
84 } ml_chained_function_t;
85
ml_chained_function_call(ml_state_t * Caller,ml_chained_function_t * Chained,int Count,ml_value_t ** Args)86 static void ml_chained_function_call(ml_state_t *Caller, ml_chained_function_t *Chained, int Count, ml_value_t **Args) {
87 ml_chained_state_t *State = new(ml_chained_state_t);
88 State->Base.Caller = Caller;
89 State->Base.run = (void *)ml_chained_state_value;
90 State->Base.Context = Caller->Context;
91 State->Current = Chained->Entries + 1;
92 return ml_call(State, Chained->Entries[0], Count, Args);
93 }
94
95 ML_TYPE(MLChainedFunctionT, (MLFunctionT, MLIteratableT), "chained-function",
96 .call = (void *)ml_chained_function_call
97 );
98
ml_chained(int Count,ml_value_t ** Functions)99 ml_value_t *ml_chained(int Count, ml_value_t **Functions) {
100 if (Count == 1) return Functions[0];
101 ml_chained_function_t *Chained = xnew(ml_chained_function_t, Count + 1, ml_value_t *);
102 Chained->Type = MLChainedFunctionT;
103 for (int I = 0; I < Count; ++I) Chained->Entries[I] = *Functions++;
104 return (ml_value_t *)Chained;
105 }
106
107 typedef struct ml_chained_iterator_t {
108 ml_state_t Base;
109 ml_value_t *Iterator;
110 ml_value_t **Current, **Entries;
111 ml_value_t *Values[3];
112 } ml_chained_iterator_t;
113
114 ML_TYPE(MLChainedStateT, (), "chained-state");
115
ML_TYPED_FN(ml_iter_key,MLChainedStateT,ml_state_t * Caller,ml_chained_iterator_t * State)116 static void ML_TYPED_FN(ml_iter_key, MLChainedStateT, ml_state_t *Caller, ml_chained_iterator_t *State) {
117 ML_RETURN(State->Values[0]);
118 }
119
ML_TYPED_FN(ml_iter_value,MLChainedStateT,ml_state_t * Caller,ml_chained_iterator_t * State)120 static void ML_TYPED_FN(ml_iter_value, MLChainedStateT, ml_state_t *Caller, ml_chained_iterator_t *State) {
121 ML_RETURN(State->Values[1]);
122 }
123
124 static void ml_chained_iterator_next(ml_chained_iterator_t *State, ml_value_t *Iter);
125
126 static void ml_chained_iterator_continue(ml_chained_iterator_t *State);
127
ml_chained_iterator_filter(ml_chained_iterator_t * State,ml_value_t * Value)128 static void ml_chained_iterator_filter(ml_chained_iterator_t *State, ml_value_t *Value) {
129 Value = ml_deref(Value);
130 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
131 if (Value == MLNil) {
132 State->Base.run = (void *)ml_chained_iterator_next;
133 State->Current = State->Entries;
134 return ml_iter_next((ml_state_t *)State, State->Iterator);
135 }
136 return ml_chained_iterator_continue(State);
137 }
138
ml_chained_iterator_value(ml_chained_iterator_t * State,ml_value_t * Value)139 static void ml_chained_iterator_value(ml_chained_iterator_t *State, ml_value_t *Value) {
140 Value = ml_deref(Value);
141 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
142 State->Values[1] = Value;
143 State->Values[2] = NULL;
144 return ml_chained_iterator_continue(State);
145 }
146
ml_chained_iterator_duo_key(ml_chained_iterator_t * State,ml_value_t * Value)147 static void ml_chained_iterator_duo_key(ml_chained_iterator_t *State, ml_value_t *Value) {
148 Value = ml_deref(Value);
149 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
150 State->Values[2] = State->Values[1];
151 State->Values[1] = State->Values[0];
152 State->Values[0] = Value;
153 ml_value_t **Entry = State->Current;
154 ml_value_t *Function = Entry[0];
155 if (!Function) ML_CONTINUE(State->Base.Caller, ml_error("StateError", "Missing value function for chain"));
156 State->Current = Entry + 1;
157 State->Base.run = (void *)ml_chained_iterator_value;
158 return ml_call(State, Function, 2, State->Values + 1);
159 }
160
ml_chained_iterator_continue(ml_chained_iterator_t * State)161 static void ml_chained_iterator_continue(ml_chained_iterator_t *State) {
162 ml_value_t **Entry = State->Current;
163 ml_value_t *Function = Entry[0];
164 if (!Function) ML_CONTINUE(State->Base.Caller, State);
165 if (Function == SoloMethod) {
166 Function = Entry[1];
167 if (!Function) ML_CONTINUE(State->Base.Caller, ml_error("StateError", "Missing value function for chain"));
168 State->Current = Entry + 2;
169 State->Base.run = (void *)ml_chained_iterator_value;
170 return ml_call(State, Function, 1, State->Values + 1);
171 } else if (Function == DuoMethod) {
172 Function = Entry[1];
173 if (!Function) ML_CONTINUE(State->Base.Caller, ml_error("StateError", "Missing value function for chain"));
174 State->Current = Entry + 2;
175 State->Base.run = (void *)ml_chained_iterator_duo_key;
176 return ml_call(State, Function, 2, State->Values);
177 } else if (Function == FilterSoloMethod) {
178 Function = Entry[1];
179 if (!Function) ML_CONTINUE(State->Base.Caller, ml_error("StateError", "Missing value function for chain"));
180 State->Current = Entry + 2;
181 State->Base.run = (void *)ml_chained_iterator_filter;
182 return ml_call(State, Function, 1, State->Values + 1);
183 } else if (Function == FilterDuoMethod) {
184 Function = Entry[1];
185 if (!Function) ML_CONTINUE(State->Base.Caller, ml_error("StateError", "Missing value function for chain"));
186 State->Current = Entry + 2;
187 State->Base.run = (void *)ml_chained_iterator_filter;
188 return ml_call(State, Function, 2, State->Values);
189 } else {
190 State->Current = Entry + 1;
191 State->Base.run = (void *)ml_chained_iterator_value;
192 return ml_call(State, Function, 1, State->Values + 1);
193 }
194 }
195
ml_chained_iterator_key(ml_chained_iterator_t * State,ml_value_t * Value)196 static void ml_chained_iterator_key(ml_chained_iterator_t *State, ml_value_t *Value) {
197 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
198 State->Values[0] = Value;
199 State->Base.run = (void *)ml_chained_iterator_value;
200 return ml_iter_value((ml_state_t *)State, State->Iterator);
201 }
202
ml_chained_iterator_next(ml_chained_iterator_t * State,ml_value_t * Iter)203 static void ml_chained_iterator_next(ml_chained_iterator_t *State, ml_value_t *Iter) {
204 if (ml_is_error(Iter)) ML_CONTINUE(State->Base.Caller, Iter);
205 if (Iter == MLNil) ML_CONTINUE(State->Base.Caller, Iter);
206 State->Base.run = (void *)ml_chained_iterator_key;
207 State->Current = State->Entries;
208 return ml_iter_key((ml_state_t *)State, State->Iterator = Iter);
209 }
210
ML_TYPED_FN(ml_iter_next,MLChainedStateT,ml_state_t * Caller,ml_chained_iterator_t * State)211 static void ML_TYPED_FN(ml_iter_next, MLChainedStateT, ml_state_t *Caller, ml_chained_iterator_t *State) {
212 State->Base.Caller = Caller;
213 State->Base.Context = Caller->Context;
214 State->Base.run = (void *)ml_chained_iterator_next;
215 return ml_iter_next((ml_state_t *)State, State->Iterator);
216 }
217
ML_TYPED_FN(ml_iterate,MLChainedFunctionT,ml_state_t * Caller,ml_chained_function_t * Chained)218 static void ML_TYPED_FN(ml_iterate, MLChainedFunctionT, ml_state_t *Caller, ml_chained_function_t *Chained) {
219 ml_chained_iterator_t *State = new(ml_chained_iterator_t);
220 State->Base.Type = MLChainedStateT;
221 State->Base.Caller = Caller;
222 State->Base.Context = Caller->Context;
223 State->Base.run = (void *)ml_chained_iterator_next;
224 State->Entries = Chained->Entries + 1;
225 return ml_iterate((ml_state_t *)State, Chained->Entries[0]);
226 }
227
228 ML_METHOD("->", MLFunctionT, MLFunctionT) {
229 //<Iteratable
230 //<Function
231 //>chainedfunction
232 ml_chained_function_t *Chained = xnew(ml_chained_function_t, 3, ml_value_t *);
233 Chained->Type = MLChainedFunctionT;
234 Chained->Entries[0] = Args[0];
235 Chained->Entries[1] = Args[1];
236 return (ml_value_t *)Chained;
237 }
238
239 ML_METHOD("->", MLIteratableT, MLFunctionT) {
240 //<Iteratable
241 //<Function
242 //>chainedfunction
243 ml_chained_function_t *Chained = xnew(ml_chained_function_t, 3, ml_value_t *);
244 Chained->Type = MLChainedFunctionT;
245 Chained->Entries[0] = Args[0];
246 Chained->Entries[1] = Args[1];
247 //Chained->Entries[2] = NULL;
248 return (ml_value_t *)Chained;
249 }
250
251 ML_METHOD("=>", MLIteratableT, MLFunctionT) {
252 //<Iteratable
253 //<Function
254 //>chainedfunction
255 ml_chained_function_t *Chained = xnew(ml_chained_function_t, 5, ml_value_t *);
256 Chained->Type = MLChainedFunctionT;
257 Chained->Entries[0] = Args[0];
258 Chained->Entries[1] = DuoMethod;
259 Chained->Entries[2] = ml_integer(1);
260 Chained->Entries[3] = Args[1];
261 //Chained->Entries[4] = NULL;
262 return (ml_value_t *)Chained;
263 }
264
265 ML_METHOD("=>", MLIteratableT, MLFunctionT, MLFunctionT) {
266 //<Iteratable
267 //<Function
268 //>chainedfunction
269 ml_chained_function_t *Chained = xnew(ml_chained_function_t, 5, ml_value_t *);
270 Chained->Type = MLChainedFunctionT;
271 Chained->Entries[0] = Args[0];
272 Chained->Entries[1] = DuoMethod;
273 Chained->Entries[2] = Args[1];
274 Chained->Entries[3] = Args[2];
275 //Chained->Entries[4] = NULL;
276 return (ml_value_t *)Chained;
277 }
278
279 ML_METHOD("->", MLChainedFunctionT, MLFunctionT) {
280 //<ChainedFunction
281 //<Function
282 //>chainedfunction
283 ml_chained_function_t *Base = (ml_chained_function_t *)Args[0];
284 int N = 0;
285 while (Base->Entries[N]) ++N;
286 ml_chained_function_t *Chained = xnew(ml_chained_function_t, N + 2, ml_value_t *);
287 Chained->Type = MLChainedFunctionT;
288 for (int I = 0; I < N; ++I) Chained->Entries[I] = Base->Entries[I];
289 Chained->Entries[N] = Args[1];
290 return (ml_value_t *)Chained;
291 }
292
293 ML_METHOD("=>", MLChainedFunctionT, MLFunctionT) {
294 //<ChainedFunction
295 //<Function
296 //>chainedfunction
297 ml_chained_function_t *Base = (ml_chained_function_t *)Args[0];
298 int N = 0;
299 while (Base->Entries[N]) ++N;
300 ml_chained_function_t *Chained = xnew(ml_chained_function_t, N + 4, ml_value_t *);
301 Chained->Type = MLChainedFunctionT;
302 for (int I = 0; I < N; ++I) Chained->Entries[I] = Base->Entries[I];
303 Chained->Entries[N] = DuoMethod;
304 Chained->Entries[N + 1] = ml_integer(1);
305 Chained->Entries[N + 2] = Args[1];
306 return (ml_value_t *)Chained;
307 }
308
309 ML_METHOD("=>", MLChainedFunctionT, MLFunctionT, MLFunctionT) {
310 //<ChainedFunction
311 //<Function
312 //>chainedfunction
313 ml_chained_function_t *Base = (ml_chained_function_t *)Args[0];
314 int N = 0;
315 while (Base->Entries[N]) ++N;
316 ml_chained_function_t *Chained = xnew(ml_chained_function_t, N + 4, ml_value_t *);
317 Chained->Type = MLChainedFunctionT;
318 for (int I = 0; I < N; ++I) Chained->Entries[I] = Base->Entries[I];
319 Chained->Entries[N] = DuoMethod;
320 Chained->Entries[N + 1] = Args[1];
321 Chained->Entries[N + 2] = Args[2];
322 return (ml_value_t *)Chained;
323 }
324
325 ML_METHOD("->?", MLIteratableT, MLFunctionT) {
326 //<Iteratable
327 //<Function
328 //>chainedfunction
329 ml_chained_function_t *Chained = xnew(ml_chained_function_t, 4, ml_value_t *);
330 Chained->Type = MLChainedFunctionT;
331 Chained->Entries[0] = Args[0];
332 Chained->Entries[1] = FilterSoloMethod;
333 Chained->Entries[2] = Args[1];
334 //Chained->Entries[3] = NULL;
335 return (ml_value_t *)Chained;
336 }
337
338 ML_METHOD("=>?", MLIteratableT, MLFunctionT) {
339 //<Iteratable
340 //<Function
341 //>chainedfunction
342 ml_chained_function_t *Chained = xnew(ml_chained_function_t, 4, ml_value_t *);
343 Chained->Type = MLChainedFunctionT;
344 Chained->Entries[0] = Args[0];
345 Chained->Entries[1] = FilterDuoMethod;
346 Chained->Entries[2] = Args[1];
347 //Chained->Entries[3] = NULL;
348 return (ml_value_t *)Chained;
349 }
350
351 ML_METHOD("->?", MLChainedFunctionT, MLFunctionT) {
352 //<ChainedFunction
353 //<Function
354 //>chainedfunction
355 ml_chained_function_t *Base = (ml_chained_function_t *)Args[0];
356 int N = 0;
357 while (Base->Entries[N]) ++N;
358 ml_chained_function_t *Chained = xnew(ml_chained_function_t, N + 3, ml_value_t *);
359 Chained->Type = MLChainedFunctionT;
360 for (int I = 0; I < N; ++I) Chained->Entries[I] = Base->Entries[I];
361 Chained->Entries[N] = FilterSoloMethod;
362 Chained->Entries[N + 1] = Args[1];
363 return (ml_value_t *)Chained;
364 }
365
366 ML_METHOD("=>?", MLChainedFunctionT, MLFunctionT) {
367 //<ChainedFunction
368 //<Function
369 //>chainedfunction
370 ml_chained_function_t *Base = (ml_chained_function_t *)Args[0];
371 int N = 0;
372 while (Base->Entries[N]) ++N;
373 ml_chained_function_t *Chained = xnew(ml_chained_function_t, N + 3, ml_value_t *);
374 Chained->Type = MLChainedFunctionT;
375 for (int I = 0; I < N; ++I) Chained->Entries[I] = Base->Entries[I];
376 Chained->Entries[N] = FilterDuoMethod;
377 Chained->Entries[N + 1] = Args[1];
378 return (ml_value_t *)Chained;
379 }
380
381 /****************************** Doubled ******************************/
382
383 typedef struct {
384 ml_type_t *Type;
385 ml_value_t *Iteratable, *Function;
386 } ml_doubled_t;
387
388 ML_TYPE(MLDoubledIteratorT, (MLIteratableT), "doubled");
389 //!internal
390
391 typedef struct ml_double_state_t {
392 ml_state_t Base;
393 ml_value_t *Iterator0;
394 ml_value_t *Iterator;
395 ml_value_t *Function;
396 ml_value_t *Arg;
397 } ml_double_state_t;
398
399 ML_TYPE(MLDoubledIteratorStateT, (MLStateT), "doubled-state");
400 //!internal
401
402 static void ml_double_iter0_next(ml_double_state_t *State, ml_value_t *Value);
403
ml_double_iter_next(ml_double_state_t * State,ml_value_t * Value)404 static void ml_double_iter_next(ml_double_state_t *State, ml_value_t *Value) {
405 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
406 if (Value == MLNil) {
407 State->Base.run = (void *)ml_double_iter0_next;
408 return ml_iter_next((ml_state_t *)State, State->Iterator0);
409 }
410 State->Iterator = Value;
411 ML_CONTINUE(State->Base.Caller, State);
412 }
413
ml_double_function_call(ml_double_state_t * State,ml_value_t * Value)414 static void ml_double_function_call(ml_double_state_t *State, ml_value_t *Value) {
415 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
416 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, Value);
417 State->Base.run = (void *)ml_double_iter_next;
418 return ml_iterate((ml_state_t *)State, Value);
419 }
420
ml_double_value0(ml_double_state_t * State,ml_value_t * Value)421 static void ml_double_value0(ml_double_state_t *State, ml_value_t *Value) {
422 Value = ml_deref(Value);
423 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
424 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, Value);
425 State->Base.run = (void *)ml_double_function_call;
426 State->Arg = Value;
427 ml_value_t *Function = State->Function;
428 return ml_call(State, Function, 1, &State->Arg);
429 }
430
ml_double_iter0_next(ml_double_state_t * State,ml_value_t * Value)431 static void ml_double_iter0_next(ml_double_state_t *State, ml_value_t *Value) {
432 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
433 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, Value);
434 State->Base.run = (void *)ml_double_value0;
435 return ml_iter_value((ml_state_t *)State, State->Iterator0 = Value);
436 }
437
ML_TYPED_FN(ml_iterate,MLDoubledIteratorT,ml_state_t * Caller,ml_doubled_t * Doubled)438 static void ML_TYPED_FN(ml_iterate, MLDoubledIteratorT, ml_state_t *Caller, ml_doubled_t *Doubled) {
439 ml_double_state_t *State = new(ml_double_state_t);
440 State->Base.Type = MLDoubledIteratorStateT;
441 State->Base.Caller = Caller;
442 State->Base.Context = Caller->Context;
443 State->Base.run = (void *)ml_double_iter0_next;
444 State->Function = Doubled->Function;
445 return ml_iterate((ml_state_t *)State, Doubled->Iteratable);
446 }
447
ML_TYPED_FN(ml_iter_key,MLDoubledIteratorStateT,ml_state_t * Caller,ml_double_state_t * State)448 static void ML_TYPED_FN(ml_iter_key, MLDoubledIteratorStateT, ml_state_t *Caller, ml_double_state_t *State) {
449 return ml_iter_key(Caller, State->Iterator);
450 }
451
ML_TYPED_FN(ml_iter_value,MLDoubledIteratorStateT,ml_state_t * Caller,ml_double_state_t * State)452 static void ML_TYPED_FN(ml_iter_value, MLDoubledIteratorStateT, ml_state_t *Caller, ml_double_state_t *State) {
453 return ml_iter_value(Caller, State->Iterator);
454 }
455
ML_TYPED_FN(ml_iter_next,MLDoubledIteratorStateT,ml_state_t * Caller,ml_double_state_t * State)456 static void ML_TYPED_FN(ml_iter_next, MLDoubledIteratorStateT, ml_state_t *Caller, ml_double_state_t *State) {
457 State->Base.Caller = Caller;
458 State->Base.Context = Caller->Context;
459 State->Base.run = (void *)ml_double_iter_next;
460 return ml_iter_next((ml_state_t *)State, State->Iterator);
461 }
462
463 ML_METHOD("^", MLIteratableT, MLFunctionT) {
464 //<Iteratable
465 //<Function
466 //>iteratable
467 // Returns a new iteratable that generates the keys and values from :mini:`Function(Value)` for each value generated by :mini:`Iteratable`.
468 ml_doubled_t *Doubled = new(ml_doubled_t);
469 Doubled->Type = MLDoubledIteratorT;
470 Doubled->Iteratable = Args[0];
471 Doubled->Function = Args[1];
472 return (ml_value_t *)Doubled;
473 }
474
475 /****************************** All ******************************/
476
477 static void all_iterate(ml_iter_state_t *State, ml_value_t *Value);
478
all_iter_value(ml_iter_state_t * State,ml_value_t * Value)479 static void all_iter_value(ml_iter_state_t *State, ml_value_t *Value) {
480 Value = ml_deref(Value);
481 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
482 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, Value);
483 State->Base.run = (void *)all_iterate;
484 return ml_iter_next((ml_state_t *)State, State->Iter);
485 }
486
all_iterate(ml_iter_state_t * State,ml_value_t * Value)487 static void all_iterate(ml_iter_state_t *State, ml_value_t *Value) {
488 Value = ml_deref(Value);
489 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
490 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, MLSome);
491 State->Base.run = (void *)all_iter_value;
492 return ml_iter_value((ml_state_t *)State, State->Iter = Value);
493 }
494
ML_FUNCTIONX(All)495 ML_FUNCTIONX(All) {
496 //<Iteratable
497 //>some | nil
498 // Returns :mini:`nil` if :mini:`nil` is produced by :mini:`Iterable`. Otherwise returns :mini:`some`.
499 ML_CHECKX_ARG_COUNT(1);
500 ML_CHECKX_ARG_TYPE(0, MLIteratableT);
501 ml_iter_state_t *State = new(ml_iter_state_t);
502 State->Base.Caller = Caller;
503 State->Base.run = (void *)all_iterate;
504 State->Base.Context = Caller->Context;
505 return ml_iterate((ml_state_t *)State, ml_chained(Count, Args));
506 }
507
508 /****************************** First ******************************/
509
first_iterate(ml_state_t * State,ml_value_t * Value)510 static void first_iterate(ml_state_t *State, ml_value_t *Value) {
511 if (ml_is_error(Value)) ML_CONTINUE(State->Caller, Value);
512 if (Value == MLNil) ML_CONTINUE(State->Caller, Value);
513 return ml_iter_value(State->Caller, Value);
514 }
515
ML_FUNCTIONX(First)516 ML_FUNCTIONX(First) {
517 //<Iteratable
518 //>any | nil
519 // Returns the first value produced by :mini:`Iteratable`.
520 ML_CHECKX_ARG_COUNT(1);
521 ML_CHECKX_ARG_TYPE(0, MLIteratableT);
522 ml_state_t *State = new(ml_state_t);
523 State->Caller = Caller;
524 State->run = first_iterate;
525 State->Context = Caller->Context;
526 return ml_iterate(State, ml_chained(Count, Args));
527 }
528
first2_iter_value(ml_iter_state_t * State,ml_value_t * Value)529 static void first2_iter_value(ml_iter_state_t *State, ml_value_t *Value) {
530 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
531 ml_tuple_set(State->Values[0], 2, Value);
532 ML_CONTINUE(State->Base.Caller, State->Values[0]);
533 }
534
first2_iter_key(ml_iter_state_t * State,ml_value_t * Value)535 static void first2_iter_key(ml_iter_state_t *State, ml_value_t *Value) {
536 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
537 ml_tuple_set(State->Values[0], 1, Value);
538 State->Base.run = (ml_state_fn)first2_iter_value;
539 return ml_iter_value((ml_state_t *)State, State->Iter);
540 }
541
first2_iterate(ml_iter_state_t * State,ml_value_t * Value)542 static void first2_iterate(ml_iter_state_t *State, ml_value_t *Value) {
543 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
544 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, Value);
545 State->Base.run = (ml_state_fn)first2_iter_key;
546 return ml_iter_key((ml_state_t *)State, State->Iter = Value);
547 }
548
ML_FUNCTIONX(First2)549 ML_FUNCTIONX(First2) {
550 //<Iteratable
551 //>tuple(any, any) | nil
552 // Returns the first key and value produced by :mini:`Iteratable`.
553 ML_CHECKX_ARG_COUNT(1);
554 ML_CHECKX_ARG_TYPE(0, MLIteratableT);
555 ml_iter_state_t *State = xnew(ml_iter_state_t, 1, ml_value_t *);
556 State->Base.Caller = Caller;
557 State->Base.run = (ml_state_fn)first2_iterate;
558 State->Base.Context = Caller->Context;
559 State->Values[0] = ml_tuple(2);
560 return ml_iterate((ml_state_t *)State, ml_chained(Count, Args));
561 }
562
563 static void last_iterate(ml_iter_state_t *State, ml_value_t *Value);
564
last_value(ml_iter_state_t * State,ml_value_t * Value)565 static void last_value(ml_iter_state_t *State, ml_value_t *Value) {
566 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
567 State->Values[0] = Value;
568 State->Base.run = (void *)last_iterate;
569 return ml_iter_next((ml_state_t *)State, State->Iter);
570 }
571
last_iterate(ml_iter_state_t * State,ml_value_t * Value)572 static void last_iterate(ml_iter_state_t *State, ml_value_t *Value) {
573 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
574 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, State->Values[0]);
575 State->Base.run = (void *)last_value;
576 return ml_iter_value((ml_state_t *)State, State->Iter = Value);
577 }
578
ML_FUNCTIONX(Last)579 ML_FUNCTIONX(Last) {
580 //<Iteratable
581 //>any | nil
582 // Returns the last value produced by :mini:`Iteratable`.
583 ML_CHECKX_ARG_COUNT(1);
584 ML_CHECKX_ARG_TYPE(0, MLIteratableT);
585 ml_iter_state_t *State = xnew(ml_iter_state_t, 1, ml_value_t *);
586 State->Base.Caller = Caller;
587 State->Base.run = (void *)last_iterate;
588 State->Base.Context = Caller->Context;
589 State->Values[0] = MLNil;
590 return ml_iterate((ml_state_t *)State, ml_chained(Count, Args));
591 }
592
593 static void last2_iterate(ml_iter_state_t *State, ml_value_t *Value);
594
last2_value(ml_iter_state_t * State,ml_value_t * Value)595 static void last2_value(ml_iter_state_t *State, ml_value_t *Value) {
596 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
597 State->Values[1] = Value;
598 State->Base.run = (void *)last2_iterate;
599 return ml_iter_next((ml_state_t *)State, State->Iter);
600 }
601
last2_key(ml_iter_state_t * State,ml_value_t * Value)602 static void last2_key(ml_iter_state_t *State, ml_value_t *Value) {
603 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
604 State->Values[0] = Value;
605 State->Base.run = (void *)last2_value;
606 return ml_iter_value((ml_state_t *)State, State->Iter);
607 }
608
last2_iterate(ml_iter_state_t * State,ml_value_t * Value)609 static void last2_iterate(ml_iter_state_t *State, ml_value_t *Value) {
610 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
611 if (Value == MLNil) {
612 if (State->Values[0]) {
613 ml_value_t *Tuple = ml_tuple(2);
614 ml_tuple_set(Tuple, 1, State->Values[0]);
615 ml_tuple_set(Tuple, 2, State->Values[1]);
616 ML_CONTINUE(State->Base.Caller, Tuple);
617 } else {
618 ML_CONTINUE(State->Base.Caller, MLNil);
619 }
620 }
621 State->Base.run = (void *)last2_key;
622 return ml_iter_key((ml_state_t *)State, State->Iter = Value);
623 }
624
ML_FUNCTIONX(Last2)625 ML_FUNCTIONX(Last2) {
626 //<Iteratable
627 //>tuple(any, any) | nil
628 // Returns the last key and value produced by :mini:`Iteratable`.
629 ML_CHECKX_ARG_COUNT(1);
630 ML_CHECKX_ARG_TYPE(0, MLIteratableT);
631 ml_iter_state_t *State = xnew(ml_iter_state_t, 3, ml_value_t *);
632 State->Base.Caller = Caller;
633 State->Base.run = (void *)last2_iterate;
634 State->Base.Context = Caller->Context;
635 return ml_iterate((ml_state_t *)State, ml_chained(Count, Args));
636 }
637
638 typedef struct ml_count_state_t {
639 ml_state_t Base;
640 ml_value_t *Iter;
641 long Count;
642 } ml_count_state_t;
643
count_iterate(ml_count_state_t * State,ml_value_t * Value)644 static void count_iterate(ml_count_state_t *State, ml_value_t *Value) {
645 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
646 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, ml_integer(State->Count));
647 ++State->Count;
648 return ml_iter_next((ml_state_t *)State, State->Iter = Value);
649 }
650
ML_METHODX(MLIterCount,MLIteratableT)651 ML_METHODX(MLIterCount, MLIteratableT) {
652 //@count
653 //<Iteratable
654 //>integer
655 // Returns the count of the values produced by :mini:`Iteratable`.
656 ml_count_state_t *State = new(ml_count_state_t);
657 State->Base.Caller = Caller;
658 State->Base.run = (void *)count_iterate;
659 State->Base.Context = Caller->Context;
660 State->Count = 0;
661 return ml_iterate((ml_state_t *)State, ml_chained(Count, Args));
662 }
663
664 typedef struct ml_count2_state_t {
665 ml_state_t Base;
666 ml_value_t *Iter;
667 ml_value_t *Counts;
668 } ml_count2_state_t;
669
670 static void count2_iterate(ml_count2_state_t *State, ml_value_t *Value);
671
count2_value(ml_count2_state_t * State,ml_value_t * Value)672 static void count2_value(ml_count2_state_t *State, ml_value_t *Value) {
673 Value = ml_deref(Value);
674 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
675 if (Value != MLNil) {
676 ml_map_node_t *Node = ml_map_slot(State->Counts, Value);
677 Node->Value = (ml_value_t *)((char *)Node->Value + 1);
678 }
679 State->Base.run = (void *)count2_iterate;
680 return ml_iter_next((ml_state_t *)State, State->Iter);
681 }
682
count2_iterate(ml_count2_state_t * State,ml_value_t * Value)683 static void count2_iterate(ml_count2_state_t *State, ml_value_t *Value) {
684 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
685 if (Value == MLNil) {
686 ML_MAP_FOREACH(State->Counts, Iter) Iter->Value = ml_integer((char *)Iter->Value - (char *)0);
687 ML_CONTINUE(State->Base.Caller, State->Counts);
688 }
689 State->Base.run = (void *)count2_value;
690 return ml_iter_value((ml_state_t *)State, State->Iter = Value);
691 }
692
ML_FUNCTIONX(Count2)693 ML_FUNCTIONX(Count2) {
694 //<Iteratable
695 //>map
696 // Returns a map of the values produced by :mini:`Iteratable` with associated counts.
697 ML_CHECKX_ARG_COUNT(1);
698 ML_CHECKX_ARG_TYPE(0, MLIteratableT);
699 ml_count2_state_t *State = new(ml_count2_state_t);
700 State->Base.Caller = Caller;
701 State->Base.run = (void *)count2_iterate;
702 State->Base.Context = Caller->Context;
703 State->Counts = ml_map();
704 return ml_iterate((ml_state_t *)State, ml_chained(Count, Args));
705 }
706
707 static ML_METHOD_DECL(LessMethod, "<");
708 static ML_METHOD_DECL(GreaterMethod, ">");
709 static ML_METHOD_DECL(AddMethod, "+");
710 static ML_METHOD_DECL(MulMethod, "*");
711
712 static void reduce_iter_next(ml_iter_state_t *State, ml_value_t *Value);
713
reduce_call(ml_iter_state_t * State,ml_value_t * Value)714 static void reduce_call(ml_iter_state_t *State, ml_value_t *Value) {
715 Value = ml_deref(Value);
716 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
717 if (Value != MLNil) State->Values[1] = Value;
718 State->Base.run = (void *)reduce_iter_next;
719 return ml_iter_next((ml_state_t *)State, State->Iter);
720 }
721
reduce_next_value(ml_iter_state_t * State,ml_value_t * Value)722 static void reduce_next_value(ml_iter_state_t *State, ml_value_t *Value) {
723 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
724 ml_value_t *Compare = State->Values[0];
725 State->Values[2] = Value;
726 State->Base.run = (void *)reduce_call;
727 return ml_call(State, Compare, 2, State->Values + 1);
728 }
729
reduce_iter_next(ml_iter_state_t * State,ml_value_t * Value)730 static void reduce_iter_next(ml_iter_state_t *State, ml_value_t *Value) {
731 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
732 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, State->Values[1] ?: MLNil);
733 State->Base.run = (void *)reduce_next_value;
734 return ml_iter_value((ml_state_t *)State, State->Iter = Value);
735 }
736
reduce_first_value(ml_iter_state_t * State,ml_value_t * Value)737 static void reduce_first_value(ml_iter_state_t *State, ml_value_t *Value) {
738 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
739 State->Values[1] = Value;
740 State->Base.run = (void *)reduce_iter_next;
741 return ml_iter_next((ml_state_t *)State, State->Iter);
742 }
743
reduce_iterate(ml_iter_state_t * State,ml_value_t * Value)744 static void reduce_iterate(ml_iter_state_t *State, ml_value_t *Value) {
745 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
746 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, MLNil);
747 State->Base.run = State->Values[1] ? (void *)reduce_next_value : (void *)reduce_first_value;
748 return ml_iter_value((ml_state_t *)State, State->Iter = Value);
749 }
750
ML_FUNCTIONX(Reduce)751 ML_FUNCTIONX(Reduce) {
752 //<Initial?:any
753 //<Iteratable:iteratable
754 //<Fn:function
755 //>any | nil
756 // Returns :mini:`Fn(Fn( ... Fn(Initial, V/1), V/2) ..., V/n)` where :mini:`V/i` are the values produced by :mini:`Iteratable`.
757 // If :mini:`Initial` is omitted, first value produced by :mini:`Iteratable` is used.
758 ML_CHECKX_ARG_COUNT(2);
759 if (Count == 2) {
760 ML_CHECKX_ARG_TYPE(0, MLIteratableT);
761 ML_CHECKX_ARG_TYPE(1, MLFunctionT);
762 ml_iter_state_t *State = xnew(ml_iter_state_t, 3, ml_value_t *);
763 State->Base.Caller = Caller;
764 State->Base.run = (void *)reduce_iterate;
765 State->Base.Context = Caller->Context;
766 State->Values[0] = Args[1];
767 return ml_iterate((ml_state_t *)State, Args[0]);
768 } else {
769 ML_CHECKX_ARG_TYPE(1, MLIteratableT);
770 ML_CHECKX_ARG_TYPE(2, MLFunctionT);
771 ml_iter_state_t *State = xnew(ml_iter_state_t, 3, ml_value_t *);
772 State->Base.Caller = Caller;
773 State->Base.run = (void *)reduce_iterate;
774 State->Base.Context = Caller->Context;
775 State->Values[0] = Args[2];
776 State->Values[1] = Args[0];
777 return ml_iterate((ml_state_t *)State, Args[1]);
778 }
779 }
780
ML_FUNCTIONX(Min)781 ML_FUNCTIONX(Min) {
782 //<Iteratable
783 //>any | nil
784 // Returns the smallest value (based on :mini:`<`) produced by :mini:`Iteratable`.
785 ML_CHECKX_ARG_COUNT(1);
786 ML_CHECKX_ARG_TYPE(0, MLIteratableT);
787 ml_iter_state_t *State = xnew(ml_iter_state_t, 3, ml_value_t *);
788 State->Base.Caller = Caller;
789 State->Base.run = (void *)reduce_iterate;
790 State->Base.Context = Caller->Context;
791 State->Values[0] = GreaterMethod;
792 return ml_iterate((ml_state_t *)State, ml_chained(Count, Args));
793 }
794
ML_FUNCTIONX(Max)795 ML_FUNCTIONX(Max) {
796 //<Iteratable
797 //>any | nil
798 // Returns the largest value (based on :mini:`>`) produced by :mini:`Iteratable`.
799 ML_CHECKX_ARG_COUNT(1);
800 ML_CHECKX_ARG_TYPE(0, MLIteratableT);
801 ml_iter_state_t *State = xnew(ml_iter_state_t, 3, ml_value_t *);
802 State->Base.Caller = Caller;
803 State->Base.run = (void *)reduce_iterate;
804 State->Base.Context = Caller->Context;
805 State->Values[0] = LessMethod;
806 return ml_iterate((ml_state_t *)State, ml_chained(Count, Args));
807 }
808
ML_FUNCTIONX(Sum)809 ML_FUNCTIONX(Sum) {
810 //<Iteratable
811 //>any | nil
812 // Returns the sum of the values (based on :mini:`+`) produced by :mini:`Iteratable`.
813 ML_CHECKX_ARG_COUNT(1);
814 ML_CHECKX_ARG_TYPE(0, MLIteratableT);
815 ml_iter_state_t *State = xnew(ml_iter_state_t, 3, ml_value_t *);
816 State->Base.Caller = Caller;
817 State->Base.run = (void *)reduce_iterate;
818 State->Base.Context = Caller->Context;
819 State->Values[0] = AddMethod;
820 return ml_iterate((ml_state_t *)State, ml_chained(Count, Args));
821 }
822
ML_FUNCTIONX(Prod)823 ML_FUNCTIONX(Prod) {
824 //<Iteratable
825 //>any | nil
826 // Returns the product of the values (based on :mini:`*`) produced by :mini:`Iteratable`.
827 ML_CHECKX_ARG_COUNT(1);
828 ML_CHECKX_ARG_TYPE(0, MLIteratableT);
829 ml_iter_state_t *State = xnew(ml_iter_state_t, 3, ml_value_t *);
830 State->Base.Caller = Caller;
831 State->Base.run = (void *)reduce_iterate;
832 State->Base.Context = Caller->Context;
833 State->Values[0] = MulMethod;
834 return ml_iterate((ml_state_t *)State, ml_chained(Count, Args));
835 }
836
837 typedef struct ml_join_state_t {
838 ml_state_t Base;
839 const char *Separator;
840 ml_value_t *Iter;
841 ml_stringbuffer_t Buffer[1];
842 size_t SeparatorLength;
843 } ml_join_state_t;
844
845 static void join_append(ml_join_state_t *State, ml_value_t *Value);
846
join_next(ml_join_state_t * State,ml_value_t * Value)847 static void join_next(ml_join_state_t *State, ml_value_t *Value) {
848 Value = ml_deref(Value);
849 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
850 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, ml_stringbuffer_value(State->Buffer));
851 ml_stringbuffer_add(State->Buffer, State->Separator, State->SeparatorLength);
852 State->Base.run = (void *)join_append;
853 return ml_iter_value((ml_state_t *)State, State->Iter = Value);
854 }
855
join_append(ml_join_state_t * State,ml_value_t * Value)856 static void join_append(ml_join_state_t *State, ml_value_t *Value) {
857 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
858 ml_stringbuffer_append(State->Buffer, Value);
859 State->Base.run = (void *)join_next;
860 return ml_iter_next((ml_state_t *)State, State->Iter);
861 }
862
join_first(ml_join_state_t * State,ml_value_t * Value)863 static void join_first(ml_join_state_t *State, ml_value_t *Value) {
864 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
865 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, ml_stringbuffer_value(State->Buffer));
866 State->Base.run = (void *)join_append;
867 return ml_iter_value((ml_state_t *)State, State->Iter = Value);
868 }
869
870 ML_METHODVX("join", MLIteratableT, MLStringT) {
871 //<Iteratable
872 //<Separator
873 //>string
874 // Joins the elements of :mini:`Iteratable` into a string using :mini:`Separator` between elements.
875 ml_join_state_t *State = new(ml_join_state_t);
876 State->Base.Caller = Caller;
877 State->Base.run = (void *)join_first;
878 State->Base.Context = Caller->Context;
879 State->Separator = ml_string_value(Args[1]);
880 State->SeparatorLength = ml_string_length(Args[1]);
881 State->Buffer[0] = (ml_stringbuffer_t)ML_STRINGBUFFER_INIT;
882 return ml_iterate((ml_state_t *)State, Args[0]);
883 }
884
885 static void reduce2_iter_next(ml_iter_state_t *State, ml_value_t *Value);
886
reduce2_next_key(ml_iter_state_t * State,ml_value_t * Value)887 static void reduce2_next_key(ml_iter_state_t *State, ml_value_t *Value) {
888 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
889 State->Values[1] = Value;
890 State->Base.run = (void *)reduce2_iter_next;
891 return ml_iter_next((ml_state_t *)State, State->Iter);
892 }
893
reduce2_call(ml_iter_state_t * State,ml_value_t * Value)894 static void reduce2_call(ml_iter_state_t *State, ml_value_t *Value) {
895 Value = ml_deref(Value);
896 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
897 if (Value != MLNil) {
898 State->Values[2] = Value;
899 State->Base.run = (void *)reduce2_next_key;
900 return ml_iter_key((ml_state_t *)State, State->Iter);
901 } else {
902 State->Base.run = (void *)reduce2_iter_next;
903 return ml_iter_next((ml_state_t *)State, State->Iter);
904 }
905 }
906
reduce2_next_value(ml_iter_state_t * State,ml_value_t * Value)907 static void reduce2_next_value(ml_iter_state_t *State, ml_value_t *Value) {
908 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
909 ml_value_t *Function = State->Values[0];
910 State->Values[3] = Value;
911 State->Base.run = (void *)reduce2_call;
912 return ml_call(State, Function, 2, State->Values + 2);
913 }
914
reduce2_iter_next(ml_iter_state_t * State,ml_value_t * Value)915 static void reduce2_iter_next(ml_iter_state_t *State, ml_value_t *Value) {
916 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
917 if (Value == MLNil) {
918 if (State->Values[1]) {
919 ml_value_t *Tuple = ml_tuple(2);
920 ml_tuple_set(Tuple, 1, State->Values[1]);
921 ml_tuple_set(Tuple, 2, State->Values[2]);
922 ML_CONTINUE(State->Base.Caller, Tuple);
923 } else {
924 ML_CONTINUE(State->Base.Caller, MLNil);
925 }
926 }
927 State->Base.run = (void *)reduce2_next_value;
928 return ml_iter_value((ml_state_t *)State, State->Iter = Value);
929 }
930
reduce2_first_value(ml_iter_state_t * State,ml_value_t * Value)931 static void reduce2_first_value(ml_iter_state_t *State, ml_value_t *Value) {
932 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
933 State->Values[2] = Value;
934 State->Base.run = (void *)reduce2_iter_next;
935 return ml_iter_next((ml_state_t *)State, State->Iter);
936 }
937
reduce2_first_key(ml_iter_state_t * State,ml_value_t * Value)938 static void reduce2_first_key(ml_iter_state_t *State, ml_value_t *Value) {
939 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
940 State->Values[1] = Value;
941 State->Base.run = (void *)reduce2_first_value;
942 return ml_iter_value((ml_state_t *)State, State->Iter);
943 }
944
reduce2_iterate(ml_iter_state_t * State,ml_value_t * Value)945 static void reduce2_iterate(ml_iter_state_t *State, ml_value_t *Value) {
946 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
947 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, MLNil);
948 State->Base.run = (void *)reduce2_first_key;
949 return ml_iter_key((ml_state_t *)State, State->Iter = Value);
950 }
951
ML_FUNCTIONX(Reduce2)952 ML_FUNCTIONX(Reduce2) {
953 //<Iteratable
954 //<Fn
955 //>any | nil
956 ML_CHECKX_ARG_COUNT(2);
957 ML_CHECKX_ARG_TYPE(0, MLIteratableT);
958 ML_CHECKX_ARG_TYPE(1, MLFunctionT);
959 ml_iter_state_t *State = xnew(ml_iter_state_t, 4, ml_value_t *);
960 State->Base.Caller = Caller;
961 State->Base.run = (void *)reduce2_iterate;
962 State->Base.Context = Caller->Context;
963 State->Values[0] = Args[1];
964 return ml_iterate((ml_state_t *)State, Args[0]);
965 }
966
ML_FUNCTIONX(Min2)967 ML_FUNCTIONX(Min2) {
968 //<Iteratable
969 //>any | nil
970 // Returns a tuple with the key and value of the smallest value (based on :mini:`<`) produced by :mini:`Iteratable`.
971 ML_CHECKX_ARG_COUNT(1);
972 ML_CHECKX_ARG_TYPE(0, MLIteratableT);
973 ml_iter_state_t *State = xnew(ml_iter_state_t, 4, ml_value_t *);
974 State->Base.Caller = Caller;
975 State->Base.run = (void *)reduce2_iterate;
976 State->Base.Context = Caller->Context;
977 State->Values[0] = GreaterMethod;
978 return ml_iterate((ml_state_t *)State, ml_chained(Count, Args));
979 }
980
ML_FUNCTIONX(Max2)981 ML_FUNCTIONX(Max2) {
982 //<Iteratable
983 //>any | nil
984 // Returns a tuple with the key and value of the largest value (based on :mini:`>`) produced by :mini:`Iteratable`.
985 ML_CHECKX_ARG_COUNT(1);
986 ML_CHECKX_ARG_TYPE(0, MLIteratableT);
987 ml_iter_state_t *State = xnew(ml_iter_state_t, 4, ml_value_t *);
988 State->Base.Caller = Caller;
989 State->Base.run = (void *)reduce2_iterate;
990 State->Base.Context = Caller->Context;
991 State->Values[0] = LessMethod;
992 return ml_iterate((ml_state_t *)State, ml_chained(Count, Args));
993 }
994
995 typedef struct ml_stacked_t {
996 ml_type_t *Type;
997 ml_value_t *Initial, *Value, *ReduceFn;
998 } ml_stacked_t;
999
1000 ML_TYPE(MLStackedT, (MLIteratableT), "stacked");
1001 //!internal
1002
1003 ML_TYPE(MLStackedStateT, (), "stacked-state");
1004 //!internal
1005
1006 static void stacked_iter_next(ml_iter_state_t *State, ml_value_t *Value);
1007
stacked_call(ml_iter_state_t * State,ml_value_t * Value)1008 static void stacked_call(ml_iter_state_t *State, ml_value_t *Value) {
1009 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
1010 State->Values[1] = Value;
1011 State->Base.run = (void *)stacked_iter_next;
1012 ML_CONTINUE(State->Base.Caller, State);
1013 }
1014
stacked_next_value(ml_iter_state_t * State,ml_value_t * Value)1015 static void stacked_next_value(ml_iter_state_t *State, ml_value_t *Value) {
1016 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
1017 ml_value_t *ReduceFn = State->Values[0];
1018 State->Values[2] = Value;
1019 State->Base.run = (void *)stacked_call;
1020 return ml_call(State, ReduceFn, 2, State->Values + 1);
1021 }
1022
stacked_iter_next(ml_iter_state_t * State,ml_value_t * Value)1023 static void stacked_iter_next(ml_iter_state_t *State, ml_value_t *Value) {
1024 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
1025 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, MLNil);
1026 State->Base.run = (void *)stacked_next_value;
1027 return ml_iter_value((ml_state_t *)State, State->Iter = Value);
1028 }
1029
stacked_first_value(ml_iter_state_t * State,ml_value_t * Value)1030 static void stacked_first_value(ml_iter_state_t *State, ml_value_t *Value) {
1031 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
1032 State->Values[1] = Value;
1033 State->Base.run = (void *)stacked_iter_next;
1034 ML_CONTINUE(State->Base.Caller, State);
1035 }
1036
stacked_iterate(ml_iter_state_t * State,ml_value_t * Value)1037 static void stacked_iterate(ml_iter_state_t *State, ml_value_t *Value) {
1038 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
1039 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, MLNil);
1040 if (State->Values[1]) {
1041 State->Base.run = (void *)stacked_next_value;
1042 } else {
1043 State->Base.run = (void *)stacked_first_value;
1044 }
1045 return ml_iter_value((ml_state_t *)State, State->Iter = Value);
1046 }
1047
1048
ML_TYPED_FN(ml_iter_key,MLStackedStateT,ml_state_t * Caller,ml_iter_state_t * State)1049 static void ML_TYPED_FN(ml_iter_key, MLStackedStateT, ml_state_t *Caller, ml_iter_state_t *State) {
1050 State->Base.Caller = Caller;
1051 return ml_iter_key(Caller, State->Iter);
1052 }
1053
ML_TYPED_FN(ml_iter_value,MLStackedStateT,ml_state_t * Caller,ml_iter_state_t * State)1054 static void ML_TYPED_FN(ml_iter_value, MLStackedStateT, ml_state_t *Caller, ml_iter_state_t *State) {
1055 State->Base.Caller = Caller;
1056 ML_RETURN(State->Values[1]);
1057 }
1058
ML_TYPED_FN(ml_iter_next,MLStackedStateT,ml_state_t * Caller,ml_iter_state_t * State)1059 static void ML_TYPED_FN(ml_iter_next, MLStackedStateT, ml_state_t *Caller, ml_iter_state_t *State) {
1060 State->Base.Caller = Caller;
1061 return ml_iter_next((ml_state_t *)State, State->Iter);
1062 }
1063
ML_TYPED_FN(ml_iterate,MLStackedT,ml_state_t * Caller,ml_stacked_t * Stacked)1064 static void ML_TYPED_FN(ml_iterate, MLStackedT, ml_state_t *Caller, ml_stacked_t *Stacked) {
1065 ml_iter_state_t *State = xnew(ml_iter_state_t, 3, ml_value_t *);
1066 State->Base.Type = MLStackedStateT;
1067 State->Base.Caller = Caller;
1068 State->Base.run = (void *)stacked_iterate;
1069 State->Base.Context = Caller->Context;
1070 State->Values[0] = Stacked->ReduceFn;
1071 State->Values[1] = Stacked->Initial;
1072 return ml_iterate((ml_state_t *)State, Stacked->Value);
1073 }
1074
1075 ML_METHOD("//", MLIteratableT, MLFunctionT) {
1076 //<Iteratable
1077 //<Fn
1078 //>iteratable
1079 // Returns an iteratable that produces :mini:`V/1`, :mini:`Fn(V/1, V/2)`, :mini:`Fn(Fn(V/1, V/2), V/3)`, ... .
1080 ml_stacked_t *Stacked = new(ml_stacked_t);
1081 Stacked->Type = MLStackedT;
1082 Stacked->Value = Args[0];
1083 Stacked->ReduceFn = Args[1];
1084 return (ml_value_t *)Stacked;
1085 }
1086
1087 ML_METHOD("//", MLIteratableT, MLAnyT, MLFunctionT) {
1088 //<Iteratable
1089 //<Initial
1090 //<Fn
1091 //>iteratable
1092 // Returns an iteratable that produces :mini:`Initial`, :mini:`Fn(Initial, V/1)`, :mini:`Fn(Fn(Initial, V/1), V/2)`, ... .
1093 ml_stacked_t *Stacked = new(ml_stacked_t);
1094 Stacked->Type = MLStackedT;
1095 Stacked->Value = Args[0];
1096 Stacked->Initial = Args[1];
1097 Stacked->ReduceFn = Args[2];
1098 return (ml_value_t *)Stacked;
1099 }
1100
1101 typedef struct ml_repeated_t {
1102 ml_type_t *Type;
1103 ml_value_t *Value, *Update;
1104 } ml_repeated_t;
1105
1106 ML_TYPE(MLRepeatedT, (MLIteratableT), "repeated");
1107 //!internal
1108
1109 typedef struct ml_repeated_state_t {
1110 ml_state_t Base;
1111 ml_value_t *Value, *Update;
1112 int Iteration;
1113 } ml_repeated_state_t;
1114
1115 ML_TYPE(MLRepeatedStateT, (), "repeated-state");
1116 //!internal
1117
repeated_update(ml_repeated_state_t * State,ml_value_t * Value)1118 static void repeated_update(ml_repeated_state_t *State, ml_value_t *Value) {
1119 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
1120 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, Value);
1121 State->Value = Value;
1122 ML_CONTINUE(State->Base.Caller, State);
1123 }
1124
ML_TYPED_FN(ml_iter_next,MLRepeatedStateT,ml_state_t * Caller,ml_repeated_state_t * State)1125 static void ML_TYPED_FN(ml_iter_next, MLRepeatedStateT, ml_state_t *Caller, ml_repeated_state_t *State) {
1126 State->Base.Caller = Caller;
1127 State->Base.Context = Caller->Context;
1128 ++State->Iteration;
1129 if (State->Update) {
1130 return ml_call(State, State->Update, 1, &State->Value);
1131 } else {
1132 ML_RETURN(State);
1133 }
1134 }
1135
ML_TYPED_FN(ml_iter_key,MLRepeatedStateT,ml_state_t * Caller,ml_repeated_state_t * State)1136 static void ML_TYPED_FN(ml_iter_key, MLRepeatedStateT, ml_state_t *Caller, ml_repeated_state_t *State) {
1137 ML_RETURN(ml_integer(State->Iteration));
1138 }
1139
ML_TYPED_FN(ml_iter_value,MLRepeatedStateT,ml_state_t * Caller,ml_repeated_state_t * State)1140 static void ML_TYPED_FN(ml_iter_value, MLRepeatedStateT, ml_state_t *Caller, ml_repeated_state_t *State) {
1141 ML_RETURN(State->Value);
1142 }
1143
ML_TYPED_FN(ml_iterate,MLRepeatedT,ml_state_t * Caller,ml_repeated_t * Repeated)1144 static void ML_TYPED_FN(ml_iterate, MLRepeatedT, ml_state_t *Caller, ml_repeated_t *Repeated) {
1145 ml_repeated_state_t *State = new(ml_repeated_state_t);
1146 State->Base.Type = MLRepeatedStateT;
1147 State->Base.run = (void *)repeated_update;
1148 State->Value = Repeated->Value;
1149 State->Update = Repeated->Update;
1150 State->Iteration = 1;
1151 ML_RETURN(State);
1152 }
1153
1154 ML_METHOD("@", MLAnyT) {
1155 //<Value
1156 //>iteratable
1157 // Returns an iteratable that repeatedly produces :mini:`Value`.
1158 ML_CHECK_ARG_COUNT(1);
1159 ml_repeated_t *Repeated = new(ml_repeated_t);
1160 Repeated->Type = MLRepeatedT;
1161 Repeated->Value = Args[0];
1162 return (ml_value_t *)Repeated;
1163 }
1164
1165 ML_METHOD("@", MLAnyT, MLFunctionT) {
1166 //<Value
1167 //<Update
1168 //>iteratable
1169 // Returns an iteratable that repeatedly produces :mini:`Value`.
1170 // :mini:`Value` is replaced with :mini:`Update(Value)` after each iteration.
1171 ML_CHECK_ARG_COUNT(1);
1172 ml_repeated_t *Repeated = new(ml_repeated_t);
1173 Repeated->Type = MLRepeatedT;
1174 Repeated->Value = Args[0];
1175 Repeated->Update = Args[1];
1176 return (ml_value_t *)Repeated;
1177 }
1178
1179 typedef struct ml_sequenced_t {
1180 ml_type_t *Type;
1181 ml_value_t *First, *Second;
1182 } ml_sequenced_t;
1183
1184 ML_TYPE(MLSequencedT, (MLIteratableT), "sequenced");
1185 //!internal
1186
1187 typedef struct ml_sequenced_state_t {
1188 ml_state_t Base;
1189 ml_value_t *Iter, *Next;
1190 } ml_sequenced_state_t;
1191
1192 ML_TYPE(MLSequencedStateT, (), "sequenced-state");
1193 //!internal
1194
1195 static void ml_sequenced_fnx_iterate(ml_sequenced_state_t *State, ml_value_t *Value);
1196
ML_TYPED_FN(ml_iter_next,MLSequencedStateT,ml_state_t * Caller,ml_sequenced_state_t * State)1197 static void ML_TYPED_FN(ml_iter_next, MLSequencedStateT, ml_state_t *Caller, ml_sequenced_state_t *State) {
1198 State->Base.Caller = Caller;
1199 State->Base.run = (void *)ml_sequenced_fnx_iterate;
1200 return ml_iter_next((ml_state_t *)State, State->Iter);
1201 }
1202
ML_TYPED_FN(ml_iter_key,MLSequencedStateT,ml_state_t * Caller,ml_sequenced_state_t * State)1203 static void ML_TYPED_FN(ml_iter_key, MLSequencedStateT, ml_state_t *Caller, ml_sequenced_state_t *State) {
1204 return ml_iter_key(Caller, State->Iter);
1205 }
1206
ML_TYPED_FN(ml_iter_value,MLSequencedStateT,ml_state_t * Caller,ml_sequenced_state_t * State)1207 static void ML_TYPED_FN(ml_iter_value, MLSequencedStateT, ml_state_t *Caller, ml_sequenced_state_t *State) {
1208 return ml_iter_value(Caller, State->Iter);
1209 }
1210
ml_sequenced_fnx_iterate(ml_sequenced_state_t * State,ml_value_t * Value)1211 static void ml_sequenced_fnx_iterate(ml_sequenced_state_t *State, ml_value_t *Value) {
1212 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
1213 if (Value == MLNil) {
1214 return ml_iterate(State->Base.Caller, State->Next);
1215 }
1216 State->Iter = Value;
1217 ML_CONTINUE(State->Base.Caller, State);
1218 }
1219
ML_TYPED_FN(ml_iterate,MLSequencedT,ml_state_t * Caller,ml_sequenced_t * Sequenced)1220 static void ML_TYPED_FN(ml_iterate, MLSequencedT, ml_state_t *Caller, ml_sequenced_t *Sequenced) {
1221 ml_sequenced_state_t *State = new(ml_sequenced_state_t);
1222 State->Base.Type = MLSequencedStateT;
1223 State->Base.Caller = Caller;
1224 State->Base.run = (void *)ml_sequenced_fnx_iterate;
1225 State->Next = Sequenced->Second;
1226 return ml_iterate((ml_state_t *)State, Sequenced->First);
1227 }
1228
1229 ML_METHOD(">>", MLIteratableT, MLIteratableT) {
1230 //<Iteratable/1
1231 //<Iteratable/2
1232 //>Iteratable
1233 // Returns an iteratable that produces the values from :mini:`Iteratable/1` followed by those from :mini:`Iteratable/2`.
1234 ml_sequenced_t *Sequenced = xnew(ml_sequenced_t, 3, ml_value_t *);
1235 Sequenced->Type = MLSequencedT;
1236 Sequenced->First = Args[0];
1237 Sequenced->Second = Args[1];
1238 return (ml_value_t *)Sequenced;
1239 }
1240
1241 ML_METHOD(">>", MLIteratableT) {
1242 //<Iteratable
1243 //>Iteratable
1244 // Returns an iteratable that repeatedly produces the values from :mini:`Iteratable` (for use with :mini:`limit`).
1245 ml_sequenced_t *Sequenced = xnew(ml_sequenced_t, 3, ml_value_t *);
1246 Sequenced->Type = MLSequencedT;
1247 Sequenced->First = Args[0];
1248 Sequenced->Second = (ml_value_t *)Sequenced;
1249 return (ml_value_t *)Sequenced;
1250 }
1251
1252 typedef struct ml_limited_t {
1253 ml_type_t *Type;
1254 ml_value_t *Value;
1255 int Remaining;
1256 } ml_limited_t;
1257
1258 ML_TYPE(MLLimitedT, (MLIteratableT), "limited");
1259 //!internal
1260
1261 ML_METHOD("count", MLLimitedT) {
1262 //!internal
1263 ml_limited_t *Limited = (ml_limited_t *)Args[0];
1264 return ml_integer(Limited->Remaining);
1265 }
1266
1267 typedef struct ml_limited_state_t {
1268 ml_state_t Base;
1269 ml_value_t *Iter;
1270 int Remaining;
1271 } ml_limited_state_t;
1272
1273 ML_TYPE(MLLimitedStateT, (), "limited-state");
1274 //!internal
1275
limited_iterate(ml_limited_state_t * State,ml_value_t * Value)1276 static void limited_iterate(ml_limited_state_t *State, ml_value_t *Value) {
1277 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
1278 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, Value);
1279 State->Iter = Value;
1280 --State->Remaining;
1281 ML_CONTINUE(State->Base.Caller, State);
1282 }
1283
ML_TYPED_FN(ml_iterate,MLLimitedT,ml_state_t * Caller,ml_limited_t * Limited)1284 static void ML_TYPED_FN(ml_iterate, MLLimitedT, ml_state_t *Caller, ml_limited_t *Limited) {
1285 if (Limited->Remaining) {
1286 ml_limited_state_t *State = new(ml_limited_state_t);
1287 State->Base.Type = MLLimitedStateT;
1288 State->Base.Caller = Caller;
1289 State->Base.run = (void *)limited_iterate;
1290 State->Base.Context = Caller->Context;
1291 State->Remaining = Limited->Remaining;
1292 return ml_iterate((ml_state_t *)State, Limited->Value);
1293 } else {
1294 ML_RETURN(MLNil);
1295 }
1296 }
1297
ML_TYPED_FN(ml_iter_key,MLLimitedStateT,ml_state_t * Caller,ml_limited_state_t * State)1298 static void ML_TYPED_FN(ml_iter_key, MLLimitedStateT, ml_state_t *Caller, ml_limited_state_t *State) {
1299 return ml_iter_key(Caller, State->Iter);
1300 }
1301
ML_TYPED_FN(ml_iter_value,MLLimitedStateT,ml_state_t * Caller,ml_limited_state_t * State)1302 static void ML_TYPED_FN(ml_iter_value, MLLimitedStateT, ml_state_t *Caller, ml_limited_state_t *State) {
1303 return ml_iter_value(Caller, State->Iter);
1304 }
1305
ML_TYPED_FN(ml_iter_next,MLLimitedStateT,ml_state_t * Caller,ml_limited_state_t * State)1306 static void ML_TYPED_FN(ml_iter_next, MLLimitedStateT, ml_state_t *Caller, ml_limited_state_t *State) {
1307 if (State->Remaining) {
1308 State->Base.Caller = Caller;
1309 State->Base.run = (void *)limited_iterate;
1310 return ml_iter_next((ml_state_t *)State, State->Iter);
1311 } else {
1312 ML_RETURN(MLNil);
1313 }
1314 }
1315
1316 ML_METHOD("limit", MLIteratableT, MLIntegerT) {
1317 //<Iteratable
1318 //<Limit
1319 //>iteratable
1320 // Returns an iteratable that produces at most :mini:`Limit` values from :mini:`Iteratable`.
1321 ml_limited_t *Limited = new(ml_limited_t);
1322 Limited->Type = MLLimitedT;
1323 Limited->Value = Args[0];
1324 Limited->Remaining = ml_integer_value_fast(Args[1]);
1325 return (ml_value_t *)Limited;
1326 }
1327
1328 typedef struct ml_skipped_t {
1329 ml_type_t *Type;
1330 ml_value_t *Value;
1331 long Remaining;
1332 } ml_skipped_t;
1333
1334 ML_TYPE(MLSkippedT, (MLIteratableT), "skipped");
1335 //!internal
1336
1337 typedef struct ml_skipped_state_t {
1338 ml_state_t Base;
1339 long Remaining;
1340 } ml_skipped_state_t;
1341
skipped_iterate(ml_skipped_state_t * State,ml_value_t * Value)1342 static void skipped_iterate(ml_skipped_state_t *State, ml_value_t *Value) {
1343 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
1344 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, Value);
1345 if (State->Remaining) {
1346 --State->Remaining;
1347 return ml_iter_next((ml_state_t *)State, Value);
1348 } else {
1349 ML_CONTINUE(State->Base.Caller, Value);
1350 }
1351 }
1352
ML_TYPED_FN(ml_iterate,MLSkippedT,ml_state_t * Caller,ml_skipped_t * Skipped)1353 static void ML_TYPED_FN(ml_iterate, MLSkippedT, ml_state_t *Caller, ml_skipped_t *Skipped) {
1354 if (Skipped->Remaining) {
1355 ml_skipped_state_t *State = new(ml_skipped_state_t);
1356 State->Base.Caller = Caller;
1357 State->Base.run = (void *)skipped_iterate;
1358 State->Base.Context = Caller->Context;
1359 State->Remaining = Skipped->Remaining;
1360 return ml_iterate((ml_state_t *)State, Skipped->Value);
1361 } else {
1362 return ml_iterate(Caller, Skipped->Value);
1363 }
1364 }
1365
1366 ML_METHOD("skip", MLIteratableT, MLIntegerT) {
1367 //<Iteratable
1368 //<Skip
1369 //>iteratable
1370 // Returns an iteratable that skips the first :mini:`Skip` values from :mini:`Iteratable` and then produces the rest.
1371 ml_skipped_t *Skipped = new(ml_skipped_t);
1372 Skipped->Type = MLSkippedT;
1373 Skipped->Value = Args[0];
1374 Skipped->Remaining = ml_integer_value_fast(Args[1]);
1375 return (ml_value_t *)Skipped;
1376 }
1377
1378 typedef struct {
1379 ml_state_t Base;
1380 ml_value_t *Value;
1381 ml_state_t *Limited;
1382 size_t Waiting, Limit, Burst;
1383 } ml_tasks_t;
1384
ml_tasks_call(ml_state_t * Caller,ml_tasks_t * Tasks,int Count,ml_value_t ** Args)1385 static void ml_tasks_call(ml_state_t *Caller, ml_tasks_t *Tasks, int Count, ml_value_t **Args) {
1386 if (!Tasks->Waiting) ML_ERROR("TasksError", "Tasks have already completed");
1387 if (Tasks->Value != MLNil) ML_RETURN(Tasks->Value);
1388 ML_CHECKX_ARG_TYPE(Count - 1, MLFunctionT);
1389 ml_value_t *Function = Args[Count - 1];
1390 ++Tasks->Waiting;
1391 ml_call(Tasks, Function, Count - 1, Args);
1392 if (Tasks->Waiting > Tasks->Limit && !Tasks->Limited) {
1393 Tasks->Limited = Caller;
1394 } else {
1395 ML_RETURN(Tasks->Value);
1396 }
1397 }
1398
ml_tasks_continue(ml_tasks_t * Tasks,ml_value_t * Value)1399 static void ml_tasks_continue(ml_tasks_t *Tasks, ml_value_t *Value) {
1400 if (ml_is_error(Value)) Tasks->Value = Value;
1401 --Tasks->Waiting;
1402 if (Tasks->Limited && Tasks->Waiting <= Tasks->Burst) {
1403 ml_state_t *Caller = Tasks->Limited;
1404 Tasks->Limited = NULL;
1405 ML_RETURN(Tasks->Value);
1406 }
1407 if (Tasks->Waiting == 0) ML_CONTINUE(Tasks->Base.Caller, Tasks->Value);
1408 }
1409
1410 extern ml_type_t MLTasksT[];
1411
ML_FUNCTIONX(Tasks)1412 ML_FUNCTIONX(Tasks) {
1413 //!tasks
1414 //<Max?:integer
1415 //<Min?:integer
1416 //>tasks
1417 // Creates a new :mini:`tasks` set.
1418 // If specified, at most :mini:`Max` functions will be called in parallel (the default is unlimited).
1419 // If :mini:`Min` is also specified then the number of running tasks must drop below :mini:`Min` before more tasks are launched.
1420 ml_tasks_t *Tasks = new(ml_tasks_t);
1421 Tasks->Base.Type = MLTasksT;
1422 Tasks->Base.run = (void *)ml_tasks_continue;
1423 Tasks->Base.Caller = Caller;
1424 Tasks->Base.Context = Caller->Context;
1425 Tasks->Value = MLNil;
1426 Tasks->Waiting = 1;
1427 if (Count >= 2) {
1428 ML_CHECKX_ARG_TYPE(0, MLIntegerT);
1429 ML_CHECKX_ARG_TYPE(1, MLIntegerT);
1430 Tasks->Limit = ml_integer_value_fast(Args[1]);
1431 Tasks->Burst = ml_integer_value_fast(Args[0]) + 1;
1432 } else if (Count >= 1) {
1433 ML_CHECKX_ARG_TYPE(0, MLIntegerT);
1434 Tasks->Limit = ml_integer_value_fast(Args[0]);
1435 Tasks->Burst = SIZE_MAX;
1436 } else {
1437 Tasks->Limit = SIZE_MAX;
1438 Tasks->Burst = SIZE_MAX;
1439 }
1440 ML_RETURN(Tasks);
1441 }
1442
1443 ML_TYPE(MLTasksT, (MLFunctionT), "tasks",
1444 //!tasks
1445 // A dynamic set of tasks (function calls). Multiple tasks can run in parallel (depending on the availability of a scheduler and/or asynchronous function calls).
1446 .call = (void *)ml_tasks_call,
1447 .Constructor = (ml_value_t *)Tasks
1448 );
1449
1450 ML_METHODVX("add", MLTasksT, MLAnyT) {
1451 //!tasks
1452 //<Tasks
1453 //<Args...
1454 //<Function
1455 // Adds the function call :mini:`Function(Args...)` to a set of tasks.
1456 // Adding a task to a completed tasks set returns an error.
1457 ml_tasks_t *Tasks = (ml_tasks_t *)Args[0];
1458 if (!Tasks->Waiting) ML_ERROR("TasksError", "Tasks have already completed");
1459 if (Tasks->Value != MLNil) ML_RETURN(Tasks->Value);
1460 ML_CHECKX_ARG_TYPE(Count - 1, MLFunctionT);
1461 ml_value_t *Function = Args[Count - 1];
1462 ++Tasks->Waiting;
1463 ml_call(Tasks, Function, Count - 2, Args + 1);
1464 if (Tasks->Waiting > Tasks->Limit && !Tasks->Limited) {
1465 Tasks->Limited = Caller;
1466 } else {
1467 ML_RETURN(Tasks->Value);
1468 }
1469 }
1470
1471 ML_METHODX("wait", MLTasksT) {
1472 //!tasks
1473 //<Tasks
1474 //>nil | error
1475 // Waits until all of the tasks in a tasks set have returned, or one of the tasks has returned an error (which is then returned from this call).
1476 ml_tasks_t *Tasks = (ml_tasks_t *)Args[0];
1477 Tasks->Base.Caller = Caller;
1478 Tasks->Base.Context = Caller->Context;
1479 ml_tasks_continue(Tasks, MLNil);
1480 }
1481
1482 typedef struct ml_parallel_iter_t ml_parallel_iter_t;
1483
1484 typedef struct {
1485 ml_state_t Base;
1486 ml_state_t NextState[1];
1487 ml_state_t KeyState[1];
1488 ml_state_t ValueState[1];
1489 ml_value_t *Iter, *Function, *Error;
1490 ml_value_t *Args[2];
1491 size_t Waiting, Limit, Burst;
1492 int Calling;
1493 } ml_parallel_t;
1494
parallel_iter_next(ml_state_t * State,ml_value_t * Iter)1495 static void parallel_iter_next(ml_state_t *State, ml_value_t *Iter) {
1496 ml_parallel_t *Parallel = (ml_parallel_t *)((char *)State - offsetof(ml_parallel_t, NextState));
1497 if (Parallel->Error) return;
1498 if (Iter == MLNil) {
1499 Parallel->Iter = NULL;
1500 --Parallel->Waiting;
1501 ML_CONTINUE(Parallel, MLNil);
1502 }
1503 if (ml_is_error(Iter)) {
1504 Parallel->Error = Iter;
1505 ML_CONTINUE(Parallel->Base.Caller, Iter);
1506 }
1507 return ml_iter_key(Parallel->KeyState, Parallel->Iter = Iter);
1508 }
1509
parallel_iter_key(ml_state_t * State,ml_value_t * Value)1510 static void parallel_iter_key(ml_state_t *State, ml_value_t *Value) {
1511 ml_parallel_t *Parallel = (ml_parallel_t *)((char *)State - offsetof(ml_parallel_t, KeyState));
1512 if (Parallel->Error) return;
1513 Parallel->Args[0] = Value;
1514 return ml_iter_value(Parallel->ValueState, Parallel->Iter);
1515 }
1516
parallel_iter_value(ml_state_t * State,ml_value_t * Value)1517 static void parallel_iter_value(ml_state_t *State, ml_value_t *Value) {
1518 ml_parallel_t *Parallel = (ml_parallel_t *)((char *)State - offsetof(ml_parallel_t, ValueState));
1519 if (Parallel->Error) return;
1520 Parallel->Args[1] = Value;
1521 Parallel->Calling = 1;
1522 ml_call(Parallel, Parallel->Function, 2, Parallel->Args);
1523 Parallel->Calling = 0;
1524 if (Parallel->Iter) {
1525 if (Parallel->Waiting > Parallel->Limit) return;
1526 ++Parallel->Waiting;
1527 return ml_iter_next(Parallel->NextState, Parallel->Iter);
1528 }
1529 }
1530
parallel_continue(ml_parallel_t * Parallel,ml_value_t * Value)1531 static void parallel_continue(ml_parallel_t *Parallel, ml_value_t *Value) {
1532 if (Parallel->Error) return;
1533 if (ml_is_error(Value)) {
1534 Parallel->Error = Value;
1535 ML_CONTINUE(Parallel->Base.Caller, Value);
1536 }
1537 --Parallel->Waiting;
1538 if (Parallel->Iter && !Parallel->Calling) {
1539 if (Parallel->Waiting > Parallel->Burst) return;
1540 ++Parallel->Waiting;
1541 return ml_iter_next(Parallel->NextState, Parallel->Iter);
1542 }
1543 if (Parallel->Waiting == 0) ML_CONTINUE(Parallel->Base.Caller, MLNil);
1544 }
1545
ML_FUNCTIONX(Parallel)1546 ML_FUNCTIONX(Parallel) {
1547 //!tasks
1548 //<Iteratable
1549 //<Max?:integer
1550 //<Min?:integer
1551 //<Function:function
1552 //>nil | error
1553 // Iterates through :mini:`Iteratable` and calls :mini:`Function(Key, Value)` for each :mini:`Key, Value` pair produced **without** waiting for the call to return.
1554 // The call to :mini:`parallel` returns when all calls to :mini:`Function` return, or an error occurs.
1555 // If :mini:`Max` is given, at most :mini:`Max` calls to :mini:`Function` will run at a time by pausing iteration through :mini:`Iteratable`.
1556 // If :mini:`Min` is also given then iteration will be resumed only when the number of calls to :mini:`Function` drops to :mini:`Min`.
1557 ML_CHECKX_ARG_COUNT(2);
1558
1559 ml_parallel_t *Parallel = new(ml_parallel_t);
1560 Parallel->Base.Caller = Caller;
1561 Parallel->Base.run = (void *)parallel_continue;
1562 Parallel->Base.Context = Caller->Context;
1563 Parallel->Waiting = 1;
1564 Parallel->NextState->run = parallel_iter_next;
1565 Parallel->NextState->Context = Caller->Context;
1566 Parallel->KeyState->run = parallel_iter_key;
1567 Parallel->KeyState->Context = Caller->Context;
1568 Parallel->ValueState->run = parallel_iter_value;
1569 Parallel->ValueState->Context = Caller->Context;
1570
1571 if (Count > 3) {
1572 ML_CHECKX_ARG_TYPE(1, MLIntegerT);
1573 ML_CHECKX_ARG_TYPE(2, MLIntegerT);
1574 ML_CHECKX_ARG_TYPE(3, MLFunctionT);
1575 Parallel->Limit = ml_integer_value_fast(Args[2]);
1576 Parallel->Burst = ml_integer_value_fast(Args[1]) + 1;
1577 Parallel->Function = Args[3];
1578 } else if (Count > 2) {
1579 ML_CHECKX_ARG_TYPE(1, MLIntegerT);
1580 ML_CHECKX_ARG_TYPE(2, MLFunctionT);
1581 Parallel->Limit = ml_integer_value_fast(Args[1]);
1582 Parallel->Burst = SIZE_MAX;
1583 Parallel->Function = Args[2];
1584 } else {
1585 ML_CHECKX_ARG_TYPE(1, MLFunctionT);
1586 Parallel->Limit = SIZE_MAX;
1587 Parallel->Burst = SIZE_MAX;
1588 Parallel->Function = Args[1];
1589 }
1590
1591 ++Parallel->Waiting;
1592 return ml_iterate(Parallel->NextState, Args[0]);
1593 }
1594
1595 typedef struct {
1596 ml_type_t *Type;
1597 ml_value_t *Iter;
1598 int Total;
1599 } ml_buffered_t;
1600
1601 ML_TYPE(MLBufferedT, (MLIteratableT), "buffered");
1602 //!internal
1603
1604 typedef struct {
1605 ml_value_t *Key, *Value;
1606 } ml_buffered_key_value_t;
1607
1608 typedef struct {
1609 ml_state_t Base;
1610 ml_value_t *Iter, *Final;
1611 int Read, Write, Ready, Total;
1612 ml_buffered_key_value_t KeyValues[];
1613 } ml_buffered_state_t;
1614
1615 ML_TYPE(MLBufferedStateT, (), "buffered-state");
1616 //!internal
1617
1618 static void ml_buffered_iterate(ml_buffered_state_t *State, ml_value_t *Value);
1619
ml_buffered_value(ml_buffered_state_t * State,ml_value_t * Value)1620 static void ml_buffered_value(ml_buffered_state_t *State, ml_value_t *Value) {
1621 State->Base.run = (void *)ml_buffered_iterate;
1622 State->KeyValues[State->Write].Value = Value;
1623 State->Write = (State->Write + 1) % State->Total;
1624 ++State->Ready;
1625 if (State->Ready < State->Total) {
1626 ml_iter_next((ml_state_t *)State, State->Iter);
1627 }
1628 ml_state_t *Caller = State->Base.Caller;
1629 if (Caller) {
1630 State->Base.Caller = NULL;
1631 ML_RETURN(State);
1632 }
1633 }
1634
ml_buffered_key(ml_buffered_state_t * State,ml_value_t * Value)1635 static void ml_buffered_key(ml_buffered_state_t *State, ml_value_t *Value) {
1636 State->KeyValues[State->Write].Key = Value;
1637 State->Base.run = (void *)ml_buffered_value;
1638 return ml_iter_value((ml_state_t *)State, State->Iter);
1639 }
1640
ml_buffered_iterate(ml_buffered_state_t * State,ml_value_t * Value)1641 static void ml_buffered_iterate(ml_buffered_state_t *State, ml_value_t *Value) {
1642 if (ml_is_error(Value)) {
1643 State->Final = Value;
1644 } else if (Value == MLNil) {
1645 State->Final = MLNil;
1646 } else {
1647 State->Base.run = (void *)ml_buffered_key;
1648 return ml_iter_key((ml_state_t *)State, State->Iter = Value);
1649 }
1650 }
1651
ML_TYPED_FN(ml_iter_next,MLBufferedStateT,ml_state_t * Caller,ml_buffered_state_t * State)1652 static void ML_TYPED_FN(ml_iter_next, MLBufferedStateT, ml_state_t *Caller, ml_buffered_state_t *State) {
1653 State->Read = (State->Read + 1) % State->Total;
1654 --State->Ready;
1655 if (!State->Final) {
1656 ml_iter_next((ml_state_t *)State, State->Iter);
1657 }
1658 if (State->Ready) {
1659 ML_RETURN(State);
1660 } else if (State->Final) {
1661 ML_RETURN(State->Final);
1662 } else {
1663 State->Base.Caller = Caller;
1664 }
1665 }
1666
ML_TYPED_FN(ml_iter_key,MLBufferedStateT,ml_state_t * Caller,ml_buffered_state_t * State)1667 static void ML_TYPED_FN(ml_iter_key, MLBufferedStateT, ml_state_t *Caller, ml_buffered_state_t *State) {
1668 ML_RETURN(State->KeyValues[State->Read].Key);
1669 }
1670
ML_TYPED_FN(ml_iter_value,MLBufferedStateT,ml_state_t * Caller,ml_buffered_state_t * State)1671 static void ML_TYPED_FN(ml_iter_value, MLBufferedStateT, ml_state_t *Caller, ml_buffered_state_t *State) {
1672 ML_RETURN(State->KeyValues[State->Read].Value);
1673 }
1674
ML_TYPED_FN(ml_iterate,MLBufferedT,ml_state_t * Caller,ml_buffered_t * Buffered)1675 static void ML_TYPED_FN(ml_iterate, MLBufferedT, ml_state_t *Caller, ml_buffered_t *Buffered) {
1676 ml_buffered_state_t *State = xnew(ml_buffered_state_t, Buffered->Total, ml_buffered_key_value_t);
1677 State->Base.Type = MLBufferedStateT;
1678 State->Base.run = (void *)ml_buffered_iterate;
1679 State->Base.Context = Caller->Context;
1680 State->Total = Buffered->Total;
1681 State->Read = State->Write = State->Ready = 0;
1682 ml_iterate((ml_state_t *)State, Buffered->Iter);
1683 if (State->Ready) {
1684 ML_RETURN(State);
1685 } else if (State->Final) {
1686 ML_RETURN(State->Final);
1687 } else {
1688 State->Base.Caller = Caller;
1689 }
1690 }
1691
ML_FUNCTION(Buffered)1692 ML_FUNCTION(Buffered) {
1693 //<Size:integer
1694 //<Iteratable
1695 //>Iteratable
1696 // Returns an iteratable that buffers the keys and values from :mini:`Iteratable` in advance, buffering at most :mini:`Size` pairs.
1697 ML_CHECK_ARG_COUNT(2);
1698 ML_CHECK_ARG_TYPE(0, MLIntegerT);
1699 ml_buffered_t *Buffered = new(ml_buffered_t);
1700 Buffered->Type = MLBufferedT;
1701 Buffered->Total = ml_integer_value(Args[0]);
1702 Buffered->Iter = ml_chained(Count - 1, Args + 1);
1703 return (ml_value_t *)Buffered;
1704 }
1705
1706 typedef struct ml_unique_t {
1707 ml_type_t *Type;
1708 ml_value_t *Iter;
1709 } ml_unique_t;
1710
1711 ML_TYPE(MLUniqueT, (MLIteratableT), "unique");
1712 //!internal
1713
1714 typedef struct ml_unique_state_t {
1715 ml_state_t Base;
1716 ml_value_t *Iter;
1717 ml_value_t *History;
1718 ml_value_t *Value;
1719 int Iteration;
1720 } ml_unique_state_t;
1721
1722 ML_TYPE(MLUniqueStateT, (), "unique-state");
1723 //!internal
1724
1725 static void ml_unique_fnx_iterate(ml_unique_state_t *State, ml_value_t *Value);
1726
ml_unique_fnx_value(ml_unique_state_t * State,ml_value_t * Value)1727 static void ml_unique_fnx_value(ml_unique_state_t *State, ml_value_t *Value) {
1728 Value = ml_deref(Value);
1729 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
1730 if (ml_map_insert(State->History, Value, MLSome) == MLNil) {
1731 State->Value = Value;
1732 ++State->Iteration;
1733 ML_CONTINUE(State->Base.Caller, State);
1734 }
1735 State->Base.run = (void *)ml_unique_fnx_iterate;
1736 return ml_iter_next((ml_state_t *)State, State->Iter);
1737 }
1738
ml_unique_fnx_iterate(ml_unique_state_t * State,ml_value_t * Value)1739 static void ml_unique_fnx_iterate(ml_unique_state_t *State, ml_value_t *Value) {
1740 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
1741 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, Value);
1742 State->Base.run = (void *)ml_unique_fnx_value;
1743 return ml_iter_value((ml_state_t *)State, State->Iter = Value);
1744 }
1745
ML_TYPED_FN(ml_iterate,MLUniqueT,ml_state_t * Caller,ml_unique_t * Unique)1746 static void ML_TYPED_FN(ml_iterate, MLUniqueT, ml_state_t *Caller, ml_unique_t *Unique) {
1747 ml_unique_state_t *State = new(ml_unique_state_t);
1748 State->Base.Type = MLUniqueStateT;
1749 State->Base.Caller = Caller;
1750 State->Base.run = (void *)ml_unique_fnx_iterate;
1751 State->Base.Context = Caller->Context;
1752 State->History = ml_map();
1753 State->Iteration = 0;
1754 return ml_iterate((ml_state_t *)State, Unique->Iter);
1755 }
1756
ML_TYPED_FN(ml_iter_key,MLUniqueStateT,ml_state_t * Caller,ml_unique_state_t * State)1757 static void ML_TYPED_FN(ml_iter_key, MLUniqueStateT, ml_state_t *Caller, ml_unique_state_t *State) {
1758 ML_RETURN(ml_integer(State->Iteration));
1759 }
1760
ML_TYPED_FN(ml_iter_value,MLUniqueStateT,ml_state_t * Caller,ml_unique_state_t * State)1761 static void ML_TYPED_FN(ml_iter_value, MLUniqueStateT, ml_state_t *Caller, ml_unique_state_t *State) {
1762 ML_RETURN(State->Value);
1763 }
1764
ML_TYPED_FN(ml_iter_next,MLUniqueStateT,ml_state_t * Caller,ml_unique_state_t * State)1765 static void ML_TYPED_FN(ml_iter_next, MLUniqueStateT, ml_state_t *Caller, ml_unique_state_t *State) {
1766 State->Base.Caller = Caller;
1767 State->Base.run = (void *)ml_unique_fnx_iterate;
1768 return ml_iter_next((ml_state_t *)State, State->Iter);
1769 }
1770
ML_FUNCTION(Unique)1771 ML_FUNCTION(Unique) {
1772 //<Iteratable
1773 //>iteratable
1774 // Returns an iteratable that returns the unique values produced by :mini:`Iteratable` (based on inserting into a :mini:`map`).
1775 ML_CHECK_ARG_COUNT(1);
1776 ml_unique_t *Unique = new(ml_unique_t);
1777 Unique->Type = MLUniqueT;
1778 Unique->Iter = ml_chained(Count, Args);
1779 return (ml_value_t *)Unique;
1780 }
1781
1782 typedef struct ml_zipped_t {
1783 ml_type_t *Type;
1784 ml_value_t *Function;
1785 int Count;
1786 ml_value_t *Iters[];
1787 } ml_zipped_t;
1788
1789 ML_TYPE(MLZippedT, (MLIteratableT), "zipped");
1790 //!internal
1791
1792 typedef struct ml_zipped_state_t {
1793 ml_state_t Base;
1794 ml_value_t *Function;
1795 ml_value_t **Iters;
1796 int Count, Index, Iteration;
1797 ml_value_t *Args[];
1798 } ml_zipped_state_t;
1799
1800 ML_TYPE(MLZippedStateT, (), "zipped-state");
1801 //!internal
1802
zipped_iterate(ml_zipped_state_t * State,ml_value_t * Value)1803 static void zipped_iterate(ml_zipped_state_t *State, ml_value_t *Value) {
1804 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
1805 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, Value);
1806 State->Iters[State->Index] = Value;
1807 if (++State->Index == State->Count) ML_CONTINUE(State->Base.Caller, State);
1808 return ml_iterate((ml_state_t *)State, State->Iters[State->Index]);
1809 }
1810
ML_TYPED_FN(ml_iterate,MLZippedT,ml_state_t * Caller,ml_zipped_t * Zipped)1811 static void ML_TYPED_FN(ml_iterate, MLZippedT, ml_state_t *Caller, ml_zipped_t *Zipped) {
1812 ml_zipped_state_t *State = xnew(ml_zipped_state_t, 2 * Zipped->Count, ml_value_t *);
1813 State->Base.Type = MLZippedStateT;
1814 State->Base.Caller = Caller;
1815 State->Base.run = (void *)zipped_iterate;
1816 State->Base.Context = Caller->Context;
1817 State->Function = Zipped->Function;
1818 State->Iters = State->Args + Zipped->Count;
1819 for (int I = 0; I < Zipped->Count; ++I) State->Iters[I] = Zipped->Iters[I];
1820 State->Count = Zipped->Count;
1821 State->Iteration = 1;
1822 return ml_iterate((ml_state_t *)State, State->Iters[0]);
1823 }
1824
ML_TYPED_FN(ml_iter_key,MLZippedStateT,ml_state_t * Caller,ml_zipped_state_t * State)1825 static void ML_TYPED_FN(ml_iter_key, MLZippedStateT, ml_state_t *Caller, ml_zipped_state_t *State) {
1826 ML_RETURN(ml_integer(State->Iteration));
1827 }
1828
ml_zipped_fnx_value(ml_zipped_state_t * State,ml_value_t * Value)1829 static void ml_zipped_fnx_value(ml_zipped_state_t *State, ml_value_t *Value) {
1830 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
1831 State->Args[State->Index] = Value;
1832 if (++State->Index == State->Count) {
1833 return ml_call(State->Base.Caller, State->Function, State->Count, State->Args);
1834 }
1835 return ml_iter_value((ml_state_t *)State, State->Iters[State->Index]);
1836 }
1837
ML_TYPED_FN(ml_iter_value,MLZippedStateT,ml_state_t * Caller,ml_zipped_state_t * State)1838 static void ML_TYPED_FN(ml_iter_value, MLZippedStateT, ml_state_t *Caller, ml_zipped_state_t *State) {
1839 State->Base.Caller = Caller;
1840 State->Base.run = (void *)ml_zipped_fnx_value;
1841 State->Index = 0;
1842 return ml_iter_value((ml_state_t *)State, State->Iters[0]);
1843 }
1844
zipped_iter_next(ml_zipped_state_t * State,ml_value_t * Value)1845 static void zipped_iter_next(ml_zipped_state_t *State, ml_value_t *Value) {
1846 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
1847 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, Value);
1848 State->Iters[State->Index] = Value;
1849 if (++State->Index == State->Count) ML_CONTINUE(State->Base.Caller, State);
1850 return ml_iter_next((ml_state_t *)State, State->Iters[State->Index]);
1851 }
1852
ML_TYPED_FN(ml_iter_next,MLZippedStateT,ml_state_t * Caller,ml_zipped_state_t * State)1853 static void ML_TYPED_FN(ml_iter_next, MLZippedStateT, ml_state_t *Caller, ml_zipped_state_t *State) {
1854 State->Base.Caller = Caller;
1855 State->Base.run = (void *)zipped_iter_next;
1856 ++State->Iteration;
1857 State->Index = 0;
1858 return ml_iter_next((ml_state_t *)State, State->Iters[0]);
1859 }
1860
ML_FUNCTION(Zip)1861 ML_FUNCTION(Zip) {
1862 //@zip
1863 //<Iteratable/1:iteratable
1864 //<...:iteratable
1865 //<Iteratable/n:iteratable
1866 //<Function
1867 //>iteratable
1868 // Returns a new iteratable that draws values :mini:`V/i` from each of :mini:`Iteratable/i` and then produces :mini:`Functon(V/1, V/2, ..., V/n)`.
1869 // The iteratable stops produces values when any of the :mini:`Iteratable/i` stops.
1870 ML_CHECK_ARG_COUNT(1);
1871 ML_CHECK_ARG_TYPE(Count - 1, MLFunctionT);
1872 ml_zipped_t *Zipped = xnew(ml_zipped_t, Count - 1, ml_value_t *);
1873 Zipped->Type = MLZippedT;
1874 Zipped->Count = Count - 1;
1875 Zipped->Function = Args[Count - 1];
1876 for (int I = 0; I < Count - 1; ++I) Zipped->Iters[I] = Args[I];
1877 return (ml_value_t *)Zipped;
1878 }
1879
1880 typedef struct ml_paired_t {
1881 ml_type_t *Type;
1882 ml_value_t *Keys, *Values;
1883 } ml_paired_t;
1884
1885 ML_TYPE(MLPairedT, (MLIteratableT), "paired");
1886 //!internal
1887
1888 typedef struct ml_paired_state_t {
1889 ml_state_t Base;
1890 ml_value_t *Keys, *Values;
1891 } ml_paired_state_t;
1892
1893 ML_TYPE(MLPairedStateT, (), "paired-state");
1894 //!internal
1895
paired_value_iterate(ml_paired_state_t * State,ml_value_t * Value)1896 static void paired_value_iterate(ml_paired_state_t *State, ml_value_t *Value) {
1897 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
1898 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, Value);
1899 State->Values = Value;
1900 ML_CONTINUE(State->Base.Caller, State);
1901 }
1902
paired_key_iterate(ml_paired_state_t * State,ml_value_t * Value)1903 static void paired_key_iterate(ml_paired_state_t *State, ml_value_t *Value) {
1904 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
1905 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, Value);
1906 State->Keys = Value;
1907 State->Base.run = (void *)paired_value_iterate;
1908 return ml_iterate((ml_state_t *)State, State->Values);
1909 }
1910
ML_TYPED_FN(ml_iterate,MLPairedT,ml_state_t * Caller,ml_paired_t * Paired)1911 static void ML_TYPED_FN(ml_iterate, MLPairedT, ml_state_t *Caller, ml_paired_t *Paired) {
1912 ml_paired_state_t *State = new(ml_paired_state_t);
1913 State->Base.Type = MLPairedStateT;
1914 State->Base.Caller = Caller;
1915 State->Base.run = (void *)paired_key_iterate;
1916 State->Base.Context = Caller->Context;
1917 State->Values = Paired->Values;
1918 return ml_iterate((ml_state_t *)State, Paired->Keys);
1919 }
1920
ML_TYPED_FN(ml_iter_key,MLPairedStateT,ml_state_t * Caller,ml_paired_state_t * State)1921 static void ML_TYPED_FN(ml_iter_key, MLPairedStateT, ml_state_t *Caller, ml_paired_state_t *State) {
1922 return ml_iter_value(Caller, State->Keys);
1923 }
1924
ML_TYPED_FN(ml_iter_value,MLPairedStateT,ml_state_t * Caller,ml_paired_state_t * State)1925 static void ML_TYPED_FN(ml_iter_value, MLPairedStateT, ml_state_t *Caller, ml_paired_state_t *State) {
1926 return ml_iter_value(Caller, State->Values);
1927 }
1928
paired_value_iter_next(ml_paired_state_t * State,ml_value_t * Value)1929 static void paired_value_iter_next(ml_paired_state_t *State, ml_value_t *Value) {
1930 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
1931 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, Value);
1932 State->Values = Value;
1933 ML_CONTINUE(State->Base.Caller, State);
1934 }
1935
paired_key_iter_next(ml_paired_state_t * State,ml_value_t * Value)1936 static void paired_key_iter_next(ml_paired_state_t *State, ml_value_t *Value) {
1937 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
1938 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, Value);
1939 State->Keys = Value;
1940 State->Base.run = (void *)paired_value_iter_next;
1941 return ml_iter_next((ml_state_t *)State, State->Values);
1942 }
1943
ML_TYPED_FN(ml_iter_next,MLPairedStateT,ml_state_t * Caller,ml_paired_state_t * State)1944 static void ML_TYPED_FN(ml_iter_next, MLPairedStateT, ml_state_t *Caller, ml_paired_state_t *State) {
1945 State->Base.Caller = Caller;
1946 State->Base.run = (void *)paired_key_iter_next;
1947 return ml_iter_next((ml_state_t *)State, State->Keys);
1948 }
1949
ML_FUNCTION(Pair)1950 ML_FUNCTION(Pair) {
1951 //@pair
1952 //<Iteratable/1:iteratable
1953 //<Iteratable/2:iteratable
1954 //>iteratable
1955 ML_CHECK_ARG_COUNT(2);
1956 ml_paired_t *Paired = new(ml_paired_t);
1957 Paired->Type = MLPairedT;
1958 Paired->Keys = Args[0];
1959 Paired->Values = Args[1];
1960 return (ml_value_t *)Paired;
1961 }
1962
1963 typedef struct ml_weaved_t {
1964 ml_type_t *Type;
1965 int Count;
1966 ml_value_t *Iters[];
1967 } ml_weaved_t;
1968
1969 ML_TYPE(MLWeavedT, (MLIteratableT), "weaved");
1970 //!internal
1971
1972 typedef struct ml_weaved_state_t {
1973 ml_state_t Base;
1974 int Count, Index, Iteration;
1975 ml_value_t *Iters[];
1976 } ml_weaved_state_t;
1977
1978 ML_TYPE(MLWeavedStateT, (), "weaved-state");
1979 //!internal
1980
weaved_iterate(ml_weaved_state_t * State,ml_value_t * Value)1981 static void weaved_iterate(ml_weaved_state_t *State, ml_value_t *Value) {
1982 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
1983 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, Value);
1984 State->Iters[State->Index] = Value;
1985 ML_CONTINUE(State->Base.Caller, State);
1986 }
1987
ML_TYPED_FN(ml_iterate,MLWeavedT,ml_state_t * Caller,ml_weaved_t * Weaved)1988 static void ML_TYPED_FN(ml_iterate, MLWeavedT, ml_state_t *Caller, ml_weaved_t *Weaved) {
1989 ml_weaved_state_t *State = xnew(ml_weaved_state_t, Weaved->Count, ml_value_t *);
1990 State->Base.Type = MLWeavedStateT;
1991 State->Base.Caller = Caller;
1992 State->Base.run = (void *)weaved_iterate;
1993 State->Base.Context = Caller->Context;
1994 for (int I = 0; I < Weaved->Count; ++I) State->Iters[I] = Weaved->Iters[I];
1995 State->Count = Weaved->Count;
1996 State->Iteration = 1;
1997 return ml_iterate((ml_state_t *)State, State->Iters[0]);
1998 }
1999
ML_TYPED_FN(ml_iter_key,MLWeavedStateT,ml_state_t * Caller,ml_weaved_state_t * State)2000 static void ML_TYPED_FN(ml_iter_key, MLWeavedStateT, ml_state_t *Caller, ml_weaved_state_t *State) {
2001 ML_RETURN(ml_integer(State->Iteration));
2002 }
2003
ML_TYPED_FN(ml_iter_value,MLWeavedStateT,ml_state_t * Caller,ml_weaved_state_t * State)2004 static void ML_TYPED_FN(ml_iter_value, MLWeavedStateT, ml_state_t *Caller, ml_weaved_state_t *State) {
2005 return ml_iter_value(Caller, State->Iters[State->Index]);
2006 }
2007
ML_TYPED_FN(ml_iter_next,MLWeavedStateT,ml_state_t * Caller,ml_weaved_state_t * State)2008 static void ML_TYPED_FN(ml_iter_next, MLWeavedStateT, ml_state_t *Caller, ml_weaved_state_t *State) {
2009 State->Base.Caller = Caller;
2010 if (++State->Index == State->Count) State->Index = 0;
2011 if (++State->Iteration > State->Count) {
2012 return ml_iter_next((ml_state_t *)State, State->Iters[State->Index]);
2013 } else {
2014 return ml_iterate((ml_state_t *)State, State->Iters[State->Index]);
2015 }
2016 }
2017
ML_FUNCTION(Weave)2018 ML_FUNCTION(Weave) {
2019 //@weave
2020 //<Iteratable/1:iteratable
2021 //<...:iteratable
2022 //<Iteratable/n:iteratable
2023 //>iteratable
2024 // Returns a new iteratable that produces interleaved values :mini:`V/i` from each of :mini:`Iteratable/i`.
2025 // The iteratable stops produces values when any of the :mini:`Iteratable/i` stops.
2026 ML_CHECK_ARG_COUNT(1);
2027 ml_weaved_t *Weaved = xnew(ml_weaved_t, Count, ml_value_t *);
2028 Weaved->Type = MLWeavedT;
2029 Weaved->Count = Count;
2030 for (int I = 0; I < Count; ++I) Weaved->Iters[I] = Args[I];
2031 return (ml_value_t *)Weaved;
2032 }
2033
2034 typedef struct {
2035 ml_type_t *Type;
2036 ml_value_t *Value;
2037 } ml_swapped_t;
2038
2039 ML_TYPE(MLSwappedT, (MLIteratableT), "swapped");
2040 //!internal
2041
2042 typedef struct {
2043 ml_state_t Base;
2044 ml_value_t *Iter;
2045 } ml_swapped_state_t;
2046
2047 ML_TYPE(MLSwappedStateT, (), "swapped-state");
2048 //!internal
2049
swapped_iterate(ml_swapped_state_t * State,ml_value_t * Value)2050 static void swapped_iterate(ml_swapped_state_t *State, ml_value_t *Value) {
2051 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
2052 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, Value);
2053 State->Iter = Value;
2054 ML_CONTINUE(State->Base.Caller, State);
2055 }
2056
ML_TYPED_FN(ml_iterate,MLSwappedT,ml_state_t * Caller,ml_swapped_t * Swapped)2057 static void ML_TYPED_FN(ml_iterate, MLSwappedT, ml_state_t *Caller, ml_swapped_t *Swapped) {
2058 ml_swapped_state_t *State = new(ml_swapped_state_t);
2059 State->Base.Caller = Caller;
2060 State->Base.Type = MLSwappedStateT;
2061 State->Base.Context = Caller->Context;
2062 State->Base.run = (void *)swapped_iterate;
2063 return ml_iterate((ml_state_t *)State, Swapped->Value);
2064 }
2065
ML_TYPED_FN(ml_iter_key,MLSwappedStateT,ml_state_t * Caller,ml_swapped_state_t * State)2066 static void ML_TYPED_FN(ml_iter_key, MLSwappedStateT, ml_state_t *Caller, ml_swapped_state_t *State) {
2067 return ml_iter_value(Caller, State->Iter);
2068 }
2069
ML_TYPED_FN(ml_iter_value,MLSwappedStateT,ml_state_t * Caller,ml_swapped_state_t * State)2070 static void ML_TYPED_FN(ml_iter_value, MLSwappedStateT, ml_state_t *Caller, ml_swapped_state_t *State) {
2071 return ml_iter_key(Caller, State->Iter);
2072 }
2073
ML_TYPED_FN(ml_iter_next,MLSwappedStateT,ml_state_t * Caller,ml_swapped_state_t * State)2074 static void ML_TYPED_FN(ml_iter_next, MLSwappedStateT, ml_state_t *Caller, ml_swapped_state_t *State) {
2075 return ml_iter_next((ml_state_t *)State, State->Iter);
2076 }
2077
ML_FUNCTION(Swap)2078 ML_FUNCTION(Swap) {
2079 //@swap
2080 //<Iteratable:iteratable
2081 // Returns a new iteratable which swaps the keys and values produced by :mini:`Iteratable`.
2082 ML_CHECK_ARG_COUNT(1);
2083 ML_CHECK_ARG_TYPE(0, MLIteratableT);
2084 ml_swapped_t *Swapped = new(ml_swapped_t);
2085 Swapped->Type = MLSwappedT;
2086 Swapped->Value = Args[0];
2087 return (ml_value_t *)Swapped;
2088 }
2089
2090 typedef struct {
2091 ml_type_t *Type;
2092 ml_value_t *Value;
2093 } ml_key_t;
2094
2095 ML_TYPE(MLKeyT, (MLIteratableT), "key");
2096 //!internal
2097
2098 typedef struct {
2099 ml_state_t Base;
2100 ml_value_t *Iter;
2101 int Iteration;
2102 } ml_key_state_t;
2103
2104 ML_TYPE(MLKeyStateT, (), "keys-state");
2105 //!internal
2106
key_iterate(ml_key_state_t * State,ml_value_t * Value)2107 static void key_iterate(ml_key_state_t *State, ml_value_t *Value) {
2108 if (ml_is_error(Value)) ML_CONTINUE(State->Base.Caller, Value);
2109 if (Value == MLNil) ML_CONTINUE(State->Base.Caller, Value);
2110 State->Iter = Value;
2111 ++State->Iteration;
2112 ML_CONTINUE(State->Base.Caller, State);
2113 }
2114
ML_TYPED_FN(ml_iterate,MLKeyT,ml_state_t * Caller,ml_key_t * Key)2115 static void ML_TYPED_FN(ml_iterate, MLKeyT, ml_state_t *Caller, ml_key_t *Key) {
2116 ml_key_state_t *State = new(ml_key_state_t);
2117 State->Base.Caller = Caller;
2118 State->Base.Type = MLKeyStateT;
2119 State->Base.Context = Caller->Context;
2120 State->Base.run = (void *)key_iterate;
2121 return ml_iterate((ml_state_t *)State, Key->Value);
2122 }
2123
ML_TYPED_FN(ml_iter_key,MLKeyStateT,ml_state_t * Caller,ml_key_state_t * State)2124 static void ML_TYPED_FN(ml_iter_key, MLKeyStateT, ml_state_t *Caller, ml_key_state_t *State) {
2125 ML_RETURN(ml_integer(State->Iteration));
2126 }
2127
ML_TYPED_FN(ml_iter_value,MLKeyStateT,ml_state_t * Caller,ml_key_state_t * State)2128 static void ML_TYPED_FN(ml_iter_value, MLKeyStateT, ml_state_t *Caller, ml_key_state_t *State) {
2129 return ml_iter_key(Caller, State->Iter);
2130 }
2131
ML_TYPED_FN(ml_iter_next,MLKeyStateT,ml_state_t * Caller,ml_key_state_t * State)2132 static void ML_TYPED_FN(ml_iter_next, MLKeyStateT, ml_state_t *Caller, ml_key_state_t *State) {
2133 return ml_iter_next((ml_state_t *)State, State->Iter);
2134 }
2135
ML_FUNCTION(Key)2136 ML_FUNCTION(Key) {
2137 //@key
2138 //<Iteratable:iteratable
2139 // Returns a new iteratable which produces the keys of :mini:`Iteratable`.
2140 ML_CHECK_ARG_COUNT(1);
2141 ML_CHECK_ARG_TYPE(0, MLIteratableT);
2142 ml_key_t *Key = new(ml_key_t);
2143 Key->Type = MLKeyT;
2144 Key->Value = Args[0];
2145 return (ml_value_t *)Key;
2146 }
2147
ml_iterfns_init(stringmap_t * Globals)2148 void ml_iterfns_init(stringmap_t *Globals) {
2149 FilterNil = new(ml_filter_t);
2150 FilterNil->Type = FilterT;
2151 FilterNil->Function = ml_integer(1);
2152 #include "ml_iterfns_init.c"
2153 if (Globals) {
2154 stringmap_insert(Globals, "filter", Filter);
2155 stringmap_insert(Globals, "first", First);
2156 stringmap_insert(Globals, "first2", First2);
2157 stringmap_insert(Globals, "last", Last);
2158 stringmap_insert(Globals, "last2", Last2);
2159 stringmap_insert(Globals, "all", All);
2160 stringmap_insert(Globals, "count", MLIterCount);
2161 stringmap_insert(Globals, "count2", Count2);
2162 stringmap_insert(Globals, "reduce", Reduce);
2163 stringmap_insert(Globals, "min", Min);
2164 stringmap_insert(Globals, "max", Max);
2165 stringmap_insert(Globals, "sum", Sum);
2166 stringmap_insert(Globals, "prod", Prod);
2167 stringmap_insert(Globals, "reduce2", Reduce2);
2168 stringmap_insert(Globals, "min2", Min2);
2169 stringmap_insert(Globals, "max2", Max2);
2170 stringmap_insert(Globals, "parallel", Parallel);
2171 stringmap_insert(Globals, "buffered", Buffered);
2172 stringmap_insert(Globals, "unique", Unique);
2173 stringmap_insert(Globals, "tasks", MLTasksT);
2174 stringmap_insert(Globals, "zip", Zip);
2175 stringmap_insert(Globals, "pair", Pair);
2176 stringmap_insert(Globals, "weave", Weave);
2177 stringmap_insert(Globals, "swap", Swap);
2178 stringmap_insert(Globals, "key", Key);
2179 }
2180 }
2181