From 20480cd42bbbe1685b9470063248ed5fc1f2506b Mon Sep 17 00:00:00 2001 From: Akshay Nair Date: Fri, 7 Jan 2022 12:29:36 +0530 Subject: refactor: minor changes --- default.nix | 12 +++++++++ src/index.ts | 26 +++++++++++++------- src/parser.ts | 78 +++++++++++++++++++++++++++-------------------------------- src/utils.ts | 4 +++ 4 files changed, 68 insertions(+), 52 deletions(-) create mode 100644 default.nix create mode 100644 src/utils.ts diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..7b1a6c7 --- /dev/null +++ b/default.nix @@ -0,0 +1,12 @@ +{ pkgs ? import { } }: +with pkgs; +mkShell rec { + buildInputs = [ + nodejs-16_x + yarn + efm-langserver + nodePackages.vls + nodePackages.prettier + nodePackages.typescript-language-server + ]; +} diff --git a/src/index.ts b/src/index.ts index 582f9be..95a5411 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,16 @@ import { constant, flow, identity, pipe } from 'fp-ts/function' -import { andThen, delimited, mapTo, optional, pair, symbol } from './parser' +import { + andThen, + delimited, + digit, + integer, + many1, + mapTo, + optional, + or, + 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,15 +38,12 @@ type Expr = | { tag: 'Truthy' } | { tag: 'Falsey' } -export const expressionP = symbol('fuck') +export const expressionP = or([ + symbol('fuck'), + mapTo(many1(digit), (j) => j.join('')), +]) -export const parser = pair( - pair( - optional(start), - expressionP, - ), - optional(end), -) +export const parser = pair(pair(optional(start), expressionP), optional(end)) /* 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 = (parser: Parser): Parser> => flow( parser, chain(([a, nextInput]) => - pipe( - nextInput, - many0(parser), - map(([ls, inp]): ParserResult => [[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 = (parser: Parser): Parser> => @@ -37,21 +40,12 @@ export const many1 = (parser: Parser): Parser> => ) export const prefixed = (a: Parser, b: Parser): Parser => - flow( - a, - chain(([_, inp]) => b(inp)) - ) + flow(a, chain(flow(snd, b))) export const suffixed = (a: Parser, b: Parser): Parser => 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 = ( @@ -72,22 +66,22 @@ export const digit = satifyChar((c) => /^[0-9]$/g.test(c)) export const integer: Parser = flow( many1(digit), - map(([ds, input]) => [parseInt(ds.join(''), 10), input]) + map(mapFst((ds) => parseInt(ds.join(''), 10))) ) export const or = (parsers: Parser[]): Parser => { - const ppp = ([p, ...ps]: Parser[]) => + const run = ([p, ...ps]: Parser[]) => 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 => satifyChar((c) => c === ch) +export const matchChar = (ch: char): Parser => satifyChar(eq(ch)) export const space = matchChar(' ') export const newline = matchChar('\n') @@ -102,11 +96,7 @@ export const matchString = (s: string): Parser => : 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 => delimited(whitespaces0, matchString(s), whitespaces0) export const mapTo = (p: Parser, f: (p: I) => R): Parser => - flow( - p, - map(([v, inp]) => [f(v), inp]) - ) + flow(p, map(mapFst(f))) -export const andThen = (f: (p: I) => Parser) => (p: Parser): Parser => - flow( - p, - chain(([v, inp]) => f(v)(inp)), - ) +export const andThen = + (f: (p: I) => Parser) => + (p: Parser): Parser => + flow( + p, + chain(([v, inp]) => f(v)(inp)) + ) export const optional = (p: Parser): Parser> => 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: Parser, b: Parser): Parser<[A, B]> => pipe( - a, - andThen(ra => mapTo(b, rb => [ra, rb])) -) - +export const pair = (a: Parser, b: Parser): Parser<[A, B]> => + pipe( + a, + andThen((ra) => mapTo(b, (rb) => [ra, rb])) + ) diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..e7392bf --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,4 @@ +export const eq = + (a: T) => + (b: T): boolean => + a === b -- cgit v1.3.1