aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO.md6
-rw-r--r--src/parser/index.ts18
-rw-r--r--src/types.ts28
-rw-r--r--src/utils.ts18
-rw-r--r--tests/eval.spec.ts16
-rw-r--r--tests/parser.spec.ts36
6 files changed, 60 insertions, 62 deletions
diff --git a/TODO.md b/TODO.md
index 5760fde..51850a3 100644
--- a/TODO.md
+++ b/TODO.md
@@ -6,16 +6,12 @@
- [ ] Parse: `{2, 5}` quantifiers
- [ ] Eval: `^$` start-end
- [ ] Func: filter
- - [ ] Func: match
+ - [ ] Func: matchAll
- [ ] Func: replace
- [ ] Not/Inverse
- [ ] Named capture groups
- [ ] Non-capture groups
-## Issues
- - [ ] . should not match for empty list
-
## Refactor
- - [ ] Remove default null for constructors
- [ ] Create group inside PropertyMatch and send single `expr`
diff --git a/src/parser/index.ts b/src/parser/index.ts
index 386fa94..c61364d 100644
--- a/src/parser/index.ts
+++ b/src/parser/index.ts
@@ -20,15 +20,15 @@ import {
} from './utils'
import { Expr, ListExpr } from '../types'
-const start = mapTo(symbol('^'), _ => Expr.Start(null))
-const end = mapTo(symbol('$'), _ => Expr.End(null))
-const anyItem = mapTo(symbol('.'), _ => Expr.AnyItem(null))
-const nextItem = mapTo(symbol(','), _ => Expr.NextItem(null))
-const anyString = mapTo(symbol('\\s'), _ => Expr.AnyString(null))
-const anyNumber = mapTo(symbol('\\n'), _ => Expr.AnyNumber(null))
-const anyBool = mapTo(symbol('\\b'), _ => Expr.AnyBool(null))
-const truthy = mapTo(symbol('\\T'), _ => Expr.Truthy(null))
-const falsey = mapTo(symbol('\\F'), _ => Expr.Falsey(null))
+const start = mapTo(symbol('^'), _ => Expr.Start())
+const end = mapTo(symbol('$'), _ => Expr.End())
+const anyItem = mapTo(symbol('.'), _ => Expr.AnyItem())
+const nextItem = mapTo(symbol(','), _ => Expr.NextItem())
+const anyString = mapTo(symbol('\\s'), _ => Expr.AnyString())
+const anyNumber = mapTo(symbol('\\n'), _ => Expr.AnyNumber())
+const anyBool = mapTo(symbol('\\b'), _ => Expr.AnyBool())
+const truthy = mapTo(symbol('\\T'), _ => Expr.Truthy())
+const falsey = mapTo(symbol('\\F'), _ => Expr.Falsey())
const wrapQuantifiers: (e: ParserResult<Expr>) => ParserResult<Expr> = chain(
([expr, input]) =>
diff --git a/src/types.ts b/src/types.ts
index 07e6e8a..d30413d 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -1,27 +1,27 @@
import {Option} from "fp-ts/lib/Option"
import { constructors, Union } from "./utils"
-type ExprT = {
- Start: null,
- End: null,
+type _ = never
+
+export type Expr = Union<{
+ Start: _,
+ End: _,
Optional: { expr: Expr },
OneOrMore: { expr: Expr },
ZeroOrMore: { expr: Expr },
- NextItem: null,
- AnyItem: null,
+ NextItem: _,
+ AnyItem: _,
Or: { left: Expr, right: Expr[] },
- AnyString: null,
- AnyNumber: null,
- AnyBool: null,
- Truthy: null,
- Falsey: null,
+ AnyString: _,
+ AnyNumber: _,
+ AnyBool: _,
+ Truthy: _,
+ Falsey: _,
Group: { exprs: Expr[] },
PropertyMatch: { name: string, exprs: Expr[] },
-}
-
-export type Expr = Union<ExprT>
+}>
-export const Expr = constructors<ExprT>()
+export const Expr = constructors<Expr>()
export type ListExpr = [
Option<Expr>,
diff --git a/src/utils.ts b/src/utils.ts
index 15d5fb0..66c4c53 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -3,19 +3,22 @@ export const eq =
(b: T): boolean =>
a === b
-type TagValue<T, N> = T extends Tag<N, infer V> ? V : never;
+type TagValue<T, N> = T extends Tag<N, infer V> ? V : never
export const match =
- <R, T extends Tag<string, any>>
- (pattern: { [key in T['tag'] | '_']?: (v: TagValue<T, key>) => R }) =>
- (tag: T): R =>
- (pattern[tag.tag] || pattern._ as any)(tag.value)
+ <R, T extends Tag<string, any>>(pattern: {
+ [key in T['tag'] | '_']?: (v: TagValue<T, key>) => R
+ }) =>
+ (tag: T): R =>
+ (pattern[tag.tag] || (pattern._ as any))(tag.value)
type Tag<N, V> = { tag: N; value: V }
export type Union<T> = { [N in keyof T]: Tag<N, T[N]> }[keyof T]
-export const constructors = <T extends Record<string, any>>(): {
- [N in keyof T]: (value: T[N]) => Union<T> // Tag<N, T[N]>
+export const constructors = <T extends Tag<string, any>>(): {
+ [N in T['tag']]: TagValue<T, N> extends null|never
+ ? (value?: null | never) => T
+ : (value: TagValue<T, N>) => T
} =>
new Proxy(
{},
@@ -27,4 +30,3 @@ export const constructors = <T extends Record<string, any>>(): {
) as any
export const jlog = (x: any) => console.log(JSON.stringify(x, null, 2))
-
diff --git a/tests/eval.spec.ts b/tests/eval.spec.ts
index ca06033..2d7e1c0 100644
--- a/tests/eval.spec.ts
+++ b/tests/eval.spec.ts
@@ -13,7 +13,7 @@ describe('Eval', () => {
[
Expr.OneOrMore({
expr: Expr.Group({
- exprs: [Expr.AnyNumber(null), Expr.Truthy(null)],
+ exprs: [Expr.AnyNumber(), Expr.Truthy()],
}),
}),
],
@@ -28,14 +28,14 @@ describe('Eval', () => {
const liexp: ListExpr = [
none,
- [Expr.AnyNumber(null), Expr.Truthy(null)],
+ [Expr.AnyNumber(), Expr.Truthy()],
none,
]
expect(find(liexp, list)).toEqual([1, 3, 5])
const liexp2: ListExpr = [
none,
- [Expr.Falsey(null), Expr.Truthy(null)],
+ [Expr.Falsey(), Expr.Truthy()],
none,
]
expect(find(liexp2, list)).toEqual([])
@@ -47,8 +47,8 @@ describe('Eval', () => {
const liexp: ListExpr = [
none,
[
- Expr.AnyItem(null),
- Expr.Group({ exprs: [Expr.AnyNumber(null), Expr.Truthy(null)] }),
+ Expr.AnyItem(),
+ Expr.Group({ exprs: [Expr.AnyNumber(), Expr.Truthy()] }),
],
none,
]
@@ -69,9 +69,9 @@ describe('Eval', () => {
[
Expr.PropertyMatch({
name: 'name',
- exprs: [Expr.AnyString(null), Expr.Truthy(null)],
+ exprs: [Expr.AnyString(), Expr.Truthy()],
}),
- Expr.PropertyMatch({ name: 'age', exprs: [Expr.AnyNumber(null)] }),
+ Expr.PropertyMatch({ name: 'age', exprs: [Expr.AnyNumber()] }),
],
none,
]
@@ -84,7 +84,7 @@ describe('Eval', () => {
const liexp: ListExpr = [
none,
- [Expr.OneOrMore({ expr: Expr.AnyNumber(null) })],
+ [Expr.OneOrMore({ expr: Expr.AnyNumber() })],
none,
]
expect(find(liexp, list)).toEqual([1, 3, 5])
diff --git a/tests/parser.spec.ts b/tests/parser.spec.ts
index 4db0894..9bc891e 100644
--- a/tests/parser.spec.ts
+++ b/tests/parser.spec.ts
@@ -33,15 +33,15 @@ describe('Foobar', () => {
expect(parser(/^ .\s(\n)\b \T $/.source)).toEqual(
right([
[
- some(Expr.Start(null)),
+ some(Expr.Start()),
[
- Expr.AnyItem(null),
- Expr.AnyString(null),
- Expr.Group({ exprs: [Expr.AnyNumber(null)] }),
- Expr.AnyBool(null),
- Expr.Truthy(null),
+ Expr.AnyItem(),
+ Expr.AnyString(),
+ Expr.Group({ exprs: [Expr.AnyNumber()] }),
+ Expr.AnyBool(),
+ Expr.Truthy(),
],
- some(Expr.End(null)),
+ some(Expr.End()),
],
'',
]),
@@ -50,13 +50,13 @@ describe('Foobar', () => {
expect(parser(/^ \s* \T? \n+ $/.source)).toEqual(
right([
[
- some(Expr.Start(null)),
+ some(Expr.Start()),
[
- Expr.ZeroOrMore({ expr: Expr.AnyString(null) }),
- Expr.Optional({ expr: Expr.Truthy(null) }),
- Expr.OneOrMore({ expr: Expr.AnyNumber(null) }),
+ Expr.ZeroOrMore({ expr: Expr.AnyString() }),
+ Expr.Optional({ expr: Expr.Truthy() }),
+ Expr.OneOrMore({ expr: Expr.AnyNumber() }),
],
- some(Expr.End(null)),
+ some(Expr.End()),
],
'',
]),
@@ -68,12 +68,12 @@ describe('Foobar', () => {
none,
[
Expr.Or({
- left: Expr.AnyString(null),
+ left: Expr.AnyString(),
right: [
- Expr.AnyBool(null),
+ Expr.AnyBool(),
Expr.Or({
- left: Expr.Truthy(null),
- right: [Expr.AnyNumber(null)],
+ left: Expr.Truthy(),
+ right: [Expr.AnyNumber()],
}),
],
}),
@@ -93,9 +93,9 @@ describe('Foobar', () => {
[
Expr.PropertyMatch({
name: 'name',
- exprs: [Expr.AnyString(null), Expr.Truthy(null)],
+ exprs: [Expr.AnyString(), Expr.Truthy()],
}),
- Expr.PropertyMatch({ name: 'age', exprs: [Expr.AnyNumber(null)] }),
+ Expr.PropertyMatch({ name: 'age', exprs: [Expr.AnyNumber()] }),
],
none,
],