aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay Nair <phenax5@gmail.com>2022-01-08 17:33:10 +0530
committerAkshay Nair <phenax5@gmail.com>2022-01-08 17:33:10 +0530
commit173b249d9a91d8fee7c3cc18946e8fda188295c2 (patch)
tree65e1435798cc652101e9a0feefedbe3b3ccacc71
parent6639605b395ceb1355c95e06ff0e1470adc54101 (diff)
downloadelxr-173b249d9a91d8fee7c3cc18946e8fda188295c2.tar.gz
elxr-173b249d9a91d8fee7c3cc18946e8fda188295c2.zip
refactor: creates constructors for expr adt
Diffstat (limited to '')
-rw-r--r--src/parser/index.ts43
-rw-r--r--src/types.ts36
-rw-r--r--src/utils.ts15
-rw-r--r--tests/basic.spec.ts25
4 files changed, 64 insertions, 55 deletions
diff --git a/src/parser/index.ts b/src/parser/index.ts
index f522214..9e284f6 100644
--- a/src/parser/index.ts
+++ b/src/parser/index.ts
@@ -1,4 +1,4 @@
-import { constant, pipe } from 'fp-ts/function'
+import { pipe } from 'fp-ts/function'
import { chain, orElse, right } from 'fp-ts/lib/Either'
import {
delimited,
@@ -13,36 +13,24 @@ import {
} from './utils'
import { Expr } from '../types'
-export const start = mapTo(symbol('^'), constant({ tag: 'Start' } as Expr))
-export const end = mapTo(symbol('$'), constant({ tag: 'End' } as Expr))
-export const anyItem = mapTo(symbol('.'), constant({ tag: 'AnyItem' } as Expr))
-export const nextItem = mapTo(
- symbol(','),
- constant({ tag: 'NextItem' } as Expr)
-)
-export const anyString = mapTo(
- symbol('\\s'),
- constant({ tag: 'AnyString' } as Expr)
-)
-export const anyNumber = mapTo(
- symbol('\\n'),
- constant({ tag: 'AnyNumber' } as Expr)
-)
-export const anyBool = mapTo(
- symbol('\\b'),
- constant({ tag: 'AnyBool' } as Expr)
-)
-export const truthy = mapTo(symbol('\\T'), constant({ tag: 'Truthy' } as Expr))
-export const falsey = mapTo(symbol('\\F'), constant({ tag: 'Falsey' } as Expr))
+export const start = mapTo(symbol('^'), () => Expr.Start(null))
+export const end = mapTo(symbol('$'), () => Expr.End(null))
+export const anyItem = mapTo(symbol('.'), () => Expr.AnyItem(null))
+export const nextItem = mapTo(symbol(','), () => Expr.NextItem(null))
+export const anyString = mapTo(symbol('\\s'), () => Expr.AnyString(null))
+export const anyNumber = mapTo(symbol('\\n'), () => Expr.AnyNumber(null))
+export const anyBool = mapTo(symbol('\\b'), () => Expr.AnyBool(null))
+export const truthy = mapTo(symbol('\\T'), () => Expr.Truthy(null))
+export const falsey = mapTo(symbol('\\F'), () => Expr.Falsey(null))
export const wrapQuantifiers: (e: ParserResult<Expr>) => ParserResult<Expr> =
chain(([expr, input]) =>
pipe(
input,
or([
- mapTo(symbol('*'), (_) => ({ tag: 'ZeroOrMore', expr } as Expr)),
- mapTo(symbol('+'), (_) => ({ tag: 'OneOrMore', expr } as Expr)),
- mapTo(symbol('?'), (_) => ({ tag: 'Optional', expr } as Expr)),
+ mapTo(symbol('*'), () => Expr.ZeroOrMore({ expr })),
+ mapTo(symbol('+'), () => Expr.OneOrMore({ expr })),
+ mapTo(symbol('?'), () => Expr.Optional({ expr })),
]),
orElse(() => right([expr, input]))
)
@@ -52,9 +40,8 @@ export const expressionP: Parser<Expr> = (input: string) =>
pipe(
input,
or([
- mapTo(
- delimited(symbol('('), many1(expressionP), symbol(')')),
- (exprs) => ({ tag: 'Group', exprs } as Expr)
+ mapTo(delimited(symbol('('), many1(expressionP), symbol(')')), (exprs) =>
+ Expr.Group({ exprs })
),
nextItem,
anyItem,
diff --git a/src/types.ts b/src/types.ts
index 21e9517..7863981 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -1,17 +1,23 @@
+import { constructors, Union } from "./utils"
-export type Expr =
- | { tag: 'Start' }
- | { tag: 'End' }
- | { tag: 'Optional'; expr: Expr }
- | { tag: 'OneOrMore'; expr: Expr }
- | { tag: 'ZeroOrMore'; expr: Expr }
- | { tag: 'NextItem' }
- | { tag: 'AnyItem' }
- | { tag: 'Or' }
- | { tag: 'AnyString' }
- | { tag: 'AnyNumber' }
- | { tag: 'AnyBool' }
- | { tag: 'Truthy' }
- | { tag: 'Falsey' }
- | { tag: 'Group'; exprs: Expr[] }
+type ExprT = {
+ Start: any,
+ End: any,
+ Optional: { expr: Expr },
+ OneOrMore: { expr: Expr },
+ ZeroOrMore: { expr: Expr },
+ NextItem: any,
+ AnyItem: any,
+ Or: any,
+ AnyString: any,
+ AnyNumber: any,
+ AnyBool: any,
+ Truthy: any,
+ Falsey: any,
+ Group: { exprs: Expr[] },
+}
+
+export type Expr = Union<ExprT>
+
+export const Expr = constructors<ExprT>()
diff --git a/src/utils.ts b/src/utils.ts
index 9c4c97b..6591050 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -7,3 +7,18 @@ export const match =
<R, K extends string>(pattern: { [key in K | '_']: () => R }) =>
(k: K): R =>
(pattern[k] || pattern._)()
+
+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]>
+} =>
+ new Proxy(
+ {},
+ {
+ get(_, k) {
+ return (value: any) => ({ tag: k, value })
+ },
+ }
+ ) as any
diff --git a/tests/basic.spec.ts b/tests/basic.spec.ts
index 59ce573..d443ce1 100644
--- a/tests/basic.spec.ts
+++ b/tests/basic.spec.ts
@@ -7,6 +7,7 @@ import {
} from '../src/parser/utils'
import { parser } from '../src/parser'
import { some } from 'fp-ts/Option'
+import { Expr } from '../src/types'
describe('Foobar', () => {
it('should do shit', () => {
@@ -28,15 +29,15 @@ describe('Foobar', () => {
expect(parser(/^ .\s(\n)\b \T $/.source)).toEqual(
right([
[
- some({ tag: 'Start' }),
+ some(Expr.Start(null)),
[
- { tag: 'AnyItem' },
- { tag: 'AnyString' },
- { tag: 'Group', exprs: [{ tag: 'AnyNumber' }] },
- { tag: 'AnyBool' },
- { tag: 'Truthy' },
+ Expr.AnyItem(null),
+ Expr.AnyString(null),
+ Expr.Group({ exprs: [Expr.AnyNumber(null)] }),
+ Expr.AnyBool(null),
+ Expr.Truthy(null),
],
- some({ tag: 'End' }),
+ some(Expr.End(null)),
],
'',
])
@@ -45,13 +46,13 @@ describe('Foobar', () => {
expect(parser(/^ \s* \T? \n+ $/.source)).toEqual(
right([
[
- some({ tag: 'Start' }),
+ some(Expr.Start(null)),
[
- { tag: 'ZeroOrMore', expr: { tag: 'AnyString' } },
- { tag: 'Optional', expr: { tag: 'Truthy' } },
- { tag: 'OneOrMore', expr: { tag: 'AnyNumber' } },
+ Expr.ZeroOrMore({ expr: Expr.AnyString(null) }),
+ Expr.Optional({ expr: Expr.Truthy(null) }),
+ Expr.OneOrMore({ expr: Expr.AnyNumber(null) }),
],
- some({ tag: 'End' }),
+ some(Expr.End(null)),
],
'',
])