Skip to content

Commit

Permalink
feat(parse): add withID() xform, add doc strings
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Apr 19, 2020
1 parent e4eab03 commit e16426b
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 0 deletions.
6 changes: 6 additions & 0 deletions packages/parse/src/xform/collect.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { Parser, ScopeTransform } from "../api";
import { xform } from "../combinators/xform";

/**
* Collects results of all direct children into an array, then discards
* children. Also see {@link collect}.
*
* @param scope
*/
export const xfCollect: ScopeTransform<any> = (scope) => {
scope!.result = scope!.children!.map((c) => c.result);
scope!.children = null;
Expand Down
11 changes: 11 additions & 0 deletions packages/parse/src/xform/hoist.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
import { Parser, ScopeTransform } from "../api";
import { xform } from "../combinators/xform";

/**
* Moves the result of first child node to this node, then discards all
* children. Also see {@link hoist}.
*
* @param scope
*/
export const xfHoist: ScopeTransform<any> = (scope) => {
scope!.result = scope!.children![0].result;
scope!.children = null;
return scope;
};

/**
* Syntax sugar for `xform(parser, xfHoist)`.
*
* @param parser
*/
export const hoist = <T>(parser: Parser<T>) => xform(parser, xfHoist);
6 changes: 6 additions & 0 deletions packages/parse/src/xform/join.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ import type { Nullable } from "@thi.ng/api";
import type { Parser, ParseScope } from "../api";
import { xform } from "../combinators/xform";

/**
* Recursively joins non-null results of all children into a single
* string, then discards children. Also see {@link join}.
*
* @param scope
*/
export const xfJoin = <T>(scope: Nullable<ParseScope<T>>) => {
if (!scope || !scope.children) return null;
const res = [];
Expand Down
12 changes: 12 additions & 0 deletions packages/parse/src/xform/number.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
import { ScopeTransform } from "../api";
import { xfJoin } from "./join";

/**
* Higher order transform. First joins all children via {@link xfJoin},
* then parses resulting string into an integer with given `radix`.
*
* @param radix
*/
export const xfInt = (radix = 10): ScopeTransform<string> => (scope) => {
scope!.result = parseInt(xfJoin(scope)!.result, radix);
return scope;
};

/**
* First joins all children via {@link xfJoin}, then parses resulting
* string into a floating point value.
*
* @param scope
*/
export const xfFloat: ScopeTransform<string> = (scope) => {
scope!.result = parseFloat(xfJoin(scope)!.result);
return scope;
Expand Down
21 changes: 21 additions & 0 deletions packages/parse/src/xform/print.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@ import { Parser, ScopeTransform } from "../api";
import { xform } from "../combinators/xform";
import { indent } from "../utils";

/**
* Side effect only. Traverses current AST node and all children and
* prints each node's ID, result and reader state (if available). Also
* see {@link print}.
*
* @param scope
* @param ctx
* @param level
*/
export const xfPrint: ScopeTransform<any> = (scope, _, level = 0) => {
if (!scope) return;
const prefix = indent(level);
Expand All @@ -19,6 +28,18 @@ export const xfPrint: ScopeTransform<any> = (scope, _, level = 0) => {
/**
* Syntax sugar for `xform(parser, xfPrint)`.
*
* @example
* ```ts
* print(seq([lit("["), oneOrMore(ALPHA), lit("]")]))(defContext("[abc]"))
* // seq: null
* // lit: "["
* // repeat1: null
* // lit: "a"
* // lit: "b"
* // lit: "c"
* // lit: "]"
* ```
*
* @param parser
*/
export const print = <T>(parser: Parser<T>) => xform(parser, xfPrint);
15 changes: 15 additions & 0 deletions packages/parse/src/xform/with-id.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ScopeTransform, Parser } from "../api";
import { xform } from "../combinators/xform";

/**
* Assigns given `id` to AST node. E.g. used for re-labeling parser
* results defined by {@link defGrammar}.
*
* @param id
*/
export const xfID = (id: string): ScopeTransform<any> => (scope) => (
(scope!.id = id), scope
);

export const withID = <T>(id: string, parser: Parser<T>) =>
xform(parser, xfID(id));

0 comments on commit e16426b

Please sign in to comment.