From 845d503bb16cb5046a4fec6d046b7b527a080187 Mon Sep 17 00:00:00 2001 From: Akshay Nair Date: Fri, 11 Aug 2023 21:40:54 +0530 Subject: chore: adds prettier --- src/utils/parser-comb.ts | 199 ++++++++++++++++++++++++++++------------------- 1 file changed, 118 insertions(+), 81 deletions(-) (limited to 'src/utils/parser-comb.ts') diff --git a/src/utils/parser-comb.ts b/src/utils/parser-comb.ts index f682068..3f171b8 100644 --- a/src/utils/parser-comb.ts +++ b/src/utils/parser-comb.ts @@ -1,83 +1,120 @@ -import { match } from './adt'; -import { Result, mapResult, chainResult } from './result'; - -export type ParseResult = Result<{ value: T, input: string }, { error: string, input: string }>; - -export type Parser = (input: string) => ParseResult; - -export const regex = (re: RegExp): Parser => input => { - if (input.length === 0) return Result.Err({ error: 'fuckedinput', input }) - const res = input.match(re) - if (!res) return Result.Err({ error: 'fucked', input }); - return Result.Ok({ value: res[0], input: input.replace(re, '') }); -} - -export const string = (str: string): Parser => input => { - if (input.length === 0) return Result.Err({ error: 'fuckedinput', input }) - if (!input.startsWith(str)) return Result.Err({ error: 'fuckedstring', input }) - return Result.Ok({ value: str, input: input.slice(str.length) }); -} - -export const or = ([parser, ...rest]: Array>): Parser => input => { - if (rest.length === 0) return parser(input); - const result = parser(input) - return match(result, { - Ok: () => result, - Err: (_) => or(rest)(input), - }); -} - -export const mapParseResult = (parser: Parser, fn: (_: { value: T, input: string }) => { value: R, input: string }): Parser => input => - mapResult(parser(input), fn) +import { match } from './adt' +import { Result, mapResult, chainResult } from './result' + +export type ParseResult = Result< + { value: T; input: string }, + { error: string; input: string } +> + +export type Parser = (input: string) => ParseResult + +export const regex = + (re: RegExp): Parser => + input => { + if (input.length === 0) return Result.Err({ error: 'fuckedinput', input }) + const res = input.match(re) + if (!res) return Result.Err({ error: 'fucked', input }) + return Result.Ok({ value: res[0], input: input.replace(re, '') }) + } + +export const string = + (str: string): Parser => + input => { + if (input.length === 0) return Result.Err({ error: 'fuckedinput', input }) + if (!input.startsWith(str)) + return Result.Err({ error: 'fuckedstring', input }) + return Result.Ok({ value: str, input: input.slice(str.length) }) + } + +export const or = + ([parser, ...rest]: Array>): Parser => + input => { + if (rest.length === 0) return parser(input) + const result = parser(input) + return match(result, { + Ok: () => result, + Err: _ => or(rest)(input), + }) + } + +export const mapParseResult = + ( + parser: Parser, + fn: (_: { value: T; input: string }) => { value: R; input: string }, + ): Parser => + input => + mapResult(parser(input), fn) export const map = (parser: Parser, fn: (_: T) => R): Parser => - mapParseResult(parser, ({ value, ...rest }) => ({ ...rest, value: fn(value) })); - -export const zip2 = (parserA: Parser, parserB: Parser): Parser => input => { - // TODO: refactor please. shit code - const resa: Result<{ value: A, input: string }, { error: string, input: string }> = parserA(input); - return chainResult(resa, ({ value: a, input: inputB }) => { - const res: Result<{ value: readonly [A, B], input: string }, { error: string, input: string }> = - map(parserB, (b) => [a, b] as const)(inputB) - return res - }) -} - -export const prefixed = (parserPrefix: Parser, parser: Parser): Parser => - map(zip2(parserPrefix, parser), ([_, a]) => a); - -export const suffixed = (parser: Parser, parserSuffix: Parser): Parser => - map(zip2(parser, parserSuffix), ([a, _]) => a); - -export const between = (prefix: Parser, parser: Parser, suffix: Parser): Parser => - suffixed(prefixed(prefix, parser), suffix) - -export const many0 = (parser: Parser): Parser> => originalInput => - match(parser(originalInput), { - Ok: ({ value, input }) => map(many0(parser), ls => [value, ...ls])(input), - Err: ({ input }) => Result.Ok({ value: [], input }), - }) - -export const many1 = (parser: Parser): Parser> => originalInput => - match(parser(originalInput), { - Ok: ({ value, input }) => map(many0(parser), ls => [value, ...ls])(input), - Err: err => Result.Err(err), - }) - -export const sepBy = (parser: Parser, sepP: Parser): Parser> => originalInput => - match(parser(originalInput), { - Ok: ({ value, input }) => map( - many0(prefixed(sepP, parser)), - ls => [value, ...ls] - )(input), - Err: _ => Result.Ok({ value: [], input: originalInput }), - }) - -export const optional = (parser: Parser): Parser => input => { - const result = parser(input) - return match(result, { - Ok: _ => result, - Err: _ => Result.Ok({ value: undefined, input }) - }) -} - + mapParseResult(parser, ({ value, ...rest }) => ({ + ...rest, + value: fn(value), + })) + +export const zip2 = + (parserA: Parser, parserB: Parser): Parser => + input => { + // TODO: refactor please. shit code + const resa: Result< + { value: A; input: string }, + { error: string; input: string } + > = parserA(input) + return chainResult(resa, ({ value: a, input: inputB }) => { + const res: Result< + { value: readonly [A, B]; input: string }, + { error: string; input: string } + > = map(parserB, b => [a, b] as const)(inputB) + return res + }) + } + +export const prefixed = ( + parserPrefix: Parser, + parser: Parser, +): Parser => map(zip2(parserPrefix, parser), ([_, a]) => a) + +export const suffixed = ( + parser: Parser, + parserSuffix: Parser, +): Parser => map(zip2(parser, parserSuffix), ([a, _]) => a) + +export const between = ( + prefix: Parser, + parser: Parser, + suffix: Parser, +): Parser => suffixed(prefixed(prefix, parser), suffix) + +export const many0 = + (parser: Parser): Parser> => + originalInput => + match(parser(originalInput), { + Ok: ({ value, input }) => map(many0(parser), ls => [value, ...ls])(input), + Err: ({ input }) => Result.Ok({ value: [], input }), + }) + +export const many1 = + (parser: Parser): Parser> => + originalInput => + match(parser(originalInput), { + Ok: ({ value, input }) => map(many0(parser), ls => [value, ...ls])(input), + Err: err => Result.Err(err), + }) + +export const sepBy = + (parser: Parser, sepP: Parser): Parser> => + originalInput => + match(parser(originalInput), { + Ok: ({ value, input }) => + map(many0(prefixed(sepP, parser)), ls => [value, ...ls])(input), + Err: _ => Result.Ok({ value: [], input: originalInput }), + }) + +export const optional = + (parser: Parser): Parser => + input => { + const result = parser(input) + return match(result, { + Ok: _ => result, + Err: _ => Result.Ok({ value: undefined, input }), + }) + } -- cgit v1.3.1