Skip to content

Commit

Permalink
topLevelInitializer and initializer can be arrays now
Browse files Browse the repository at this point in the history
  • Loading branch information
hildjj committed Dec 11, 2023
1 parent 7e0475b commit 121273b
Show file tree
Hide file tree
Showing 13 changed files with 1,035 additions and 410 deletions.
2 changes: 1 addition & 1 deletion docs/js/benchmark-bundle.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/js/test-bundle.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/vendor/peggy/peggy.min.js

Large diffs are not rendered by default.

74 changes: 33 additions & 41 deletions lib/compiler/asts.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,27 @@

const visitor = require("./visitor");

/**
* Combine two things, each of which might be an array, into a single value,
* in the order [...a, ...b].
*
* @template T
* @param {T | T[] | undefined} a
* @param {T | T[] | undefined} b
* @returns {T | T[] | undefined}
*/
function combinePossibleArrays(a, b) {
if (a) {
if (!b) {
return a;
}
const aa = Array.isArray(a) ? a : [a];
const bb = Array.isArray(b) ? b : [b];
return aa.concat(bb);
}
return b;
}

// AST utilities.
const asts = {
findRule(ast, name) {
Expand Down Expand Up @@ -88,47 +109,18 @@ const asts = {
},

combine(asts) {
let combined = null;
for (const ast of asts) {
if (combined) {
// Note: Change topLevelInitializer and initializer to be an array in
// order to keep the location along with.
if (ast.topLevelInitializer) {
if (combined.topLevelInitializer) {
// Try this and see if it's better than the other way in practice.
const init
= ast.topLevelInitializer
+ "\n"
+ combined.topLevelInitializer;

// Move imports to the top
let imports = "";
let nonImports = "";
for (const line of init.split(/[\r\n]+/)) {
if (/^\s*import/.test(line)) {
imports += line;
} else {
nonImports += line;
}
}
combined.topLevelInitializer = imports + "\n" + nonImports;
} else {
combined.topLevelInitializer = ast.topLevelInitializer;
}
}
if (ast.initializer) {
if (combined.initializer) {
combined.initializer = ast.initializer + "\n" + combined.initializer;
} else {
combined.initializer = ast.initializer;
}
}
combined.rules = combined.rules.concat(ast.rules);
} else {
combined = ast;
}
}
return combined;
return asts.reduce((combined, ast) => {
combined.topLevelInitializer = combinePossibleArrays(
combined.topLevelInitializer,
ast.topLevelInitializer
);
combined.initializer = combinePossibleArrays(
combined.initializer,
ast.initializer
);
combined.rules = combined.rules.concat(ast.rules);
return combined;
});
},
};

Expand Down
2 changes: 2 additions & 0 deletions lib/compiler/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const generateJS = require("./passes/generate-js");
const inferenceMatchResult = require("./passes/inference-match-result");
const removeProxyRules = require("./passes/remove-proxy-rules");
const mergeCharacterClasses = require("./passes/merge-character-classes");
const moveImports = require("./passes/move-imports");
const reportDuplicateLabels = require("./passes/report-duplicate-labels");
const reportDuplicateRules = require("./passes/report-duplicate-rules");
const reportInfiniteRecursion = require("./passes/report-infinite-recursion");
Expand Down Expand Up @@ -61,6 +62,7 @@ const compiler = {
removeProxyRules,
mergeCharacterClasses,
inferenceMatchResult,
moveImports,
],
generate: [
generateBytecode,
Expand Down
16 changes: 14 additions & 2 deletions lib/compiler/passes/generate-js.js
Original file line number Diff line number Diff line change
Expand Up @@ -849,7 +849,13 @@ function generateJS(ast, options) {
const parts = [];

if (ast.topLevelInitializer) {
parts.push(ast2SourceNode(ast.topLevelInitializer));
if (Array.isArray(ast.topLevelInitializer)) {
for (const tli of ast.topLevelInitializer) {
parts.push(ast2SourceNode(tli));
}
} else {
parts.push(ast2SourceNode(ast.topLevelInitializer));
}
parts.push("");
}

Expand Down Expand Up @@ -1283,7 +1289,13 @@ function generateJS(ast, options) {
});

if (ast.initializer) {
parts.push(ast2SourceNode(ast.initializer));
if (Array.isArray(ast.initializer)) {
for (const init of ast.initializer) {
parts.push(ast2SourceNode(init));
}
} else {
parts.push(ast2SourceNode(ast.initializer));
}
parts.push("");
}

Expand Down
21 changes: 21 additions & 0 deletions lib/compiler/passes/move-imports.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @ts-check
"use strict";

/**
* @typedef {import("../../peg")} PEG
*/

/**
*
* @param {PEG.ast.Grammar} ast
*/
function moveImports(ast) {
if (Array.isArray(ast.topLevelInitializer)) {
ast.topLevelInitializer
= ast.topLevelInitializer.filter(tli => tli.imports).concat(
ast.topLevelInitializer.filter(tli => !tli.imports)
);
}
}

module.exports = moveImports;
16 changes: 14 additions & 2 deletions lib/compiler/visitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,23 @@ const visitor = {
const DEFAULT_FUNCTIONS = {
grammar(node, ...args) {
if (node.topLevelInitializer) {
visit(node.topLevelInitializer, ...args);
if (Array.isArray(node.topLevelInitializer)) {
for (const tli of node.topLevelInitializer) {
visit(tli, ...args);
}
} else {
visit(node.topLevelInitializer, ...args);
}
}

if (node.initializer) {
visit(node.initializer, ...args);
if (Array.isArray(node.initializer)) {
for (const init of node.initializer) {
visit(init, ...args);
}
} else {
visit(node.initializer, ...args);
}
}

node.rules.forEach(rule => visit(rule, ...args));
Expand Down
Loading

0 comments on commit 121273b

Please sign in to comment.