git.dumitru.net fructose / master src / parser / combinators / EitherParser.ts
master

Tree @master (Download .tar.gz)

EitherParser.ts @masterraw · history · blame

import Document from "../../Document";
import DocumentLocation from "../../DocumentLocation";
import Parser from "../Parser";
import ParserError from "../ParserError";
import ParserValue from "../ParserValue";

export default class EitherParser<L, R> implements Parser<L | R> {
  public readonly name: string;
  private l: () => Parser<L>;
  private r: () => Parser<R>;

  constructor(l: () => Parser<L>, r: () => Parser<R>) {
    this.l = l;
    this.r = r;
    this.name = `${l().name} or ${r().name}`;
  }

  public parse(doc: Document, loc: DocumentLocation): ParserValue<L | R> | ParserError {
    const tryLeft = this.l().parse(doc, loc);

    if (tryLeft instanceof ParserValue) {
      return tryLeft;
    }

    const tryRight = this.r().parse(doc, loc);

    if (tryRight instanceof ParserValue) {
      return tryRight;
    }

    return new ParserError("expected either, got something else", loc, null);
  }
}