Skip to content
Merged
5 changes: 5 additions & 0 deletions packages/parse/src/all.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export { default as bootPeg } from './boot-peg.js';
export { default as bootPegAst } from './boot-pegast.js';
export { default as makePeg } from './quasi-peg.js';
export { default as makeJSON } from './quasi-json.js';
export { default as makeJustin } from './quasi-justin.js';
8 changes: 5 additions & 3 deletions packages/parse/src/boot-peg.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,9 @@ ${self.template.raw.reduce((prior, r, i) => {
}, '')}
-------
${failStr}`);
console.error(`Syntax error ${tokStr}`);
const err = Error(`Syntax: cannot parse ${tokStr}`);
err.stack = undefined;
throw err;
};

/**
Expand Down Expand Up @@ -690,7 +692,7 @@ pos = ${posSrc};`;
wm.set(template, quasiRest);
}
if (typeof quasiRest !== 'function') {
console.error(`${typeof quasiRest}: ${quasiRest}`);
return quasiRest;
}
return quasiRest(...subs);
};
Expand Down Expand Up @@ -771,7 +773,7 @@ pos = ${posSrc};`;
/**
* @template X
* @param {ParserOptions} options
* @returns {IPegTag<IParserTag<X>>}
* @returns {IPegTag<IParserTag<X, any>>}
*/
const makeExtensionTag = (options = {}) => {
/**
Expand Down
21 changes: 20 additions & 1 deletion packages/parse/src/main.js
Original file line number Diff line number Diff line change
@@ -1 +1,20 @@
export { default as bootPeg } from './boot-peg.js';
import { bootPeg, bootPegAst, makePeg, makeJSON, makeJustin } from './all.js';

export { bootPeg };

// The currently-supported parse tags.

/**
* Parser template tag that creates new parser template tags from PEGs.
*/
export const peg = bootPeg(makePeg, bootPegAst);

/**
* JSON parser template tag.
*/
export const json = makeJSON(peg);

/**
* Justin parser template tag.
*/
export const justin = makeJustin(peg.extends(json));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok... I got this to work in the case of:

justin`make(BLD, BigInt(100))`

My first attempt was:

justin`make(BLD, 100n)`

The diagnostic was pretty misleading: quasiRest is not a function.

Copy link
Member Author

@michaelfig michaelfig Mar 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed this error. Now it returns the diagnostic I was expecting:

justin`make(BLD, 100n)`
-------template--------
"make(BLD, 100n)"

-------
looking for digit, frac, exp, _WSN
Syntax error at 13 "n" #0:13

and I added support for bigint literals, so now you should get:

[
  'call',
  [ 'use', 'make', _pegPosition: '"m" #0:0' ],
  [
    [ 'use', 'BLD', _pegPosition: '"B" #0:5' ],
    [ 'data', 100n, _pegPosition: '"1" #0:10' ],
    _pegPosition: '"(" #0:4'
  ],
  _pegPosition: '"m" #0:0'
]

2 changes: 1 addition & 1 deletion packages/parse/src/peg.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ interface ParserOptions {
debug?: boolean;
}

interface IParserTag<T = any, U = any> {
interface IParserTag<T = any, U = { holes: any[]; ast: any }> {
(template: TemplateStringsArray, ...args: T[]): U;
options(opts: Partial<ParserOptions>): IParserTag<T, U>;
parserCreator: PegParserCreator;
Expand Down
13 changes: 7 additions & 6 deletions packages/parse/src/quasi-json.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const makeJSON = peg => {
const { FAIL, HOLE, SKIP } = peg;
return peg`
# to be overridden or inherited
start <- _WS assignExpr _EOF ${v => () => v};
start <- _WS assignExpr _EOF ${ast => (...holes) => ({ ast, holes })};

# to be extended
primaryExpr <- dataStructure;
Expand Down Expand Up @@ -116,15 +116,16 @@ hex <- digit / [a-fA-F];

NUMBER <- < int frac? exp? > _WSN;

int <- [1-9] digit+
int <- [1-9] digits
/ digit
/ MINUS digit
/ MINUS [1-9] digit+;
/ MINUS [1-9] digits
/ MINUS digit;

