diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/eval/index.ts | 41 | ||||
| -rw-r--r-- | src/index.ts | 5 | ||||
| -rw-r--r-- | src/parser/index.ts | 1 |
3 files changed, 37 insertions, 10 deletions
diff --git a/src/eval/index.ts b/src/eval/index.ts index b7f4de1..b1d55b9 100644 --- a/src/eval/index.ts +++ b/src/eval/index.ts @@ -2,7 +2,7 @@ import { identity, pipe } from 'fp-ts/function' import { filter, takeLeftWhile, zip, zipWith } from 'fp-ts/Array' import * as Option from 'fp-ts/Option' import { index, Expr, ListExpr, Literal } from '../types' -import { match } from '../utils' +import { jlog, match } from '../utils' export interface MatchGroupIndexed<T = any> { value: T @@ -25,7 +25,7 @@ const accumulateSkip = () => { return { localSkip: (i: index) => - <T>(x: T): T => (skipIndexes.push(i), x), + <T>(x: T): T => (skipIndexes.push(i), x), getSkips: () => skipIndexes, } } @@ -38,7 +38,7 @@ const checkExpr = <T>( skip: ( n: index, ) => (m: MatchGroupIndexed<any>[]) => MatchGroupIndexed<any>[] = _ => - identity, + identity, ): MatchGroupIndexed<any>[] => { return pipe( expr, @@ -144,7 +144,6 @@ const checkExpr = <T>( }, ZeroOrMore: ({ expr }) => { - // TODO: Nested quantified expressions? const matches = pipe( list, takeLeftWhile(a => checkExpr(expr, a, list, index).length > 0), @@ -168,10 +167,11 @@ const checkExpr = <T>( } const groups = getGroups() - const skips = Math.max( + const skips = groups.length === 0 ? 1 : Math.max( 1, - getSkips().reduce((a, b) => a + b, -1), + getSkips().reduce((a, b) => a + b, 0), ) + return pipe(groups, skip(skips)) }, @@ -193,8 +193,8 @@ export const matchAll = <T>( const next = (i: number = 1) => - (curMatch: MatchGroupIndexed[]) => - [...curMatch, ...check(index + i, ls.slice(i), expr)] + (curMatch: MatchGroupIndexed[]) => + [...curMatch, ...check(index + i, ls.slice(i), expr)] return checkExpr(expr, item, ls, index, next) } @@ -203,3 +203,28 @@ export const matchAll = <T>( groups: check(0, list, expr), } } + +export const replaceAll = <T>( + [startO, expr, endO]: ListExpr, + replacer: (v: T, match: MatchGroupIndexed<T>, i: index) => T[], + list: T[], +): T[] => { + const check = (index: number, ls: T[], expr: Expr): T[] => { + if (ls.length === 0) return [] + + const [item] = ls + + const next = + (skip: number = 1) => + (curMatch: MatchGroupIndexed[]): MatchGroupIndexed<T>[] => { + const [match] = curMatch + const vals = match ? replacer(item, match, index) : ls.slice(0, skip) + // console.log(i, curMatch, vals) + return [...vals, ...check(index + skip, ls.slice(skip), expr)] as any + } + + return checkExpr(expr, item, ls, index, next) as any + } + + return check(0, list, expr) +} diff --git a/src/index.ts b/src/index.ts index 5bcb4f9..1a52c95 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,7 +3,7 @@ import { flow, pipe } from 'fp-ts/function' import { fst } from 'fp-ts/Tuple' import * as ev from './eval' import { parser } from './parser' -import { ListExpr } from './types' +import { index, ListExpr } from './types' const toSourceString = (r: string | RegExp): string => typeof r === 'string' ? r : r.source @@ -19,3 +19,6 @@ export const liexp: (r: string | RegExp) => ListExpr = flow( export const matchAll = <T>(exp: string | RegExp, list: T[]) => pipe(exp, liexp, lxp => ev.matchAll(lxp, list)) + +export const replaceAll = <T>(exp: string | RegExp, replacer: (v: T, m: ev.MatchGroupIndexed<T>, i: index) => T[], list: T[]) => + pipe(exp, liexp, lxp => ev.replaceAll(lxp, replacer, list)) diff --git a/src/parser/index.ts b/src/parser/index.ts index ac5c8ed..cdb4af1 100644 --- a/src/parser/index.ts +++ b/src/parser/index.ts @@ -8,7 +8,6 @@ import { manyTill, mapTo, matchChar, - matchString, oneOf, optional, or, |
