Skip to content

Commit

Permalink
Cleanup bytecode generator (pegjs/pegjs#450): Merge js.js into genera…
Browse files Browse the repository at this point in the history
…te-js.js
  • Loading branch information
Mingun committed May 20, 2021
1 parent e8557cc commit dcbe046
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 70 deletions.
54 changes: 0 additions & 54 deletions lib/compiler/js.js

This file was deleted.

79 changes: 63 additions & 16 deletions lib/compiler/passes/generate-js.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,57 @@
"use strict";

const asts = require("../asts");
const js = require("../js");
const op = require("../opcodes");
const VERSION = require("../../version");

function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); }

function stringEscape(s) {
// ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a string
// literal except for the closing quote character, backslash, carriage
// return, line separator, paragraph separator, and line feed. Any character
// may appear in the form of an escape sequence.
//
// For portability, we also escape all control and non-ASCII characters.
return s
.replace(/\\/g, "\\\\") // backslash
.replace(/"/g, "\\\"") // closing double quote
.replace(/\0/g, "\\0") // null
.replace(/\x08/g, "\\b") // backspace
.replace(/\t/g, "\\t") // horizontal tab
.replace(/\n/g, "\\n") // line feed
.replace(/\v/g, "\\v") // vertical tab
.replace(/\f/g, "\\f") // form feed
.replace(/\r/g, "\\r") // carriage return
.replace(/[\x00-\x0F]/g, ch => "\\x0" + hex(ch))
.replace(/[\x10-\x1F\x7F-\xFF]/g, ch => "\\x" + hex(ch))
.replace(/[\u0100-\u0FFF]/g, ch => "\\u0" + hex(ch))
.replace(/[\u1000-\uFFFF]/g, ch => "\\u" + hex(ch));
}

function regexpClassEscape(s) {
// Based on ECMA-262, 5th ed., 7.8.5 & 15.10.1.
//
// For portability, we also escape all control and non-ASCII characters.
return s
.replace(/\\/g, "\\\\") // backslash
.replace(/\//g, "\\/") // closing slash
.replace(/]/g, "\\]") // closing bracket
.replace(/\^/g, "\\^") // caret
.replace(/-/g, "\\-") // dash
.replace(/\0/g, "\\0") // null
.replace(/\x08/g, "\\b") // backspace
.replace(/\t/g, "\\t") // horizontal tab
.replace(/\n/g, "\\n") // line feed
.replace(/\v/g, "\\v") // vertical tab
.replace(/\f/g, "\\f") // form feed
.replace(/\r/g, "\\r") // carriage return
.replace(/[\x00-\x0F]/g, ch => "\\x0" + hex(ch))
.replace(/[\x10-\x1F\x7F-\xFF]/g, ch => "\\x" + hex(ch))
.replace(/[\u0100-\u0FFF]/g, ch => "\\u0" + hex(ch))
.replace(/[\u1000-\uFFFF]/g, ch => "\\u" + hex(ch));
}

// Generates parser JavaScript code.
function generateJS(ast, options) {
// These only indent non-empty lines to avoid trailing whitespace.
Expand All @@ -17,39 +64,39 @@ function generateJS(ast, options) {

function generateTables() {
function buildLiteral(literal) {
return "\"" + js.stringEscape(literal) + "\"";
return "\"" + stringEscape(literal) + "\"";
}

function buildRegexp(cls) {
return "/^["
+ (cls.inverted ? "^" : "")
+ cls.value.map(part =>
Array.isArray(part)
? js.regexpClassEscape(part[0])
? regexpClassEscape(part[0])
+ "-"
+ js.regexpClassEscape(part[1])
: js.regexpClassEscape(part)
+ regexpClassEscape(part[1])
: regexpClassEscape(part)
).join("")
+ "]/" + (cls.ignoreCase ? "i" : "");
}

function buildExpectation(e) {
switch (e.type) {
case "rule": {
return "peg$otherExpectation(\"" + js.stringEscape(e.value) + "\")";
return "peg$otherExpectation(\"" + stringEscape(e.value) + "\")";
}
case "literal": {
return "peg$literalExpectation(\""
+ js.stringEscape(e.value)
+ stringEscape(e.value)
+ "\", "
+ e.ignoreCase
+ ")";
}
case "class": {
const parts = e.value.map(part =>
Array.isArray(part)
? "[\"" + js.stringEscape(part[0]) + "\", \"" + js.stringEscape(part[1]) + "\"]"
: "\"" + js.stringEscape(part) + "\""
? "[\"" + stringEscape(part[0]) + "\", \"" + stringEscape(part[1]) + "\"]"
: "\"" + stringEscape(part) + "\""
).join(", ");

return "peg$classExpectation(["
Expand Down Expand Up @@ -512,12 +559,12 @@ function generateJS(ast, options) {
parts.push(" var " + stackVars.join(", ") + ";");

parts.push(indent2(generateRuleHeader(
"\"" + js.stringEscape(rule.name) + "\"",
"\"" + stringEscape(rule.name) + "\"",
asts.indexOfRule(ast, rule.name)
)));
parts.push(indent2(code));
parts.push(indent2(generateRuleFooter(
"\"" + js.stringEscape(rule.name) + "\"",
"\"" + stringEscape(rule.name) + "\"",
s(0)
)));

Expand Down Expand Up @@ -1040,7 +1087,7 @@ function generateJS(ast, options) {
dependencyVars.forEach(variable => {
parts.push("var " + variable
+ " = require(\""
+ js.stringEscape(options.dependencies[variable])
+ stringEscape(options.dependencies[variable])
+ "\");"
);
});
Expand Down Expand Up @@ -1070,7 +1117,7 @@ function generateJS(ast, options) {
dependencyVars.forEach(variable => {
parts.push("import " + variable
+ " from \""
+ js.stringEscape(options.dependencies[variable])
+ stringEscape(options.dependencies[variable])
+ "\";"
);
});
Expand All @@ -1092,7 +1139,7 @@ function generateJS(ast, options) {
const dependencyIds = dependencyVars.map(v => options.dependencies[v]);
const dependencies = "["
+ dependencyIds.map(
id => "\"" + js.stringEscape(id) + "\""
id => "\"" + stringEscape(id) + "\""
).join(", ")
+ "]";
const params = dependencyVars.join(", ");
Expand Down Expand Up @@ -1130,11 +1177,11 @@ function generateJS(ast, options) {
const dependencyIds = dependencyVars.map(v => options.dependencies[v]);
const dependencies = "["
+ dependencyIds.map(
id => "\"" + js.stringEscape(id) + "\""
id => "\"" + stringEscape(id) + "\""
).join(", ")
+ "]";
const requires = dependencyIds.map(
id => "require(\"" + js.stringEscape(id) + "\")"
id => "require(\"" + stringEscape(id) + "\")"
).join(", ");
const params = dependencyVars.join(", ");

Expand Down

0 comments on commit dcbe046

Please sign in to comment.