diff options
| author | Akshay Nair <phenax5@gmail.com> | 2022-01-06 23:41:32 +0530 |
|---|---|---|
| committer | Akshay Nair <phenax5@gmail.com> | 2022-01-06 23:41:32 +0530 |
| commit | 8ef91f03fac2bad20fb927fe2ca2782c66fdb513 (patch) | |
| tree | 6214acb7d0cf940a4b4ac64fbca3c12294de71e8 | |
| parent | 3d88de49d99d86c70204d6870296b20177c2af21 (diff) | |
| download | elxr-8ef91f03fac2bad20fb927fe2ca2782c66fdb513.tar.gz elxr-8ef91f03fac2bad20fb927fe2ca2782c66fdb513.zip | |
feat: adds more parser combinators
Diffstat (limited to '')
| -rw-r--r-- | src/index.ts | 12 | ||||
| -rw-r--r-- | src/parser.ts | 24 | ||||
| -rw-r--r-- | tests/basic.spec.ts | 6 |
3 files changed, 40 insertions, 2 deletions
diff --git a/src/index.ts b/src/index.ts index d236473..582f9be 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import { constant, flow, identity, pipe } from 'fp-ts/function' -import { mapTo, symbol } from './parser' +import { andThen, delimited, mapTo, optional, pair, symbol } from './parser' export const start = mapTo(symbol('^'), constant({ tag: 'Start' } as Expr)) export const end = mapTo(symbol('$'), constant({ tag: 'End' } as Expr)) @@ -27,6 +27,16 @@ type Expr = | { tag: 'Truthy' } | { tag: 'Falsey' } +export const expressionP = symbol('fuck') + +export const parser = pair( + pair( + optional(start), + expressionP, + ), + optional(end), +) + /* ^ $ => start and end of list diff --git a/src/parser.ts b/src/parser.ts index f8dcd44..5ccba43 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -1,5 +1,6 @@ import { flow, pipe } from 'fp-ts/function' -import { Either, left, right, map, chain, orElse } from 'fp-ts/Either' +import { Either, left, right, map, chain, orElse, fold } from 'fp-ts/Either' +import { none, some, Option } from 'fp-ts/lib/Option' export type char = string @@ -117,3 +118,24 @@ export const mapTo = <I, R>(p: Parser<I>, f: (p: I) => R): Parser<R> => p, map(([v, inp]) => [f(v), inp]) ) + +export const andThen = <I, R>(f: (p: I) => Parser<R>) => (p: Parser<I>): Parser<R> => + flow( + p, + chain(([v, inp]) => f(v)(inp)), + ) + +export const optional = <T>(p: Parser<T>): Parser<Option<T>> => + flow( + p, + fold( + ([_, inp]) => right([none, inp]), + ([v, inp]) => right([some(v), inp]) + ) + ) + +export const pair = <A, B>(a: Parser<A>, b: Parser<B>): Parser<[A, B]> => pipe( + a, + andThen(ra => mapTo(b, rb => [ra, rb])) +) + diff --git a/tests/basic.spec.ts b/tests/basic.spec.ts index eeeb121..962f076 100644 --- a/tests/basic.spec.ts +++ b/tests/basic.spec.ts @@ -9,7 +9,9 @@ import { whitespaces0, delimited, symbol, + optional, } from '../src/parser' +import { parser } from '../src' describe('Foobar', () => { it('should do shit', () => { @@ -26,4 +28,8 @@ describe('Foobar', () => { right([2, '0 ']) ) }) + + it('should maybeshut', () => { + console.log(JSON.stringify(parser('fuck'), null, 2)) + }) }) |
