-
-
Notifications
You must be signed in to change notification settings - Fork 144
/
repeat.ts
37 lines (36 loc) · 960 Bytes
/
repeat.ts
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
import {
Match,
Matcher,
SeqCallback,
RES_PARTIAL,
} from "./api";
import { success } from "./success";
export const repeat = <T, C, R>(
match: Matcher<T, C, R>,
min: number,
max: number,
callback?: SeqCallback<T, C, R>
): Matcher<T, C, R> =>
() => {
let m = match();
let i = 0;
const buf: T[] = [];
return (ctx, x) => {
buf.push(x);
const r = m(ctx, x);
if (r.type === Match.FULL) {
i++;
if (i === max) {
return success(callback && callback(ctx, buf));
}
m = match();
return RES_PARTIAL;
} else if (r.type === Match.FAIL) {
if (i >= min) {
buf.pop();
return success(callback && callback(ctx, buf), Match.FULL_NC);
}
}
return r;
};
};