module /** */ import { Issues } from "../issues" ; import { ResultKind } from "../result" ; import { ParsingState } from "../state" ; import { ImplicitParjser , ParjsCombinator } from "../../index" ; import { ScalarConverter } from "../scalar-converter" ; import { ParjserBase } from "../parser" ; import { defineCombinator } from "./combinator" ; param delimeter param max export function manySepBy < T > ( delimeter , max ? ) ; export function manySepBy ( implDelimeter , max = Infinity ) { let delimeter = ScalarConverter . convert ( implDelimeter ) as any as ParjserBase ; return defineCombinator ( source => { return new class extends ParjserBase { type = "manySepBy" ; expecting = source . expecting ; _apply ( ps ) { let arr = [ ] as any [ ] ; source . apply ( ps ) ; if ( ps . atLeast ( ResultKind . HardFail ) ) { return ; } else if ( ps . isSoft ) { ps . value = [ ] ; ps . kind = ResultKind . Ok ; return ; } let { position } = ps ; arr . push ( ps . value ) ; let i = 1 ; while ( true ) { if ( i >= max ) break ; delimeter . apply ( ps ) ; if ( ps . isSoft ) { break ; } else if ( ps . atLeast ( ResultKind . HardFail ) ) { return ; } source . apply ( ps ) ; if ( ps . isSoft ) { break ; } else if ( ps . atLeast ( ResultKind . HardFail ) ) { return ; } if ( max >= Infinity && ps . position === position ) { Issues . guardAgainstInfiniteLoop ( "many" ) ; } arr . push ( ps . value ) ; position = ps . position ; i ++ ; } ps . kind = ResultKind . Ok ; ps . position = position ; ps . value = arr ; } } ( ) ; } ) ; }