digit <- [0-9];
digits <- digit*;

frac <- '.' digit+;
exp <- [Ee] [+\-]? digit+;
frac <- '.' digits;
exp <- [Ee] [+\-]? digits;

# _WSN is whitespace or a non-ident character.
_WSN <- ~[$A-Za-z_] _WS ${_ => SKIP};
Expand Down
35 changes: 25 additions & 10 deletions packages/parse/src/quasi-justin.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
// * multi-line strings (via template literals).
// * undefined.
// * includes all floating point values: NaN, Infinity, -Infinity
// * will include BigInt once available.
// * includes BigInt literals: 123n
// * numbers and bigints can have optional underscores: 1_000_000n

// Justin also includes most pure JavaScript expressions. Justin does not
// include function expressions or variable or function
Expand All @@ -22,9 +23,9 @@
// See https://github.com/endojs/Jessie/blob/main/README.md
// for documentation of the Jessie grammar.

// Justin is defined to be extended into the Chainmail grammar, to
// provide its expression language in a JS-like style. Chainmail
// expressions need to be pure and should be terminating.
// Justin is also intended to be extended into the Chainmail grammar, to provide
// its expression language in a JS-like style. Chainmail expressions need to be
// pure and should be terminating.

/// <reference path="./peg.d.ts"/>

Expand Down Expand Up @@ -70,7 +71,7 @@ const makeJustin = peg => {
const { SKIP } = peg;
return peg`
# to be overridden or inherited
start <- _WS assignExpr _EOF ${v => () => v};
start <- _WS assignExpr _EOF ${ast => (...holes) => ({ ast, holes })};

# A.1 Lexical Grammar

Expand All @@ -82,6 +83,16 @@ const makeJustin = peg => {
RIGHT_PAREN <- ")" _WS;
STARSTAR <- "**" _WS;

# Allow optional underscore digit separators.
digits <- super.digit ** ("_"?);
NUMBER <- super.NUMBER ${ns => ns.replaceAll('_', '')};

# BigInts are not supported in JSON, but they are in Justin.
bigintLiteral <- < int > "n" _WSN ${ns => [
'data',
BigInt(ns.replaceAll('_', '')),
]};

# Define Javascript-style comments.
_WS <- super._WS (EOL_COMMENT / MULTILINE_COMMENT)? ${_ => SKIP};
EOL_COMMENT <- "//" (~[\n\r] .)* _WS;
Expand Down Expand Up @@ -144,11 +155,14 @@ const makeJustin = peg => {
/ "interface" / "private" / "public") _WSN;

# Quasiliterals aka template literals
QUASI_CHAR <- "\\" . / ~"\`" .;
QUASI_ALL <- "\`" < (~"\${" QUASI_CHAR)* > "\`" _WS;
QUASI_HEAD <- "\`" < (~"\${" QUASI_CHAR)* > "\${" _WS;
QUASI_MID <- "}" < (~"\${" QUASI_CHAR)* > "\${" _WS;
QUASI_TAIL <- "}" < (~"\${" QUASI_CHAR)* > "\`" _WS;
QCHAR <- "\\" . / ~QQUOTE .;
QQUOTE <- "\`";
QHOLE <- "\${";
QHOLE_END <- "}";
QUASI_ALL <- QQUOTE < (~QHOLE QCHAR)* > QQUOTE _WS;
QUASI_HEAD <- QQUOTE < (~QHOLE QCHAR)* > QHOLE _WS;
QUASI_MID <- QHOLE_END < (~QHOLE QCHAR)* > QHOLE _WS;
QUASI_TAIL <- QHOLE_END < (~QHOLE QCHAR)* > QQUOTE _WS;


# A.2 Expressions
Expand All @@ -158,6 +172,7 @@ const makeJustin = peg => {

dataStructure <-
undefined
/ bigintLiteral
/ super.dataStructure;

# Optional trailing commas.
Expand Down
48 changes: 0 additions & 48 deletions packages/parse/src/tag-string.js

This file was deleted.

Loading