aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay Nair <phenax5@gmail.com>2022-02-17 21:31:29 +0530
committerAkshay Nair <phenax5@gmail.com>2022-02-17 21:31:29 +0530
commitdfed1434ebc06a630cd7bde6609e3b122bf81de3 (patch)
treee71b9bbc7f8389491389d3e5280f4bddb0e0ec8b
parent996c8ad9de8186417d040fa59f189208b4311375 (diff)
downloadelxr-dfed1434ebc06a630cd7bde6609e3b122bf81de3.tar.gz
elxr-dfed1434ebc06a630cd7bde6609e3b122bf81de3.zip
feat(replace): adds replaceAll function
-rw-r--r--default.nix2
-rw-r--r--src/eval/index.ts41
-rw-r--r--src/index.ts5
-rw-r--r--src/parser/index.ts1
-rw-r--r--tests/basic.spec.ts31
-rw-r--r--tests/replace.spec.ts39
6 files changed, 108 insertions, 11 deletions
diff --git a/default.nix b/default.nix
index 7b1a6c7..11ff735 100644
--- a/default.nix
+++ b/default.nix
@@ -5,8 +5,8 @@ mkShell rec {
nodejs-16_x
yarn
efm-langserver
- nodePackages.vls
nodePackages.prettier
+ nodePackages.eslint
nodePackages.typescript-language-server
];
}
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,
diff --git a/tests/basic.spec.ts b/tests/basic.spec.ts
index f02169c..67f63d6 100644
--- a/tests/basic.spec.ts
+++ b/tests/basic.spec.ts
@@ -219,6 +219,37 @@ describe('Basic tests', () => {
index: 6,
},
])
+
+ expect(
+ matchAll(/"start", \s, \n/, [
+ 1,
+ 'start',
+ 'x',
+ 2,
+ 'start',
+ 3,
+ 'start',
+ 'y',
+ 4,
+ ]).groups,
+ ).toEqual([
+ {
+ value: [
+ [{ value: 'start', index: 1 }],
+ [{ value: 'x', index: 2 }],
+ [{ value: 2, index: 3 }],
+ ],
+ index: 1,
+ },
+ {
+ value: [
+ [{ value: 'start', index: 6 }],
+ [{ value: 'y', index: 7 }],
+ [{ value: 4, index: 8 }],
+ ],
+ index: 6,
+ },
+ ])
})
it('should match min-max quantified expressions', () => {
diff --git a/tests/replace.spec.ts b/tests/replace.spec.ts
new file mode 100644
index 0000000..dd82eaa
--- /dev/null
+++ b/tests/replace.spec.ts
@@ -0,0 +1,39 @@
+import { jlog } from '../src/utils'
+import { replaceAll } from '../src'
+
+describe('Basic tests', () => {
+ it('should', () => {
+ expect(
+ replaceAll(/"start", \s, \n/, _ => ['replaced'], [
+ 1,
+ 'start',
+ 'x',
+ 2,
+ 'start',
+ 3,
+ 'start',
+ 'y',
+ 4,
+ ]),
+ ).toEqual([1, 'replaced', 'start', 3, 'replaced'])
+ })
+
+ it('should replace matching items', () => {
+ expect(replaceAll(/\F/, (_x, _i) => [69], [1, 5, 0, 0, 2, 9, 0])).toEqual([
+ 1, 5, 69, 69, 2, 9, 69,
+ ])
+
+ expect(
+ replaceAll(/\s+/, (_x, m) => [(m.value as any).join(',')], [
+ 1,
+ 'wow',
+ 'test',
+ [],
+ '0',
+ 2,
+ '',
+ 'nice',
+ ]),
+ ).toEqual([1, 'wow,test', [], '0', 2, ',nice'])
+ })
+})