diff options
| author | Akshay Nair <phenax5@gmail.com> | 2022-01-07 12:29:36 +0530 |
|---|---|---|
| committer | Akshay Nair <phenax5@gmail.com> | 2022-01-07 12:29:36 +0530 |
| commit | 20480cd42bbbe1685b9470063248ed5fc1f2506b (patch) | |
| tree | edc0ffc194dc2d8a583be1492e01744c9b23ef49 /src/parser.ts | |
| parent | 8ef91f03fac2bad20fb927fe2ca2782c66fdb513 (diff) | |
| download | elxr-20480cd42bbbe1685b9470063248ed5fc1f2506b.tar.gz elxr-20480cd42bbbe1685b9470063248ed5fc1f2506b.zip | |
refactor: minor changes
Diffstat (limited to 'src/parser.ts')
| -rw-r--r-- | src/parser.ts | 78 |
1 files changed, 35 insertions, 43 deletions
diff --git a/src/parser.ts b/src/parser.ts index 5ccba43..9baab8e 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -1,6 +1,8 @@ import { flow, pipe } from 'fp-ts/function' import { Either, left, right, map, chain, orElse, fold } from 'fp-ts/Either' -import { none, some, Option } from 'fp-ts/lib/Option' +import { none, some, Option } from 'fp-ts/Option' +import { mapFst, snd } from 'fp-ts/Tuple' +import { eq } from './utils' export type char = string @@ -17,13 +19,14 @@ export const many0 = <T>(parser: Parser<T>): Parser<Array<T>> => flow( parser, chain(([a, nextInput]) => - pipe( - nextInput, - many0(parser), - map(([ls, inp]): ParserResult<T[]> => [[a, ...ls], inp]) - ) + pipe(nextInput, many0(parser), map(mapFst((ls) => [a, ...ls]))) ), - orElse(([_, inp]) => right([[] as T[], inp])) + orElse( + flow( + mapFst((_) => [] as T[]), + right + ) + ) ) export const many1 = <T>(parser: Parser<T>): Parser<Array<T>> => @@ -37,21 +40,12 @@ export const many1 = <T>(parser: Parser<T>): Parser<Array<T>> => ) export const prefixed = <T>(a: Parser<any>, b: Parser<T>): Parser<T> => - flow( - a, - chain(([_, inp]) => b(inp)) - ) + flow(a, chain(flow(snd, b))) export const suffixed = <T>(a: Parser<T>, b: Parser<any>): Parser<T> => flow( a, - chain(([out, inp]) => - pipe( - inp, - b, - chain(([_, inp2]) => right([out, inp2])) - ) - ) + chain(([out, inp]) => pipe(inp, b, map(mapFst((_) => out)))) ) export const delimited = <T>( @@ -72,22 +66,22 @@ export const digit = satifyChar((c) => /^[0-9]$/g.test(c)) export const integer: Parser<number> = flow( many1(digit), - map(([ds, input]) => [parseInt(ds.join(''), 10), input]) + map(mapFst((ds) => parseInt(ds.join(''), 10))) ) export const or = <T>(parsers: Parser<T>[]): Parser<T> => { - const ppp = ([p, ...ps]: Parser<T>[]) => + const run = ([p, ...ps]: Parser<T>[]) => flow( p, orElse(([_, inp]) => or(ps)(inp)) ) return parsers.length > 0 - ? ppp(parsers) + ? run(parsers) : (inp: string) => left(['unable to match', inp]) } -export const matchChar = (ch: char): Parser<char> => satifyChar((c) => c === ch) +export const matchChar = (ch: char): Parser<char> => satifyChar(eq(ch)) export const space = matchChar(' ') export const newline = matchChar('\n') @@ -102,11 +96,7 @@ export const matchString = (s: string): Parser<string> => : flow( matchChar(s.charAt(0)), chain(([c, inp]) => - pipe( - inp, - matchString(s.slice(1)), - map(([s, inp]) => [c + s, inp]) - ) + pipe(inp, matchString(s.slice(1)), map(mapFst((s) => c + s))) ) ) @@ -114,28 +104,30 @@ export const symbol = (s: string): Parser<string> => delimited(whitespaces0, matchString(s), whitespaces0) export const mapTo = <I, R>(p: Parser<I>, f: (p: I) => R): Parser<R> => - flow( - p, - map(([v, inp]) => [f(v), inp]) - ) + flow(p, map(mapFst(f))) -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 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]) + flow( + mapFst((_) => none), + right + ), + flow(mapFst(some), right) ) ) -export const pair = <A, B>(a: Parser<A>, b: Parser<B>): Parser<[A, B]> => pipe( - a, - andThen(ra => mapTo(b, rb => [ra, rb])) -) - +export const pair = <A, B>(a: Parser<A>, b: Parser<B>): Parser<[A, B]> => + pipe( + a, + andThen((ra) => mapTo(b, (rb) => [ra, rb])) + ) |
