Skip to content

Commit

Permalink
refactor(parse): update context, rename ops, remove arrays dep
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Apr 15, 2020
1 parent 151e50c commit a913c96
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 34 deletions.
1 change: 0 additions & 1 deletion packages/parse/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
},
"dependencies": {
"@thi.ng/api": "^6.10.0",
"@thi.ng/arrays": "^0.6.3",
"@thi.ng/checks": "^2.6.2",
"@thi.ng/errors": "^1.2.10"
},
Expand Down
9 changes: 6 additions & 3 deletions packages/parse/src/combinators/repeat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ export const repeat = <T>(
return ctx.end();
};

export const repeat0 = <T>(parser: Parser<T>, id = "repeat0", max?: number) =>
repeat(parser, id, 0, max);
export const zeroOrMore = <T>(
parser: Parser<T>,
id = "repeat0",
max?: number
) => repeat(parser, id, 0, max);

export const repeat1 = <T>(parser: Parser<T>, id = "repeat1", max?: number) =>
export const oneOrMore = <T>(parser: Parser<T>, id = "repeat1", max?: number) =>
repeat(parser, id, 1, max);
6 changes: 3 additions & 3 deletions packages/parse/src/combinators/xform.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { peek } from "@thi.ng/arrays";
import type { Parser, ScopeTransform } from "../api";

export const xform = <T>(
Expand All @@ -8,14 +7,15 @@ export const xform = <T>(
): Parser<T> => (ctx) => {
const res = parser(ctx);
if (res) {
const scope = peek(ctx.scope.children!);
const children = ctx.scope.children!;
const scope = children[children.length - 1];
const res = xf(scope, ctx, user);
if (res) {
if (scope.children && !scope.children.length) {
scope.children = null;
}
} else {
ctx.scope.children!.pop();
children.pop();
}
return true;
}
Expand Down
10 changes: 6 additions & 4 deletions packages/parse/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { alt } from "./combinators/alt";
import { maybe } from "./combinators/maybe";
import { repeat0, repeat1 } from "./combinators/repeat";
import { oneOrMore, zeroOrMore } from "./combinators/repeat";
import { seq } from "./combinators/seq";
import { xform } from "./combinators/xform";
import { lit } from "./prims/lit";
Expand All @@ -24,9 +24,11 @@ export const ALPHA_NUM = alt([ALPHA, DIGIT]);

export const SIGN = maybe(oneOf("-+"), "");

export const DIGITS_0 = repeat0(DIGIT);
export const DIGITS_1 = repeat1(DIGIT);
export const HEX_DIGITS_1 = repeat1(HEX_DIGIT);
export const DIGITS_0 = zeroOrMore(DIGIT);

export const DIGITS_1 = oneOrMore(DIGIT);

export const HEX_DIGITS_1 = oneOrMore(HEX_DIGIT);

const EXP = maybe(seq([maybe(oneOf("eE")), SIGN, DIGITS_1]));

Expand Down
44 changes: 23 additions & 21 deletions packages/parse/src/context.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { ParseScope, IReader } from "./api";
import { peek } from "@thi.ng/arrays";
import type { IReader, ParseScope } from "./api";
import { parseError } from "./error";
import { defStringReader } from "./string-reader";

Expand All @@ -14,64 +13,67 @@ interface ContextOpts {

export class ParseContext<T> {
protected _scopes: ParseScope<T>[];
protected _curr: ParseScope<T>;
protected _maxDepth: number;

constructor(public reader: IReader<T>, opts?: Partial<ContextOpts>) {
this._scopes = [
{
id: "root",
state: { p: 0, l: 1, c: 1 },
children: null,
result: null,
},
];
opts = { maxDepth: 32, ...opts };
this._maxDepth = opts.maxDepth!;
this._curr = {
id: "root",
state: { p: 0, l: 1, c: 1 },
children: null,
result: null,
};
this._scopes = [this._curr];
}

start(type: string) {
if (this._scopes.length >= this._maxDepth) {
parseError(this, `recursion limit reached ${this._maxDepth}`);
}
const curr = peek(this._scopes);
const scopes = this._scopes;
const scope: ParseScope<T> = {
id: type,
state: { ...curr.state },
state: { ...scopes[scopes.length - 1].state },
children: null,
result: null,
};
this._scopes.push(scope);
return scope;
scopes.push(scope);
return (this._curr = scope);
}

discard() {
this._scopes.pop()!;
const scopes = this._scopes;
scopes.pop();
this._curr = scopes[scopes.length - 1];
return false;
}

end() {
const child = this._scopes.pop()!;
const parent = peek(this._scopes);
const scopes = this._scopes;
const child = scopes.pop()!;
const parent = scopes[scopes.length - 1];
const cstate = child.state;
const pstate = parent.state;
// child.state = pstate;
child.state = { p: pstate.p, l: pstate.l, c: pstate.c };
parent.state = cstate;
const children = parent.children;
children ? children.push(child) : (parent.children = [child]);
this._curr = parent;
return true;
}

get scope() {
return peek(this._scopes);
return this._curr;
}

get state() {
return peek(this._scopes).state;
return this._curr.state;
}

get done() {
return peek(this._scopes).state.done;
return this._curr.state.done;
}
}

Expand Down
13 changes: 11 additions & 2 deletions packages/parse/test/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import { Fn2 } from "@thi.ng/api";
import * as assert from "assert";
import { alt, defContext, FLOAT, INT, oneOf, repeat0, WS, xform } from "../src";
import {
alt,
defContext,
FLOAT,
INT,
oneOf,
WS,
xform,
zeroOrMore,
} from "../src";

describe("parse", () => {
it("float", () => {
Expand Down Expand Up @@ -40,7 +49,7 @@ describe("parse", () => {
stack.push(ops[scope!.result](a, b));
return null;
});
const program = repeat0(alt([value, op, WS]));
const program = zeroOrMore(alt([value, op, WS]));
program(defContext("10 5 3 * + -2 * 10 /"));
assert.deepEqual(stack, [-5]);
});
Expand Down

0 comments on commit a913c96

Please sign in to comment.