summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jest.config.js2
-rw-r--r--package.json3
-rw-r--r--src/index.d.ts7
-rw-r--r--src/index.ts56
-rw-r--r--tests/basic.spec.d.ts0
-rw-r--r--tests/basic.spec.ts6
-rw-r--r--tsconfig.json3
-rw-r--r--yarn.lock5
8 files changed, 77 insertions, 5 deletions
diff --git a/jest.config.js b/jest.config.js
index 3e889da..01b5ff1 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -1,5 +1,5 @@
module.exports = {
- roots: ['<rootDir>/tests'],
+ roots: ['<rootDir>/tests', '<rootDir>/src'],
transform: {
'^.+\\.(ts|tsx)$': 'ts-jest'
},
diff --git a/package.json b/package.json
index f46bc29..9d62f1f 100644
--- a/package.json
+++ b/package.json
@@ -19,5 +19,8 @@
"rimraf": "^3.0.2",
"ts-jest": "^27.1.2",
"typescript": "^4.5.4"
+ },
+ "dependencies": {
+ "fp-ts": "^2.11.6"
}
}
diff --git a/src/index.d.ts b/src/index.d.ts
new file mode 100644
index 0000000..fdaab41
--- /dev/null
+++ b/src/index.d.ts
@@ -0,0 +1,7 @@
+import { Either } from 'fp-ts/Either';
+declare type ParserResult<T> = [T, string];
+declare type ParserError = [string, string];
+declare type Parser<T> = (input: string) => Either<ParserError, ParserResult<T>>;
+export declare const p_digit: Parser<string>;
+export declare const many0: <T>(p: Parser<T>) => Parser<T[]>;
+export {};
diff --git a/src/index.ts b/src/index.ts
index 71455c6..a9b3409 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1 +1,55 @@
-export const x: number = 200
+import { flow, identity, pipe } from 'fp-ts/function'
+import { Either, left, right, map, chain, mapLeft, fold, orElse } from 'fp-ts/Either'
+
+type char = string
+
+type ParserResult<T> = [T, string]
+type ParserError = [string, string]
+type Parser<T> = (input: string) => Either<ParserError, ParserResult<T>>
+
+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]),
+ )
+ ),
+ orElse(([_, inp]) => right([[] as T[], inp]))
+)
+
+export const many1 = <T>(parser: Parser<T>): Parser<Array<T>> => flow(
+ many0(parser),
+ chain(([res, inp]) =>
+ res.length > 0 ? right([res, inp]) : left([`many1 failed to parse at ${inp}`, inp]))
+)
+
+export const satify_char = (f: (c: char) => boolean): Parser<char> => (input: string) => {
+ const c = input.charAt(0)
+ if (f(c)) return right([c, input.slice(1)])
+ return left([`Expected to satisfy ${f}, got "${c}"`, input])
+};
+
+export const digit = satify_char(c => /^[0-9]$/g.test(c))
+
+export const integer: Parser<number> = flow(
+ many1(digit),
+ map(([ds, input]) => [parseInt(ds.join(''), 10), input])
+)
+
+export const or = <T>(parsers: Parser<T>[]): Parser<T> => {
+ const ppp = ([p, ...ps]: Parser<T>[]) => flow(
+ p,
+ orElse(([_, inp]) => or(ps)(inp))
+ )
+
+ return parsers.length > 0 ? ppp(parsers) : (inp: string) => left(['unable to match', inp])
+}
+
+export const space = satify_char(c => c === ' ')
+export const newline = satify_char(c => c === '\n')
+export const tab = satify_char(c => c === '\t')
+
+export const whitespace = or([space, newline, tab])
+
diff --git a/tests/basic.spec.d.ts b/tests/basic.spec.d.ts
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/basic.spec.d.ts
diff --git a/tests/basic.spec.ts b/tests/basic.spec.ts
index ed1a8c7..26a2edb 100644
--- a/tests/basic.spec.ts
+++ b/tests/basic.spec.ts
@@ -1,8 +1,10 @@
-import { x } from "../src";
+import {right} from 'fp-ts/Either'
+import { many0, digit, integer, whitespace } from '../src'
describe('Foobar', () => {
it ('should do shit', () => {
- expect(x).toBe(200)
+ expect(integer('12901')).toEqual(right([12901, '']))
+ expect(integer('12901asas')).toEqual(right([12901, 'asas']))
})
})
diff --git a/tsconfig.json b/tsconfig.json
index d205a4f..cc1f11b 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -7,7 +7,8 @@
"noImplicitAny": false,
"esModuleInterop": true,
"moduleResolution": "node",
+ "checkJs": false,
"outDir": "lib",
- "rootDir": "src"
+ "baseUrl": "."
}
}
diff --git a/yarn.lock b/yarn.lock
index 2379e48..e0a9cc7 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1226,6 +1226,11 @@ form-data@^3.0.0:
combined-stream "^1.0.8"
mime-types "^2.1.12"
+fp-ts@^2.11.6:
+ version "2.11.6"
+ resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-2.11.6.tgz#fa11c21bb235cfba0dfd4170f88adcd36e02ac9b"
+ integrity sha512-/EDgWhlWXenPvyax2UyKPhdHK+IkVFQZUggby41dCeWgE2F20Z3cx8eWikotwKicfKu7HvZ+tz3xN0vdOGrL6A==
+
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"