Skip to content

Commit

Permalink
update types
Browse files Browse the repository at this point in the history
  • Loading branch information
marihachi committed Jul 29, 2023
1 parent 5afdf63 commit 19b86a0
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 100 deletions.
106 changes: 53 additions & 53 deletions src/combinators.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,42 @@
import * as Api from './index.js';
import * as T from './index.js';

/**
* Create a new parser that matches the given string.
*
* @public
*/
export function str<T extends string>(value: T): Api.Parser<T>
export function str<U extends string>(value: U): T.Parser<U>
/**
* Create a new parser that matches the given regular expression.
*
* @public
*/
export function str(pattern: RegExp): Api.Parser<string>
export function str(value: string | RegExp): Api.Parser<string> {
export function str(pattern: RegExp): T.Parser<string>
export function str(value: string | RegExp): T.Parser<string> {
return (typeof value === 'string') ? strWithString(value) : strWithRegExp(value);
}

function strWithString<T extends string>(value: T): Api.Parser<T> {
return Api.parser((input, index, [], _state) => {
function strWithString<U extends string>(value: U): T.Parser<U> {
return T.parser((input, index, [], _state) => {
if ((input.length - index) < value.length) {
return Api.failure(index);
return T.failure(index);
}
if (input.slice(index, index + value.length) !== value) {
return Api.failure(index);
return T.failure(index);
}
return Api.success(index + value.length, value);
return T.success(index + value.length, value);
});
}

function strWithRegExp(pattern: RegExp): Api.Parser<string> {
function strWithRegExp(pattern: RegExp): T.Parser<string> {
const re = RegExp(`^(?:${pattern.source})`, pattern.flags);
return Api.parser((input, index, [], _state) => {
return T.parser((input, index, [], _state) => {
const text = input.slice(index);
const result = re.exec(text);
if (result == null) {
return Api.failure(index);
return T.failure(index);
}
return Api.success(index + result[0].length, result[0]);
return T.success(index + result[0].length, result[0]);
});
}

Expand All @@ -45,20 +45,20 @@ function strWithRegExp(pattern: RegExp): Api.Parser<string> {
*
* @public
*/
export function seq<T extends Api.Parser<any>[]>(parsers: [...T]): Api.Parser<Api.ResultTypes<[...T]>>
export function seq<U extends T.Parser<any>[]>(parsers: [...U]): T.Parser<T.ResultTypes<[...U]>>
/**
* Create a new parser that sequentially applies an array of parser.
*
* @public
* @param select The index of the data returned in the result.
* @param select - The index of the data returned in the result.
*/
export function seq<T extends Api.Parser<any>[], U extends number>(parsers: [...T], select: U): T[U]
export function seq(parsers: Api.Parser<any>[], select?: number) {
export function seq<U extends T.Parser<any>[], V extends number>(parsers: [...U], select: V): U[V]
export function seq(parsers: T.Parser<any>[], select?: number) {
return (select == null) ? seqAll(parsers) : seqSelect(parsers, select);
}

function seqAll<T extends Api.Parser<any>[]>(parsers: [...T]): Api.Parser<Api.ResultTypes<[...T]>> {
return Api.parser((input, index, children, state) => {
function seqAll<U extends T.Parser<any>[]>(parsers: [...U]): T.Parser<T.ResultTypes<[...U]>> {
return T.parser((input, index, children, state) => {
let result;
let latestIndex = index;
const accum = [];
Expand All @@ -70,11 +70,11 @@ function seqAll<T extends Api.Parser<any>[]>(parsers: [...T]): Api.Parser<Api.Re
latestIndex = result.index;
accum.push(result.value);
}
return Api.success(latestIndex, (accum as Api.ResultTypes<[...T]>));
return T.success(latestIndex, (accum as T.ResultTypes<[...U]>));
}, parsers);
}

function seqSelect<T extends Api.Parser<any>[], U extends number>(parsers: [...T], select: U): T[U] {
function seqSelect<U extends T.Parser<any>[], V extends number>(parsers: [...U], select: V): U[V] {
return seqAll(parsers).map(values => values[select]);
}

Expand All @@ -83,16 +83,16 @@ function seqSelect<T extends Api.Parser<any>[], U extends number>(parsers: [...T
*
* @public
*/
export function alt<T extends Api.Parser<unknown>[]>(parsers: [...T]): Api.Parser<Api.ResultTypes<T>[number]> {
return Api.parser((input, index, children, state) => {
export function alt<U extends T.Parser<unknown>[]>(parsers: [...U]): T.Parser<T.ResultTypes<U>[number]> {
return T.parser((input, index, children, state) => {
let result;
for (let i = 0; i < children.length; i++) {
result = children[i].exec(input, state, index) as Api.Result<Api.ResultTypes<T>[number]>;
result = children[i].exec(input, state, index) as T.Result<T.ResultTypes<U>[number]>;
if (result.success) {
return result;
}
}
return Api.failure(index);
return T.failure(index);
}, parsers);
}

Expand All @@ -101,9 +101,9 @@ export function alt<T extends Api.Parser<unknown>[]>(parsers: [...T]): Api.Parse
*
* @public
*/
export function succeeded<T>(value: T): Api.Parser<T> {
return Api.parser((_input, index, [], _state) => {
return Api.success(index, value);
export function succeeded<U>(value: U): T.Parser<U> {
return T.parser((_input, index, [], _state) => {
return T.success(index, value);
});
}

Expand All @@ -112,12 +112,12 @@ export function succeeded<T>(value: T): Api.Parser<T> {
*
* @public
*/
export function match<T>(parser: Api.Parser<T>): Api.Parser<T> {
return Api.parser((input, index, [child], state) => {
export function match<U>(parser: T.Parser<U>): T.Parser<U> {
return T.parser((input, index, [child], state) => {
const result = child.exec(input, state, index);
return result.success
? Api.success(index, result.value)
: Api.failure(index);
? T.success(index, result.value)
: T.failure(index);
}, [parser]);
}

Expand All @@ -126,12 +126,12 @@ export function match<T>(parser: Api.Parser<T>): Api.Parser<T> {
*
* @public
*/
export function notMatch(parser: Api.Parser<unknown>): Api.Parser<null> {
return Api.parser((input, index, [child], state) => {
export function notMatch(parser: T.Parser<unknown>): T.Parser<null> {
return T.parser((input, index, [child], state) => {
const result = child.exec(input, state, index);
return !result.success
? Api.success(index, null)
: Api.failure(index);
? T.success(index, null)
: T.failure(index);
}, [parser]);
}

Expand All @@ -140,11 +140,11 @@ export function notMatch(parser: Api.Parser<unknown>): Api.Parser<null> {
*
* @public
*/
export function where<T>(condition: (state: any) => boolean, parser: Api.Parser<T>): Api.Parser<T> {
return Api.parser((input, index, [child], state) => {
export function where<U>(condition: (state: any) => boolean, parser: T.Parser<U>): T.Parser<U> {
return T.parser((input, index, [child], state) => {
return condition(state)
? child.exec(input, state, index)
: Api.failure(index);
: T.failure(index);
}, [parser]);
}

Expand All @@ -164,52 +164,52 @@ export const newline = alt([crlf, cr, lf]);
*
* @public
*/
export const sof = Api.parser((_input, index, [], _state) => {
export const sof = T.parser((_input, index, [], _state) => {
return index === 0
? Api.success(index, null)
: Api.failure(index);
? T.success(index, null)
: T.failure(index);
});

/**
* Match the end of the input string.
*
* @public
*/
export const eof = Api.parser((input, index, [], _state) => {
export const eof = T.parser((input, index, [], _state) => {
return index >= input.length
? Api.success(index, null)
: Api.failure(index);
? T.success(index, null)
: T.failure(index);
});

/**
* any char
*
* @public
*/
export const char = Api.parser((input, index, [], _state) => {
export const char = T.parser((input, index, [], _state) => {
if ((input.length - index) < 1) {
return Api.failure(index);
return T.failure(index);
}
const value = input.charAt(index);
return Api.success(index + 1, value);
return T.success(index + 1, value);
});

/**
* Match lineBegin
*
* @public
*/
export const lineBegin = Api.parser((input, index, [], state) => {
export const lineBegin = T.parser((input, index, [], state) => {
if (sof.exec(input, state, index).success) {
return Api.success(index, null);
return T.success(index, null);
}
if (cr.exec(input, state, index - 1).success) {
return Api.success(index, null);
return T.success(index, null);
}
if (lf.exec(input, state, index - 1).success) {
return Api.success(index, null);
return T.success(index, null);
}
return Api.failure(index);
return T.failure(index);
});

/**
Expand Down
10 changes: 5 additions & 5 deletions src/language.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import * as Api from './index.js';
import * as T from './index.js';

/**
* Create a language
*
* @public
*/
export function language<T>(syntaxes: { [K in keyof T]: (r: Record<string, Api.Parser<any>>) => T[K] }): T {
export function language<U>(syntaxes: { [K in keyof U]: (r: Record<string, T.Parser<any>>) => U[K] }): U {
// TODO: 関数の型宣言をいい感じにしたい
const rules: Record<string, Api.Parser<any>> = {};
const rules: Record<string, T.Parser<any>> = {};
for (const key of Object.keys(syntaxes)) {
rules[key] = Api.lazy(() => {
rules[key] = T.lazy(() => {
const parser = (syntaxes as any)[key](rules);
if (parser == null || !(parser instanceof Api.Parser)) {
if (parser == null || !(parser instanceof T.Parser)) {
throw new Error('syntax must return a Parser.');
}
parser.name = key;
Expand Down
Loading

0 comments on commit 19b86a0

Please sign in to comment.