Skip to content

Commit

Permalink
(new-codegen) Use common code for matching literals, classes and any
Browse files Browse the repository at this point in the history
  • Loading branch information
Mingun committed Apr 27, 2019
1 parent 4608d9f commit 4561aee
Show file tree
Hide file tree
Showing 5 changed files with 302 additions and 892 deletions.
8 changes: 4 additions & 4 deletions lib/compiler/opcodes.js
Expand Up @@ -36,10 +36,10 @@ let opcodes = {

// Matching

MATCH_ANY: 17, // MATCH_ANY a, f, ...
MATCH_STRING: 18, // MATCH_STRING s, a, f, ...
MATCH_STRING_IC: 19, // MATCH_STRING_IC s, a, f, ...
MATCH_CLASS: 20, // MATCH_CLASS c, a, f, ...
MATCH_ANY: 17, // MATCH_ANY
MATCH_LITERAL: 18, // MATCH_LITERAL l
MATCH_LITERAL_IC: 19, // MATCH_LITERAL_IC l
MATCH_CLASS: 20, // MATCH_CLASS c
ACCEPT_N: 21, // ACCEPT_N n
ACCEPT_STRING: 22, // ACCEPT_STRING s
EXPECT: 23, // EXPECT e
Expand Down
49 changes: 20 additions & 29 deletions lib/compiler/passes/generate-bytecode.js
Expand Up @@ -153,37 +153,21 @@ let visitor = require("../visitor");
// Matching
// --------
//
// [17] MATCH_ANY a, f, ...
// [17] MATCH_ANY
//
// if (input.length > currPos) {
// interpret(ip + 3, ip + 3 + a);
// } else {
// interpret(ip + 3 + a, ip + 3 + a + f);
// }
// state.matchAny()
//
// [18] MATCH_STRING s, a, f, ...
// [18] MATCH_LITERAL l
//
// if (input.substr(currPos, literals[s].length) === literals[s]) {
// interpret(ip + 4, ip + 4 + a);
// } else {
// interpret(ip + 4 + a, ip + 4 + a + f);
// }
// state.matchLiteral(l)
//
// [19] MATCH_STRING_IC s, a, f, ...
// [19] MATCH_LITERAL_IC l
//
// if (input.substr(currPos, literals[s].length).toLowerCase() === literals[s]) {
// interpret(ip + 4, ip + 4 + a);
// } else {
// interpret(ip + 4 + a, ip + 4 + a + f);
// }
// state.matchLiteralIC(l)
//
// [20] MATCH_CLASS c, a, f, ...
// [20] MATCH_CLASS c
//
// if (classes[c].test(input.charAt(currPos))) {
// interpret(ip + 4, ip + 4 + a);
// } else {
// interpret(ip + 4 + a, ip + 4 + a + f);
// }
// state.matchClass(c)
//
// [21] ACCEPT_N n
//
Expand Down Expand Up @@ -302,6 +286,13 @@ function generateBytecode(ast) {
);
}

function buildTryCondition(match, commonCode, thenCode, elseCode) {
if (match > 0) { return thenCode; }
if (match < 0) { return elseCode; }

return commonCode;
}

function buildBreakCondition(match, condCode, n, thenCode, elseCode) {
thenCode = buildSequence(thenCode, [op.BREAK, n]);

Expand Down Expand Up @@ -947,11 +938,11 @@ function generateBytecode(ast) {
// save one |substr| call that would be needed if we used |ACCEPT_N|.
return buildSequence(
context.reportFailures ? [op.EXPECT, expectedIndex] : [],
buildCondition(
buildTryCondition(
match,
node.ignoreCase
? [op.MATCH_STRING_IC, stringIndex]
: [op.MATCH_STRING, stringIndex],
? [op.MATCH_LITERAL_IC, stringIndex]
: [op.MATCH_LITERAL, stringIndex],
node.ignoreCase
? [op.ACCEPT_N, node.value.length]
: [op.ACCEPT_STRING, stringIndex],
Expand All @@ -976,7 +967,7 @@ function generateBytecode(ast) {

return buildSequence(
context.reportFailures ? [op.EXPECT, expectedIndex] : [],
buildCondition(
buildTryCondition(
match,
[op.MATCH_CLASS, classIndex],
[op.ACCEPT_N, 1],
Expand All @@ -991,7 +982,7 @@ function generateBytecode(ast) {

return buildSequence(
context.reportFailures ? [op.EXPECT, expectedIndex] : [],
buildCondition(
buildTryCondition(
node.match|0,
[op.MATCH_ANY],
[op.ACCEPT_N, 1],
Expand Down
49 changes: 22 additions & 27 deletions lib/compiler/passes/generate-js.js
Expand Up @@ -427,38 +427,33 @@ function generateJS(ast, options) {
compileLoop();
break;

case op.MATCH_ANY: // MATCH_ANY a, f, ...
compileCondition("input.length > peg$state._offset", 0);
case op.MATCH_ANY: // MATCH_ANY
parts.push(resStack.push("peg$state.matchAny()"));
ip++;
break;

case op.MATCH_STRING: // MATCH_STRING s, a, f, ...
compileCondition(
ast.literals[bc[ip + 1]].length > 1
? "input.substr(peg$state._offset, "
+ ast.literals[bc[ip + 1]].length
+ ") === "
+ l(bc[ip + 1])
: "input.charCodeAt(peg$state._offset) === "
+ ast.literals[bc[ip + 1]].charCodeAt(0),
1
);
case op.MATCH_LITERAL: { // MATCH_LITERAL l
let str = ast.literals[bc[ip + 1]];
parts.push(resStack.push(
str.length > 1
? "peg$state.matchLiteral(" + l(bc[ip + 1]) + ")"
: "peg$state.matchChar(" + l(bc[ip + 1]) + ", " + str.charCodeAt(0) + ")"
));
ip += 2;
break;

case op.MATCH_STRING_IC: // MATCH_STRING_IC s, a, f, ...
compileCondition(
"input.substr(peg$state._offset, "
+ ast.literals[bc[ip + 1]].length
+ ").toLowerCase() === "
+ l(bc[ip + 1]),
1
);
}
case op.MATCH_LITERAL_IC: // MATCH_LITERAL_IC l
parts.push(resStack.push(
"peg$state.matchLiteralIC(" + l(bc[ip + 1]) + ")"
));
ip += 2;
break;

case op.MATCH_CLASS: // MATCH_CLASS c, a, f, ...
compileCondition(
r(bc[ip + 1]) + ".test(input.charAt(peg$state._offset))",
1
);
case op.MATCH_CLASS: // MATCH_CLASS c
parts.push(resStack.push(
"peg$state.matchClass(" + r(bc[ip + 1]) + ")"
));
ip += 2;
break;

case op.ACCEPT_N: // ACCEPT_N n
Expand Down

0 comments on commit 4561aee

Please sign in to comment.