* Remove stack manipulations from FAIL opcode and rename FAIL to EXPECT * Always save the expected values regardless of the match result of expression * Remove unnecessary check for match result in the `named` node * Collect and process expectations from predicates
This commit is contained in:
parent
1b20aa5427
commit
669f782a5f
|
@ -34,7 +34,7 @@ const opcodes = {
|
|||
MATCH_REGEXP: 20, // MATCH_REGEXP r, a, f, ...
|
||||
ACCEPT_N: 21, // ACCEPT_N n
|
||||
ACCEPT_STRING: 22, // ACCEPT_STRING s
|
||||
FAIL: 23, // FAIL e
|
||||
EXPECT: 23, // EXPECT e
|
||||
|
||||
// Calls
|
||||
|
||||
|
@ -49,7 +49,10 @@ const opcodes = {
|
|||
// Failure Reporting
|
||||
|
||||
SILENT_FAILS_ON: 28, // SILENT_FAILS_ON
|
||||
SILENT_FAILS_OFF: 29 // SILENT_FAILS_OFF
|
||||
SILENT_FAILS_OFF: 29, // SILENT_FAILS_OFF
|
||||
|
||||
EXPECT_NS_BEGIN: 38, // EXPECT_NS_BEGIN
|
||||
EXPECT_NS_END: 39 // EXPECT_NS_END invert
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -148,10 +148,9 @@ const visitor = require( "../visitor" );
|
|||
// stack.push(consts[s]);
|
||||
// currPos += consts[s].length;
|
||||
//
|
||||
// [23] FAIL e
|
||||
// [23] EXPECT e
|
||||
//
|
||||
// stack.push(FAILED);
|
||||
// fail(consts[e]);
|
||||
// expect(consts[e]);
|
||||
//
|
||||
// Calls
|
||||
// -----
|
||||
|
@ -187,6 +186,20 @@ const visitor = require( "../visitor" );
|
|||
// [29] SILENT_FAILS_OFF
|
||||
//
|
||||
// silentFails--;
|
||||
//
|
||||
// [38] EXPECT_NS_BEGIN
|
||||
//
|
||||
// expected.push({ pos: curPos, variants: [] });
|
||||
//
|
||||
// [39] EXPECT_NS_END invert
|
||||
//
|
||||
// value = expected.pop();
|
||||
// if (value.pos === expected.top().pos) {
|
||||
// if (invert) {
|
||||
// value.variants.forEach(e => { e.not = !e.not; });
|
||||
// }
|
||||
// expected.top().variants.pushAll(value.variants);
|
||||
// }
|
||||
function generateBytecode( ast ) {
|
||||
|
||||
const consts = [];
|
||||
|
@ -252,13 +265,13 @@ function generateBytecode( ast ) {
|
|||
|
||||
return buildSequence(
|
||||
[ op.PUSH_CURR_POS ],
|
||||
[ op.SILENT_FAILS_ON ],
|
||||
[ op.EXPECT_NS_BEGIN ],
|
||||
generate( expression, {
|
||||
sp: context.sp + 1,
|
||||
env: cloneEnv( context.env ),
|
||||
action: null
|
||||
} ),
|
||||
[ op.SILENT_FAILS_OFF ],
|
||||
[ op.EXPECT_NS_END, negative ? 1 : 0 ],
|
||||
buildCondition(
|
||||
[ negative ? op.IF_ERROR : op.IF_NOT_ERROR ],
|
||||
buildSequence(
|
||||
|
@ -325,15 +338,11 @@ function generateBytecode( ast ) {
|
|||
`peg$otherExpectation("${ js.stringEscape( node.name ) }")`
|
||||
);
|
||||
|
||||
// The code generated below is slightly suboptimal because |FAIL| pushes
|
||||
// to the stack, so we need to stick a |POP| in front of it. We lack a
|
||||
// dedicated instruction that would just report the failure and not touch
|
||||
// the stack.
|
||||
return buildSequence(
|
||||
[ op.EXPECT, nameIndex ],
|
||||
[ op.SILENT_FAILS_ON ],
|
||||
generate( node.expression, context ),
|
||||
[ op.SILENT_FAILS_OFF ],
|
||||
buildCondition( [ op.IF_ERROR ], [ op.FAIL, nameIndex ], [] )
|
||||
[ op.SILENT_FAILS_OFF ]
|
||||
);
|
||||
|
||||
},
|
||||
|
@ -600,14 +609,17 @@ function generateBytecode( ast ) {
|
|||
// For case-sensitive strings the value must match the beginning of the
|
||||
// remaining input exactly. As a result, we can use |ACCEPT_STRING| and
|
||||
// save one |substr| call that would be needed if we used |ACCEPT_N|.
|
||||
return buildCondition(
|
||||
node.ignoreCase
|
||||
? [ op.MATCH_STRING_IC, stringIndex ]
|
||||
: [ op.MATCH_STRING, stringIndex ],
|
||||
node.ignoreCase
|
||||
? [ op.ACCEPT_N, node.value.length ]
|
||||
: [ op.ACCEPT_STRING, stringIndex ],
|
||||
[ op.FAIL, expectedIndex ]
|
||||
return buildSequence(
|
||||
[ op.EXPECT, expectedIndex ],
|
||||
buildCondition(
|
||||
node.ignoreCase
|
||||
? [ op.MATCH_STRING_IC, stringIndex ]
|
||||
: [ op.MATCH_STRING, stringIndex ],
|
||||
node.ignoreCase
|
||||
? [ op.ACCEPT_N, node.value.length ]
|
||||
: [ op.ACCEPT_STRING, stringIndex ],
|
||||
[ op.PUSH_FAILED ]
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
@ -652,10 +664,13 @@ function generateBytecode( ast ) {
|
|||
+ ")"
|
||||
);
|
||||
|
||||
return buildCondition(
|
||||
[ op.MATCH_REGEXP, regexpIndex ],
|
||||
[ op.ACCEPT_N, 1 ],
|
||||
[ op.FAIL, expectedIndex ]
|
||||
return buildSequence(
|
||||
[ op.EXPECT, expectedIndex ],
|
||||
buildCondition(
|
||||
[ op.MATCH_REGEXP, regexpIndex ],
|
||||
[ op.ACCEPT_N, 1 ],
|
||||
[ op.PUSH_FAILED ]
|
||||
)
|
||||
);
|
||||
|
||||
},
|
||||
|
@ -664,10 +679,13 @@ function generateBytecode( ast ) {
|
|||
|
||||
const expectedIndex = addConst( "peg$anyExpectation()" );
|
||||
|
||||
return buildCondition(
|
||||
[ op.MATCH_ANY ],
|
||||
[ op.ACCEPT_N, 1 ],
|
||||
[ op.FAIL, expectedIndex ]
|
||||
return buildSequence(
|
||||
[ op.EXPECT, expectedIndex ],
|
||||
buildCondition(
|
||||
[ op.MATCH_ANY ],
|
||||
[ op.ACCEPT_N, 1 ],
|
||||
[ op.PUSH_FAILED ]
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
@ -391,10 +391,9 @@ function generateJS( ast, options ) {
|
|||
" ip += 2;",
|
||||
" break;",
|
||||
"",
|
||||
" case " + op.FAIL + ":", // FAIL e
|
||||
" stack.push(peg$FAILED);",
|
||||
" case " + op.EXPECT + ":", // EXPECT e
|
||||
" if (peg$silentFails === 0) {",
|
||||
" peg$fail(peg$consts[bc[ip + 1]]);",
|
||||
" peg$expect(peg$consts[bc[ip + 1]]);",
|
||||
" }",
|
||||
" ip += 2;",
|
||||
" break;",
|
||||
|
@ -427,6 +426,16 @@ function generateJS( ast, options ) {
|
|||
" ip++;",
|
||||
" break;",
|
||||
"",
|
||||
" case " + op.EXPECT_NS_BEGIN + ":", // EXPECT_NS_BEGIN
|
||||
" peg$begin();",
|
||||
" ip++;",
|
||||
" break;",
|
||||
"",
|
||||
" case " + op.EXPECT_NS_END + ":", // EXPECT_NS_END invert
|
||||
" peg$end(bc[ip + 1]);",
|
||||
" ip += 2;",
|
||||
" break;",
|
||||
"",
|
||||
" // istanbul ignore next",
|
||||
" default:",
|
||||
" throw new Error(\"Invalid opcode: \" + bc[ip] + \".\");",
|
||||
|
@ -748,9 +757,8 @@ function generateJS( ast, options ) {
|
|||
ip += 2;
|
||||
break;
|
||||
|
||||
case op.FAIL: // FAIL e
|
||||
parts.push( stack.push( "peg$FAILED" ) );
|
||||
parts.push( "if (peg$silentFails === 0) { peg$fail(" + c( bc[ ip + 1 ] ) + "); }" );
|
||||
case op.EXPECT: // EXPECT e
|
||||
parts.push( "if (peg$silentFails === 0) { peg$expect(" + c( bc[ ip + 1 ] ) + "); }" );
|
||||
ip += 2;
|
||||
break;
|
||||
|
||||
|
@ -783,6 +791,16 @@ function generateJS( ast, options ) {
|
|||
ip++;
|
||||
break;
|
||||
|
||||
case op.EXPECT_NS_BEGIN: // EXPECT_NS_BEGIN
|
||||
parts.push( "peg$begin();" );
|
||||
ip++;
|
||||
break;
|
||||
|
||||
case op.EXPECT_NS_END: // EXPECT_NS_END invert
|
||||
parts.push( "peg$end(" + ( bc[ ip + 1 ] !== 0 ) + ");" );
|
||||
ip += 2;
|
||||
break;
|
||||
|
||||
// istanbul ignore next
|
||||
default:
|
||||
throw new Error( "Invalid opcode: " + bc[ ip ] + "." );
|
||||
|
@ -881,6 +899,10 @@ function generateJS( ast, options ) {
|
|||
"",
|
||||
" other: function(expectation) {",
|
||||
" return expectation.description;",
|
||||
" },",
|
||||
"",
|
||||
" not: function(expectation) {",
|
||||
" return \"not \" + describeExpectation(expectation.expected);",
|
||||
" }",
|
||||
" };",
|
||||
"",
|
||||
|
@ -1065,8 +1087,7 @@ function generateJS( ast, options ) {
|
|||
" var peg$currPos = 0;",
|
||||
" var peg$savedPos = 0;",
|
||||
" var peg$posDetailsCache = [{ line: 1, column: 1 }];",
|
||||
" var peg$maxFailPos = 0;",
|
||||
" var peg$maxFailExpected = [];",
|
||||
" var peg$expected = [];",
|
||||
" var peg$silentFails = 0;", // 0 = report failures, > 0 = silence failures
|
||||
""
|
||||
].join( "\n" ) );
|
||||
|
@ -1246,15 +1267,37 @@ function generateJS( ast, options ) {
|
|||
" };",
|
||||
" }",
|
||||
"",
|
||||
" function peg$fail(expected) {",
|
||||
" if (peg$currPos < peg$maxFailPos) { return; }",
|
||||
" function peg$begin() {",
|
||||
" peg$expected.push({ pos: peg$currPos, variants: [] });",
|
||||
" }",
|
||||
"",
|
||||
" if (peg$currPos > peg$maxFailPos) {",
|
||||
" peg$maxFailPos = peg$currPos;",
|
||||
" peg$maxFailExpected = [];",
|
||||
" function peg$expect(expected) {",
|
||||
" var top = peg$expected[peg$expected.length - 1];",
|
||||
"",
|
||||
" if (peg$currPos < top.pos) { return; }",
|
||||
"",
|
||||
" if (peg$currPos > top.pos) {",
|
||||
" top.pos = peg$currPos;",
|
||||
" top.variants = [];",
|
||||
" }",
|
||||
"",
|
||||
" peg$maxFailExpected.push(expected);",
|
||||
" top.variants.push(expected);",
|
||||
" }",
|
||||
"",
|
||||
" function peg$end(invert) {",
|
||||
" var expected = peg$expected.pop();",
|
||||
" var top = peg$expected[peg$expected.length - 1];",
|
||||
" var variants = expected.variants;",
|
||||
"",
|
||||
" if (top.pos !== expected.pos) { return; }",
|
||||
"",
|
||||
" if (invert) {",
|
||||
" variants = variants.map(function(e) {",
|
||||
" return e.type === \"not\" ? e.expected : { type: \"not\", expected: e };",
|
||||
" });",
|
||||
" }",
|
||||
"",
|
||||
" Array.prototype.push.apply(top.variants, variants);",
|
||||
" }",
|
||||
"",
|
||||
" function peg$buildSimpleError(message, location) {",
|
||||
|
@ -1269,6 +1312,19 @@ function generateJS( ast, options ) {
|
|||
" location",
|
||||
" );",
|
||||
" }",
|
||||
"",
|
||||
" function peg$buildError() {",
|
||||
" var expected = peg$expected[0];",
|
||||
" var failPos = expected.pos;",
|
||||
"",
|
||||
" return peg$buildStructuredError(",
|
||||
" expected.variants,",
|
||||
" failPos < input.length ? input.charAt(failPos) : null,",
|
||||
" failPos < input.length",
|
||||
" ? peg$computeLocation(failPos, failPos + 1)",
|
||||
" : peg$computeLocation(failPos, failPos)",
|
||||
" );",
|
||||
" }",
|
||||
""
|
||||
].join( "\n" ) );
|
||||
|
||||
|
@ -1295,6 +1351,8 @@ function generateJS( ast, options ) {
|
|||
|
||||
}
|
||||
|
||||
parts.push( " peg$begin();" );
|
||||
|
||||
if ( options.optimize === "size" ) {
|
||||
|
||||
parts.push( " peg$result = peg$parseRule(peg$startRuleIndex);" );
|
||||
|
@ -1311,16 +1369,10 @@ function generateJS( ast, options ) {
|
|||
" return peg$result;",
|
||||
" } else {",
|
||||
" if (peg$result !== peg$FAILED && peg$currPos < input.length) {",
|
||||
" peg$fail(peg$endExpectation());",
|
||||
" peg$expect(peg$endExpectation());",
|
||||
" }",
|
||||
"",
|
||||
" throw peg$buildStructuredError(",
|
||||
" peg$maxFailExpected,",
|
||||
" peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null,",
|
||||
" peg$maxFailPos < input.length",
|
||||
" ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1)",
|
||||
" : peg$computeLocation(peg$maxFailPos, peg$maxFailPos)",
|
||||
" );",
|
||||
" throw peg$buildError();",
|
||||
" }",
|
||||
"}"
|
||||
].join( "\n" ) );
|
||||
|
|
605
lib/parser.js
605
lib/parser.js
File diff suppressed because it is too large
Load diff
|
@ -1194,19 +1194,33 @@ describe( "generated parser behavior", function () {
|
|||
|
||||
} );
|
||||
|
||||
it( "discards any expectations recorded when matching the expression", function () {
|
||||
it( "doesn't discard any expectations recorded when matching the expression", function () {
|
||||
|
||||
const parser = peg.generate( "start = 'a' / &'b' / 'c'", options );
|
||||
|
||||
expect( parser ).to.failToParse( "d", {
|
||||
expected: [
|
||||
{ type: "literal", text: "a", ignoreCase: false },
|
||||
{ type: "literal", text: "b", ignoreCase: false },
|
||||
{ type: "literal", text: "c", ignoreCase: false }
|
||||
]
|
||||
} );
|
||||
|
||||
} );
|
||||
|
||||
it( "records expectations from right place", function () {
|
||||
|
||||
const parser = peg.generate( "start = 'a' / &'b' .", options );
|
||||
|
||||
expect( parser ).to.failToParse( "d", {
|
||||
expected: [
|
||||
{ type: "literal", text: "a", ignoreCase: false },
|
||||
{ type: "literal", text: "b", ignoreCase: false }
|
||||
]
|
||||
} );
|
||||
|
||||
} );
|
||||
|
||||
} );
|
||||
|
||||
} );
|
||||
|
@ -1243,19 +1257,45 @@ describe( "generated parser behavior", function () {
|
|||
|
||||
} );
|
||||
|
||||
it( "discards any expectations recorded when matching the expression", function () {
|
||||
it( "inverts any expectations recorded when matching the expression", function () {
|
||||
|
||||
const parser = peg.generate( "start = 'a' / !'b' / 'c'", options );
|
||||
|
||||
expect( parser ).to.failToParse( "b", {
|
||||
expected: [
|
||||
{ type: "literal", text: "a", ignoreCase: false },
|
||||
{ type: "not", expected: { type: "literal", text: "b", ignoreCase: false } },
|
||||
{ type: "literal", text: "c", ignoreCase: false }
|
||||
]
|
||||
} );
|
||||
|
||||
} );
|
||||
|
||||
it( "records expectations from right place", function () {
|
||||
|
||||
const parser = peg.generate( "start = 'a' / !'b' .", options );
|
||||
|
||||
expect( parser ).to.failToParse( "b", {
|
||||
expected: [
|
||||
{ type: "literal", text: "a", ignoreCase: false },
|
||||
{ type: "not", expected: { type: "literal", text: "b", ignoreCase: false } }
|
||||
]
|
||||
} );
|
||||
|
||||
} );
|
||||
|
||||
it( "reports not inverted expectations when the expression inverted twice", function () {
|
||||
|
||||
const parser = peg.generate( "start = !(!'a')", options );
|
||||
|
||||
expect( parser ).to.failToParse( "b", {
|
||||
expected: [
|
||||
{ type: "literal", text: "a", ignoreCase: false }
|
||||
]
|
||||
} );
|
||||
|
||||
} );
|
||||
|
||||
} );
|
||||
|
||||
} );
|
||||
|
|
|
@ -34,9 +34,9 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
"c = 'c'"
|
||||
].join( "\n" ), {
|
||||
rules: [
|
||||
{ bytecode: [ 18, 0, 2, 2, 22, 0, 23, 1 ] },
|
||||
{ bytecode: [ 18, 2, 2, 2, 22, 2, 23, 3 ] },
|
||||
{ bytecode: [ 18, 4, 2, 2, 22, 4, 23, 5 ] }
|
||||
{ bytecode: [ 23, 1, 18, 0, 2, 1, 22, 0, 3 ] },
|
||||
{ bytecode: [ 23, 3, 18, 2, 2, 1, 22, 2, 3 ] },
|
||||
{ bytecode: [ 23, 5, 18, 4, 2, 1, 22, 4, 3 ] }
|
||||
]
|
||||
} );
|
||||
|
||||
|
@ -66,7 +66,7 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( "start = 'a'", bytecodeDetails( [
|
||||
18, 0, 2, 2, 22, 0, 23, 1 // <expression>
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3 // <expression>
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
@ -80,11 +80,10 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
28, // SILENT_FAILS_ON
|
||||
18, 1, 2, 2, 22, 1, 23, 2, // <expression>
|
||||
29, // SILENT_FAILS_OFF
|
||||
14, 2, 0, // IF_ERROR
|
||||
23, 0 // * FAIL
|
||||
23, 0, // EXPECT <0>
|
||||
28, // SILENT_FAILS_ON
|
||||
23, 2, 18, 1, 2, 1, 22, 1, 3, // <expression>
|
||||
29 // SILENT_FAILS_OFF
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
@ -106,13 +105,13 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( "start = 'a' / 'b' / 'c'", bytecodeDetails( [
|
||||
18, 0, 2, 2, 22, 0, 23, 1, // <alternatives[0]>
|
||||
14, 21, 0, // IF_ERROR
|
||||
6, // * POP
|
||||
18, 2, 2, 2, 22, 2, 23, 3, // <alternatives[1]>
|
||||
14, 9, 0, // IF_ERROR
|
||||
6, // * POP
|
||||
18, 4, 2, 2, 22, 4, 23, 5 // <alternatives[2]>
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <alternatives[0]>
|
||||
14, 23, 0, // IF_ERROR
|
||||
6, // * POP
|
||||
23, 3, 18, 2, 2, 1, 22, 2, 3, // <alternatives[1]>
|
||||
14, 10, 0, // IF_ERROR
|
||||
6, // * POP
|
||||
23, 5, 18, 4, 2, 1, 22, 4, 3 // <alternatives[2]>
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
@ -128,12 +127,12 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
5, // PUSH_CURR_POS
|
||||
18, 0, 2, 2, 22, 0, 23, 1, // <expression>
|
||||
15, 6, 0, // IF_NOT_ERROR
|
||||
24, 1, // * LOAD_SAVED_POS
|
||||
26, 2, 1, 0, // CALL
|
||||
9 // NIP
|
||||
5, // PUSH_CURR_POS
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
15, 6, 0, // IF_NOT_ERROR
|
||||
24, 1, // * LOAD_SAVED_POS
|
||||
26, 2, 1, 0, // CALL
|
||||
9 // NIP
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
@ -157,12 +156,12 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
5, // PUSH_CURR_POS
|
||||
18, 0, 2, 2, 22, 0, 23, 1, // <expression>
|
||||
15, 7, 0, // IF_NOT_ERROR
|
||||
24, 1, // * LOAD_SAVED_POS
|
||||
26, 2, 1, 1, 0, // CALL
|
||||
9 // NIP
|
||||
5, // PUSH_CURR_POS
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
15, 7, 0, // IF_NOT_ERROR
|
||||
24, 1, // * LOAD_SAVED_POS
|
||||
26, 2, 1, 1, 0, // CALL
|
||||
9 // NIP
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
@ -186,24 +185,24 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
5, // PUSH_CURR_POS
|
||||
18, 0, 2, 2, 22, 0, 23, 1, // <elements[0]>
|
||||
15, 39, 3, // IF_NOT_ERROR
|
||||
18, 2, 2, 2, 22, 2, 23, 3, // * <elements[1]>
|
||||
15, 24, 4, // IF_NOT_ERROR
|
||||
18, 4, 2, 2, 22, 4, 23, 5, // * <elements[2]>
|
||||
15, 9, 4, // IF_NOT_ERROR
|
||||
24, 3, // * LOAD_SAVED_POS
|
||||
26, 6, 4, 3, 2, 1, 0, // CALL <6>
|
||||
8, 3, // * POP_N
|
||||
7, // POP_CURR_POS
|
||||
3, // PUSH_FAILED
|
||||
8, 2, // * POP_N
|
||||
7, // POP_CURR_POS
|
||||
3, // PUSH_FAILED
|
||||
6, // * POP
|
||||
7, // POP_CURR_POS
|
||||
3 // PUSH_FAILED
|
||||
5, // PUSH_CURR_POS
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <elements[0]>
|
||||
15, 41, 3, // IF_NOT_ERROR
|
||||
23, 3, 18, 2, 2, 1, 22, 2, 3, // * <elements[1]>
|
||||
15, 25, 4, // IF_NOT_ERROR
|
||||
23, 5, 18, 4, 2, 1, 22, 4, 3, // * <elements[2]>
|
||||
15, 9, 4, // IF_NOT_ERROR
|
||||
24, 3, // * LOAD_SAVED_POS
|
||||
26, 6, 4, 3, 2, 1, 0, // CALL <6>
|
||||
8, 3, // * POP_N
|
||||
7, // POP_CURR_POS
|
||||
3, // PUSH_FAILED
|
||||
8, 2, // * POP_N
|
||||
7, // POP_CURR_POS
|
||||
3, // PUSH_FAILED
|
||||
6, // * POP
|
||||
7, // POP_CURR_POS
|
||||
3 // PUSH_FAILED
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
@ -233,24 +232,24 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
5, // PUSH_CURR_POS
|
||||
18, 0, 2, 2, 22, 0, 23, 1, // <elements[0]>
|
||||
15, 33, 3, // IF_NOT_ERROR
|
||||
18, 2, 2, 2, 22, 2, 23, 3, // * <elements[1]>
|
||||
15, 18, 4, // IF_NOT_ERROR
|
||||
18, 4, 2, 2, 22, 4, 23, 5, // * <elements[2]>
|
||||
15, 3, 4, // IF_NOT_ERROR
|
||||
11, 3, // * WRAP
|
||||
9, // NIP
|
||||
8, 3, // * POP_N
|
||||
7, // POP_CURR_POS
|
||||
3, // PUSH_FAILED
|
||||
8, 2, // * POP_N
|
||||
7, // POP_CURR_POS
|
||||
3, // PUSH_FAILED
|
||||
6, // * POP
|
||||
7, // POP_CURR_POS
|
||||
3 // PUSH_FAILED
|
||||
5, // PUSH_CURR_POS
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <elements[0]>
|
||||
15, 35, 3, // IF_NOT_ERROR
|
||||
23, 3, 18, 2, 2, 1, 22, 2, 3, // * <elements[1]>
|
||||
15, 19, 4, // IF_NOT_ERROR
|
||||
23, 5, 18, 4, 2, 1, 22, 4, 3, // * <elements[2]>
|
||||
15, 3, 4, // IF_NOT_ERROR
|
||||
11, 3, // * WRAP
|
||||
9, // NIP
|
||||
8, 3, // * POP_N
|
||||
7, // POP_CURR_POS
|
||||
3, // PUSH_FAILED
|
||||
8, 2, // * POP_N
|
||||
7, // POP_CURR_POS
|
||||
3, // PUSH_FAILED
|
||||
6, // * POP
|
||||
7, // POP_CURR_POS
|
||||
3 // PUSH_FAILED
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
@ -275,7 +274,7 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( "start = a:'a'", bytecodeDetails( [
|
||||
18, 0, 2, 2, 22, 0, 23, 1 // <expression>
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3 // <expression>
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
@ -287,12 +286,12 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( "start = $'a'", bytecodeDetails( [
|
||||
5, // PUSH_CURR_POS
|
||||
18, 0, 2, 2, 22, 0, 23, 1, // <expression>
|
||||
15, 2, 1, // IF_NOT_ERROR
|
||||
6, // * POP
|
||||
12, // TEXT
|
||||
9 // * NIP
|
||||
5, // PUSH_CURR_POS
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
15, 2, 1, // IF_NOT_ERROR
|
||||
6, // * POP
|
||||
12, // TEXT
|
||||
9 // * NIP
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
@ -306,17 +305,17 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
5, // PUSH_CURR_POS
|
||||
28, // SILENT_FAILS_ON
|
||||
18, 0, 2, 2, 22, 0, 23, 1, // <expression>
|
||||
29, // SILENT_FAILS_OFF
|
||||
15, 3, 3, // IF_NOT_ERROR
|
||||
6, // * POP
|
||||
7, // POP_CURR_POS
|
||||
1, // PUSH_UNDEFINED
|
||||
6, // * POP
|
||||
6, // POP
|
||||
3 // PUSH_FAILED
|
||||
5, // PUSH_CURR_POS
|
||||
38, // EXPECT_NS_BEGIN
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
39, 0, // EXPECT_NS_END <false>
|
||||
15, 3, 3, // IF_NOT_ERROR
|
||||
6, // * POP
|
||||
7, // POP_CURR_POS
|
||||
1, // PUSH_UNDEFINED
|
||||
6, // * POP
|
||||
6, // POP
|
||||
3 // PUSH_FAILED
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
@ -339,17 +338,17 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
5, // PUSH_CURR_POS
|
||||
28, // SILENT_FAILS_ON
|
||||
18, 0, 2, 2, 22, 0, 23, 1, // <expression>
|
||||
29, // SILENT_FAILS_OFF
|
||||
14, 3, 3, // IF_ERROR
|
||||
6, // * POP
|
||||
6, // POP
|
||||
1, // PUSH_UNDEFINED
|
||||
6, // * POP
|
||||
7, // POP_CURR_POS
|
||||
3 // PUSH_FAILED
|
||||
5, // PUSH_CURR_POS
|
||||
38, // EXPECT_NS_BEGIN
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
39, 1, // EXPECT_NS_END <true>
|
||||
14, 3, 3, // IF_ERROR
|
||||
6, // * POP
|
||||
6, // POP
|
||||
1, // PUSH_UNDEFINED
|
||||
6, // * POP
|
||||
7, // POP_CURR_POS
|
||||
3 // PUSH_FAILED
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
@ -372,10 +371,10 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
18, 0, 2, 2, 22, 0, 23, 1, // <expression>
|
||||
14, 2, 0, // IF_ERROR
|
||||
6, // * POP
|
||||
2 // PUSH_NULL
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
14, 2, 0, // IF_ERROR
|
||||
6, // * POP
|
||||
2 // PUSH_NULL
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
@ -398,12 +397,12 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
4, // PUSH_EMPTY_ARRAY
|
||||
18, 0, 2, 2, 22, 0, 23, 1, // <expression>
|
||||
16, 9, // WHILE_NOT_ERROR
|
||||
10, // * APPEND
|
||||
18, 0, 2, 2, 22, 0, 23, 1, // <expression>
|
||||
6 // POP
|
||||
4, // PUSH_EMPTY_ARRAY
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
16, 10, // WHILE_NOT_ERROR
|
||||
10, // * APPEND
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
6 // POP
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
@ -426,16 +425,16 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
4, // PUSH_EMPTY_ARRAY
|
||||
18, 0, 2, 2, 22, 0, 23, 1, // <expression>
|
||||
15, 12, 3, // IF_NOT_ERROR
|
||||
16, 9, // * WHILE_NOT_ERROR
|
||||
10, // * APPEND
|
||||
18, 0, 2, 2, 22, 0, 23, 1, // <expression>
|
||||
6, // POP
|
||||
6, // * POP
|
||||
6, // POP
|
||||
3 // PUSH_FAILED
|
||||
4, // PUSH_EMPTY_ARRAY
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
15, 13, 3, // IF_NOT_ERROR
|
||||
16, 10, // * WHILE_NOT_ERROR
|
||||
10, // * APPEND
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
6, // POP
|
||||
6, // * POP
|
||||
6, // POP
|
||||
3 // PUSH_FAILED
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
@ -456,7 +455,7 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( "start = ('a')", bytecodeDetails( [
|
||||
18, 0, 2, 2, 22, 0, 23, 1 // <expression>
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3 // <expression>
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
@ -501,35 +500,35 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
5, // PUSH_CURR_POS
|
||||
18, 0, 2, 2, 22, 0, 23, 1, // <elements[0]>
|
||||
15, 55, 3, // IF_NOT_ERROR
|
||||
18, 2, 2, 2, 22, 2, 23, 3, // * <elements[1]>
|
||||
15, 40, 4, // IF_NOT_ERROR
|
||||
18, 4, 2, 2, 22, 4, 23, 5, // * <elements[2]>
|
||||
15, 25, 4, // IF_NOT_ERROR
|
||||
25, // * UPDATE_SAVED_POS
|
||||
26, 6, 0, 3, 2, 1, 0, // CALL
|
||||
13, 2, 2, // IF
|
||||
6, // * POP
|
||||
1, // PUSH_UNDEFINED
|
||||
6, // * POP
|
||||
3, // PUSH_FAILED
|
||||
15, 3, 4, // IF_NOT_ERROR
|
||||
11, 4, // * WRAP
|
||||
9, // NIP
|
||||
8, 4, // * POP_N
|
||||
7, // POP_CURR_POS
|
||||
3, // PUSH_FAILED
|
||||
8, 3, // * POP_N
|
||||
7, // POP_CURR_POS
|
||||
3, // PUSH_FAILED
|
||||
8, 2, // * POP_N
|
||||
7, // POP_CURR_POS
|
||||
3, // PUSH_FAILED
|
||||
6, // * POP
|
||||
7, // POP_CURR_POS
|
||||
3 // PUSH_FAILED
|
||||
5, // PUSH_CURR_POS
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <elements[0]>
|
||||
15, 57, 3, // IF_NOT_ERROR
|
||||
23, 3, 18, 2, 2, 1, 22, 2, 3, // * <elements[1]>
|
||||
15, 41, 4, // IF_NOT_ERROR
|
||||
23, 5, 18, 4, 2, 1, 22, 4, 3, // * <elements[2]>
|
||||
15, 25, 4, // IF_NOT_ERROR
|
||||
25, // * UPDATE_SAVED_POS
|
||||
26, 6, 0, 3, 2, 1, 0, // CALL
|
||||
13, 2, 2, // IF
|
||||
6, // * POP
|
||||
1, // PUSH_UNDEFINED
|
||||
6, // * POP
|
||||
3, // PUSH_FAILED
|
||||
15, 3, 4, // IF_NOT_ERROR
|
||||
11, 4, // * WRAP
|
||||
9, // NIP
|
||||
8, 4, // * POP_N
|
||||
7, // POP_CURR_POS
|
||||
3, // PUSH_FAILED
|
||||
8, 3, // * POP_N
|
||||
7, // POP_CURR_POS
|
||||
3, // PUSH_FAILED
|
||||
8, 2, // * POP_N
|
||||
7, // POP_CURR_POS
|
||||
3, // PUSH_FAILED
|
||||
6, // * POP
|
||||
7, // POP_CURR_POS
|
||||
3 // PUSH_FAILED
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
@ -590,35 +589,35 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
5, // PUSH_CURR_POS
|
||||
18, 0, 2, 2, 22, 0, 23, 1, // <elements[0]>
|
||||
15, 55, 3, // IF_NOT_ERROR
|
||||
18, 2, 2, 2, 22, 2, 23, 3, // * <elements[1]>
|
||||
15, 40, 4, // IF_NOT_ERROR
|
||||
18, 4, 2, 2, 22, 4, 23, 5, // * <elements[2]>
|
||||
15, 25, 4, // IF_NOT_ERROR
|
||||
25, // * UPDATE_SAVED_POS
|
||||
26, 6, 0, 3, 2, 1, 0, // CALL
|
||||
13, 2, 2, // IF
|
||||
6, // * POP
|
||||
3, // PUSH_FAILED
|
||||
6, // * POP
|
||||
1, // PUSH_UNDEFINED
|
||||
15, 3, 4, // IF_NOT_ERROR
|
||||
11, 4, // * WRAP
|
||||
9, // NIP
|
||||
8, 4, // * POP_N
|
||||
7, // POP_CURR_POS
|
||||
3, // PUSH_FAILED
|
||||
8, 3, // * POP_N
|
||||
7, // POP_CURR_POS
|
||||
3, // PUSH_FAILED
|
||||
8, 2, // * POP_N
|
||||
7, // POP_CURR_POS
|
||||
3, // PUSH_FAILED
|
||||
6, // * POP
|
||||
7, // POP_CURR_POS
|
||||
3 // PUSH_FAILED
|
||||
5, // PUSH_CURR_POS
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <elements[0]>
|
||||
15, 57, 3, // IF_NOT_ERROR
|
||||
23, 3, 18, 2, 2, 1, 22, 2, 3, // * <elements[1]>
|
||||
15, 41, 4, // IF_NOT_ERROR
|
||||
23, 5, 18, 4, 2, 1, 22, 4, 3, // * <elements[2]>
|
||||
15, 25, 4, // IF_NOT_ERROR
|
||||
25, // * UPDATE_SAVED_POS
|
||||
26, 6, 0, 3, 2, 1, 0, // CALL
|
||||
13, 2, 2, // IF
|
||||
6, // * POP
|
||||
3, // PUSH_FAILED
|
||||
6, // * POP
|
||||
1, // PUSH_UNDEFINED
|
||||
15, 3, 4, // IF_NOT_ERROR
|
||||
11, 4, // * WRAP
|
||||
9, // NIP
|
||||
8, 4, // * POP_N
|
||||
7, // POP_CURR_POS
|
||||
3, // PUSH_FAILED
|
||||
8, 3, // * POP_N
|
||||
7, // POP_CURR_POS
|
||||
3, // PUSH_FAILED
|
||||
8, 2, // * POP_N
|
||||
7, // POP_CURR_POS
|
||||
3, // PUSH_FAILED
|
||||
6, // * POP
|
||||
7, // POP_CURR_POS
|
||||
3 // PUSH_FAILED
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
@ -690,9 +689,10 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
18, 0, 2, 2, // MATCH_STRING
|
||||
23, 1, // EXPECT <1>
|
||||
18, 0, 2, 1, // MATCH_STRING <0>
|
||||
22, 0, // * ACCEPT_STRING
|
||||
23, 1 // * FAIL
|
||||
3 // * PUSH_FAILED
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
@ -715,9 +715,10 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
19, 0, 2, 2, // MATCH_STRING_IC
|
||||
23, 1, // EXPECT <1>
|
||||
19, 0, 2, 1, // MATCH_STRING_IC <0>
|
||||
21, 1, // * ACCEPT_N
|
||||
23, 1 // * FAIL
|
||||
3 // * PUSH_FAILED
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
@ -740,9 +741,10 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( "start = [a]", bytecodeDetails( [
|
||||
20, 0, 2, 2, // MATCH_REGEXP
|
||||
23, 1, // EXPECT <1>
|
||||
20, 0, 2, 1, // MATCH_REGEXP <0>
|
||||
21, 1, // * ACCEPT_N
|
||||
23, 1 // * FAIL
|
||||
3 // * PUSH_FAILED
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
@ -808,9 +810,10 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
17, 2, 2, // MATCH_ANY
|
||||
23, 0, // EXPECT <0>
|
||||
17, 2, 1, // MATCH_ANY
|
||||
21, 1, // * ACCEPT_N
|
||||
23, 0 // * FAIL
|
||||
3 // * PUSH_FAILED
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
|
Loading…
Reference in a new issue