import Document from "../../Document";
import DocumentLocation from "../../DocumentLocation";
import Parser from "../Parser";
import ParserError from "../ParserError";
import ParserValue from "../ParserValue";
export default class SequenceParser<T> implements Parser<T[]> {
public readonly name: string;
private ps: Array<() => Parser<T>>;
constructor(ps: Array<() => Parser<T>>) {
this.ps = ps;
this.name = `${ps.map((p) => p ? p.name : "").join(" ")}`;
}
public parse(doc: Document, loc: DocumentLocation): ParserValue<T[]> | ParserError {
let curr = loc;
const accumulator: T[] = [];
for (const p of this.ps) {
const result = p().parse(doc, curr);
if (result instanceof ParserValue) {
accumulator.push(result.value);
curr = result.location;
} else if (result instanceof ParserError) {
return new ParserError(`expected ${p.name}, got something else`, curr, result);
}
}
return new ParserValue(accumulator, curr);
}
}