diff options
| author | Akshay Nair <phenax5@gmail.com> | 2023-08-11 21:40:54 +0530 |
|---|---|---|
| committer | Akshay Nair <phenax5@gmail.com> | 2023-08-11 21:50:20 +0530 |
| commit | 845d503bb16cb5046a4fec6d046b7b527a080187 (patch) | |
| tree | a9f8fdf4510ad4d61e8d105065be9071946e2bdf /src/utils | |
| parent | 5a9942fde65787b35d4eb8e3441af6fe68819612 (diff) | |
| download | css-everything-845d503bb16cb5046a4fec6d046b7b527a080187.tar.gz css-everything-845d503bb16cb5046a4fec6d046b7b527a080187.zip | |
chore: adds prettier
Diffstat (limited to '')
| -rw-r--r-- | src/utils/adt.ts | 17 | ||||
| -rw-r--r-- | src/utils/parser-comb.ts | 171 | ||||
| -rw-r--r-- | src/utils/result.ts | 18 |
3 files changed, 125 insertions, 81 deletions
diff --git a/src/utils/adt.ts b/src/utils/adt.ts index 78ab667..45d9e50 100644 --- a/src/utils/adt.ts +++ b/src/utils/adt.ts @@ -1,14 +1,18 @@ type TagValue<T, N> = T extends Tag<N, infer V> ? V : never -export const match = - <R, T extends Tag<string, any>>(tag: T, pattern: { +export const match = <R, T extends Tag<string, any>>( + tag: T, + pattern: { [key in T['tag'] | '_']?: (v: TagValue<T, key>) => R - }): R => ((pattern as any)[tag.tag] || (pattern._ as any))(tag.value) + }, +): R => ((pattern as any)[tag.tag] || (pattern._ as any))(tag.value) -export const matchString = - <R, T extends string = string>(key: T, pattern: { +export const matchString = <R, T extends string = string>( + key: T, + pattern: { [key in T | '_']?: (key: key) => R - }): R => ((pattern as any)[key] || (pattern._ as any))(key) + }, +): R => ((pattern as any)[key] || (pattern._ as any))(key) type Tag<N, V> = { tag: N; value: V } export type Enum<T> = { [N in keyof T]: Tag<N, T[N]> }[keyof T] @@ -26,4 +30,3 @@ export const constructors = <T extends Tag<string, any>>(): { }, }, ) as any - 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'; +import { match } from './adt' +import { Result, mapResult, chainResult } from './result' -export type ParseResult<T> = Result<{ value: T, input: string }, { error: string, input: string }>; +export type ParseResult<T> = Result< + { value: T; input: string }, + { error: string; input: string } +> -export type Parser<T> = (input: string) => ParseResult<T>; +export type Parser<T> = (input: string) => ParseResult<T> -export const regex = (re: RegExp): Parser<string> => 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 regex = + (re: RegExp): Parser<string> => + 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<string> => 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 string = + (str: string): Parser<string> => + 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 = <T>([parser, ...rest]: Array<Parser<T>>): Parser<T> => input => { - if (rest.length === 0) return parser(input); - const result = parser(input) - return match(result, { - Ok: () => result, - Err: (_) => or(rest)(input), - }); -} +export const or = + <T>([parser, ...rest]: Array<Parser<T>>): Parser<T> => + input => { + if (rest.length === 0) return parser(input) + const result = parser(input) + return match(result, { + Ok: () => result, + Err: _ => or(rest)(input), + }) + } -export const mapParseResult = <T, R>(parser: Parser<T>, fn: (_: { value: T, input: string }) => { value: R, input: string }): Parser<R> => input => - mapResult(parser(input), fn) +export const mapParseResult = + <T, R>( + parser: Parser<T>, + fn: (_: { value: T; input: string }) => { value: R; input: string }, + ): Parser<R> => + input => + mapResult(parser(input), fn) export const map = <T, R>(parser: Parser<T>, fn: (_: T) => R): Parser<R> => - mapParseResult(parser, ({ value, ...rest }) => ({ ...rest, value: fn(value) })); + mapParseResult(parser, ({ value, ...rest }) => ({ + ...rest, + value: fn(value), + })) -export const zip2 = <A, B>(parserA: Parser<A>, parserB: Parser<B>): Parser<readonly [A, B]> => 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 zip2 = + <A, B>(parserA: Parser<A>, parserB: Parser<B>): Parser<readonly [A, B]> => + 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 = <A>(parserPrefix: Parser<any>, parser: Parser<A>): Parser<A> => - map(zip2(parserPrefix, parser), ([_, a]) => a); +export const prefixed = <A>( + parserPrefix: Parser<any>, + parser: Parser<A>, +): Parser<A> => map(zip2(parserPrefix, parser), ([_, a]) => a) -export const suffixed = <A>(parser: Parser<A>, parserSuffix: Parser<any>): Parser<A> => - map(zip2(parser, parserSuffix), ([a, _]) => a); +export const suffixed = <A>( + parser: Parser<A>, + parserSuffix: Parser<any>, +): Parser<A> => map(zip2(parser, parserSuffix), ([a, _]) => a) -export const between = <A>(prefix: Parser<any>, parser: Parser<A>, suffix: Parser<any>): Parser<A> => - suffixed(prefixed(prefix, parser), suffix) +export const between = <A>( + prefix: Parser<any>, + parser: Parser<A>, + suffix: Parser<any>, +): Parser<A> => suffixed(prefixed(prefix, parser), suffix) -export const many0 = <A>(parser: Parser<A>): Parser<Array<A>> => originalInput => - match(parser(originalInput), { - Ok: ({ value, input }) => map(many0(parser), ls => [value, ...ls])(input), - Err: ({ input }) => Result.Ok({ value: [], input }), - }) +export const many0 = + <A>(parser: Parser<A>): Parser<Array<A>> => + originalInput => + match(parser(originalInput), { + Ok: ({ value, input }) => map(many0(parser), ls => [value, ...ls])(input), + Err: ({ input }) => Result.Ok({ value: [], input }), + }) -export const many1 = <A>(parser: Parser<A>): Parser<Array<A>> => originalInput => - match(parser(originalInput), { - Ok: ({ value, input }) => map(many0(parser), ls => [value, ...ls])(input), - Err: err => Result.Err(err), - }) +export const many1 = + <A>(parser: Parser<A>): Parser<Array<A>> => + originalInput => + match(parser(originalInput), { + Ok: ({ value, input }) => map(many0(parser), ls => [value, ...ls])(input), + Err: err => Result.Err(err), + }) -export const sepBy = <A>(parser: Parser<A>, sepP: Parser<any>): Parser<Array<A>> => 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 = <A>(parser: Parser<A>): Parser<undefined | A> => input => { - const result = parser(input) - return match(result, { - Ok: _ => result, - Err: _ => Result.Ok({ value: undefined, input }) - }) -} +export const sepBy = + <A>(parser: Parser<A>, sepP: Parser<any>): Parser<Array<A>> => + 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 = + <A>(parser: Parser<A>): Parser<undefined | A> => + input => { + const result = parser(input) + return match(result, { + Ok: _ => result, + Err: _ => Result.Ok({ value: undefined, input }), + }) + } diff --git a/src/utils/result.ts b/src/utils/result.ts index c0120b8..39a7fe6 100644 --- a/src/utils/result.ts +++ b/src/utils/result.ts @@ -1,14 +1,18 @@ -import { Enum, constructors, match } from "./adt"; +import { Enum, constructors, match } from './adt' -export type Result<V, E> = Enum<{ Ok: V, Err: E }> +export type Result<V, E> = Enum<{ Ok: V; Err: E }> export const Result = constructors<Result<any, any>>() -export const mapResult = <A, B, E>(res: Result<A, E>, fn: (_: A) => B): Result<B, E> => - chainResult(res, a => Result.Ok(fn(a))) +export const mapResult = <A, B, E>( + res: Result<A, E>, + fn: (_: A) => B, +): Result<B, E> => chainResult(res, a => Result.Ok(fn(a))) -export const chainResult = <A, B, E>(res: Result<A, E>, fn: (_: A) => Result<B, E>): Result<B, E> => +export const chainResult = <A, B, E>( + res: Result<A, E>, + fn: (_: A) => Result<B, E>, +): Result<B, E> => match(res, { Ok: a => fn(a), Err: e => Result.Err(e), - }); - + }) |
