Move all codegeneration from generateBytecode
pass to generateJs
pass (#459)
* Split 'consts' collection by content types into: - literals: for literal expressions, like `"a"` - classes: for character class expressions, like `[a]` - expectations: for constants describing expected values when parse failed - functions: for constants with function code * Move any JavaScript code generation from 'generateBytecode' to 'generateJs'. * Rename opcode 'MATCH_REGEXP' to 'MATCH_CLASS' (name reflects purpose, not implementation). * Replace 'PUSH' opcode with 'PUSH_EMPTY_STRING' opcode because it is only used with empty strings
This commit is contained in:
parent
617b6b7425
commit
9b90fa1d81
|
@ -5,54 +5,54 @@ const opcodes = {
|
|||
|
||||
// Stack Manipulation
|
||||
|
||||
PUSH: 0, // PUSH c
|
||||
PUSH_UNDEFINED: 1, // PUSH_UNDEFINED
|
||||
PUSH_NULL: 2, // PUSH_NULL
|
||||
PUSH_FAILED: 3, // PUSH_FAILED
|
||||
PUSH_EMPTY_ARRAY: 4, // PUSH_EMPTY_ARRAY
|
||||
PUSH_CURR_POS: 5, // PUSH_CURR_POS
|
||||
POP: 6, // POP
|
||||
POP_CURR_POS: 7, // POP_CURR_POS
|
||||
POP_N: 8, // POP_N n
|
||||
NIP: 9, // NIP
|
||||
APPEND: 10, // APPEND
|
||||
WRAP: 11, // WRAP n
|
||||
TEXT: 12, // TEXT
|
||||
PUSH_EMPTY_STRING: 0, // PUSH_EMPTY_STRING
|
||||
PUSH_UNDEFINED: 1, // PUSH_UNDEFINED
|
||||
PUSH_NULL: 2, // PUSH_NULL
|
||||
PUSH_FAILED: 3, // PUSH_FAILED
|
||||
PUSH_EMPTY_ARRAY: 4, // PUSH_EMPTY_ARRAY
|
||||
PUSH_CURR_POS: 5, // PUSH_CURR_POS
|
||||
POP: 6, // POP
|
||||
POP_CURR_POS: 7, // POP_CURR_POS
|
||||
POP_N: 8, // POP_N n
|
||||
NIP: 9, // NIP
|
||||
APPEND: 10, // APPEND
|
||||
WRAP: 11, // WRAP n
|
||||
TEXT: 12, // TEXT
|
||||
|
||||
// Conditions and Loops
|
||||
|
||||
IF: 13, // IF t, f
|
||||
IF_ERROR: 14, // IF_ERROR t, f
|
||||
IF_NOT_ERROR: 15, // IF_NOT_ERROR t, f
|
||||
WHILE_NOT_ERROR: 16, // WHILE_NOT_ERROR b
|
||||
IF: 13, // IF t, f
|
||||
IF_ERROR: 14, // IF_ERROR t, f
|
||||
IF_NOT_ERROR: 15, // IF_NOT_ERROR t, f
|
||||
WHILE_NOT_ERROR: 16, // WHILE_NOT_ERROR b
|
||||
|
||||
// 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_REGEXP: 20, // MATCH_REGEXP r, a, f, ...
|
||||
ACCEPT_N: 21, // ACCEPT_N n
|
||||
ACCEPT_STRING: 22, // ACCEPT_STRING s
|
||||
EXPECT: 23, // EXPECT e
|
||||
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, ...
|
||||
ACCEPT_N: 21, // ACCEPT_N n
|
||||
ACCEPT_STRING: 22, // ACCEPT_STRING s
|
||||
EXPECT: 23, // EXPECT e
|
||||
|
||||
// Calls
|
||||
|
||||
LOAD_SAVED_POS: 24, // LOAD_SAVED_POS p
|
||||
UPDATE_SAVED_POS: 25, // UPDATE_SAVED_POS
|
||||
CALL: 26, // CALL f, n, pc, p1, p2, ..., pN
|
||||
LOAD_SAVED_POS: 24, // LOAD_SAVED_POS p
|
||||
UPDATE_SAVED_POS: 25, // UPDATE_SAVED_POS
|
||||
CALL: 26, // CALL f, n, pc, p1, p2, ..., pN
|
||||
|
||||
// Rules
|
||||
|
||||
RULE: 27, // RULE r
|
||||
RULE: 27, // RULE r
|
||||
|
||||
// Failure Reporting
|
||||
|
||||
SILENT_FAILS_ON: 28, // SILENT_FAILS_ON
|
||||
SILENT_FAILS_OFF: 29, // SILENT_FAILS_OFF
|
||||
SILENT_FAILS_ON: 28, // SILENT_FAILS_ON
|
||||
SILENT_FAILS_OFF: 29, // SILENT_FAILS_OFF
|
||||
|
||||
EXPECT_NS_BEGIN: 38, // EXPECT_NS_BEGIN
|
||||
EXPECT_NS_END: 39 // EXPECT_NS_END invert
|
||||
EXPECT_NS_BEGIN: 38, // EXPECT_NS_BEGIN
|
||||
EXPECT_NS_END: 39 // EXPECT_NS_END invert
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
"use strict";
|
||||
|
||||
const asts = require( "../asts" );
|
||||
const js = require( "../js" );
|
||||
const op = require( "../opcodes" );
|
||||
const visitor = require( "../visitor" );
|
||||
const util = require( "../../util" );
|
||||
|
@ -14,9 +13,9 @@ const util = require( "../../util" );
|
|||
// Stack Manipulation
|
||||
// ------------------
|
||||
//
|
||||
// [0] PUSH c
|
||||
// [0] PUSH_EMPTY_STRING
|
||||
//
|
||||
// stack.push(consts[c]);
|
||||
// stack.push("");
|
||||
//
|
||||
// [1] PUSH_UNDEFINED
|
||||
//
|
||||
|
@ -117,7 +116,7 @@ const util = require( "../../util" );
|
|||
//
|
||||
// [18] MATCH_STRING s, a, f, ...
|
||||
//
|
||||
// if (input.substr(currPos, consts[s].length) === consts[s]) {
|
||||
// if (input.substr(currPos, literals[s].length) === literals[s]) {
|
||||
// interpret(ip + 4, ip + 4 + a);
|
||||
// } else {
|
||||
// interpret(ip + 4 + a, ip + 4 + a + f);
|
||||
|
@ -125,15 +124,15 @@ const util = require( "../../util" );
|
|||
//
|
||||
// [19] MATCH_STRING_IC s, a, f, ...
|
||||
//
|
||||
// if (input.substr(currPos, consts[s].length).toLowerCase() === consts[s]) {
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// [20] MATCH_REGEXP r, a, f, ...
|
||||
// [20] MATCH_CLASS c, a, f, ...
|
||||
//
|
||||
// if (consts[r].test(input.charAt(currPos))) {
|
||||
// if (classes[c].test(input.charAt(currPos))) {
|
||||
// interpret(ip + 4, ip + 4 + a);
|
||||
// } else {
|
||||
// interpret(ip + 4 + a, ip + 4 + a + f);
|
||||
|
@ -146,12 +145,12 @@ const util = require( "../../util" );
|
|||
//
|
||||
// [22] ACCEPT_STRING s
|
||||
//
|
||||
// stack.push(consts[s]);
|
||||
// currPos += consts[s].length;
|
||||
// stack.push(literals[s]);
|
||||
// currPos += literals[s].length;
|
||||
//
|
||||
// [23] EXPECT e
|
||||
//
|
||||
// expect(consts[e]);
|
||||
// expect(expectations[e]);
|
||||
//
|
||||
// Calls
|
||||
// -----
|
||||
|
@ -166,7 +165,7 @@ const util = require( "../../util" );
|
|||
//
|
||||
// [26] CALL f, n, pc, p1, p2, ..., pN
|
||||
//
|
||||
// value = consts[f](stack[p1], ..., stack[pN]);
|
||||
// value = functions[f](stack[p1], ..., stack[pN]);
|
||||
// stack.pop(n);
|
||||
// stack.push(value);
|
||||
//
|
||||
|
@ -203,19 +202,46 @@ const util = require( "../../util" );
|
|||
// }
|
||||
function generateBytecode( ast ) {
|
||||
|
||||
const consts = [];
|
||||
const literals = [];
|
||||
const classes = [];
|
||||
const expectations = [];
|
||||
const functions = [];
|
||||
let generate;
|
||||
|
||||
function addConst( value ) {
|
||||
function addLiteralConst( value ) {
|
||||
|
||||
const index = consts.indexOf( value );
|
||||
return index === -1 ? consts.push( value ) - 1 : index;
|
||||
const index = literals.indexOf( value );
|
||||
return index === -1 ? literals.push( value ) - 1 : index;
|
||||
|
||||
}
|
||||
|
||||
function addFunctionConst( params, code ) {
|
||||
function addClassConst( node ) {
|
||||
|
||||
return addConst( `function(${ params.join( ", " ) }) {${ code }}` );
|
||||
const cls = {
|
||||
value: node.parts,
|
||||
inverted: node.inverted,
|
||||
ignoreCase: node.ignoreCase
|
||||
};
|
||||
const pattern = JSON.stringify( cls );
|
||||
const index = classes.findIndex( c => JSON.stringify( c ) === pattern );
|
||||
return index === -1 ? classes.push( cls ) - 1 : index;
|
||||
|
||||
}
|
||||
|
||||
function addExpectedConst( expected ) {
|
||||
|
||||
const pattern = JSON.stringify( expected );
|
||||
const index = expectations.findIndex( e => JSON.stringify( e ) === pattern );
|
||||
return index === -1 ? expectations.push( expected ) - 1 : index;
|
||||
|
||||
}
|
||||
|
||||
function addFunctionConst( predicate, params, code ) {
|
||||
|
||||
const func = { predicate: predicate, params: params, body: code };
|
||||
const pattern = JSON.stringify( func );
|
||||
const index = functions.findIndex( f => JSON.stringify( f ) === pattern );
|
||||
return index === -1 ? functions.push( func ) - 1 : index;
|
||||
|
||||
}
|
||||
|
||||
|
@ -284,7 +310,7 @@ function generateBytecode( ast ) {
|
|||
|
||||
function buildSemanticPredicate( node, negative, context ) {
|
||||
|
||||
const functionIndex = addFunctionConst( Object.keys( context.env ), node.code );
|
||||
const functionIndex = addFunctionConst( true, Object.keys( context.env ), node.code );
|
||||
|
||||
return buildSequence(
|
||||
[ op.UPDATE_SAVED_POS ],
|
||||
|
@ -312,7 +338,10 @@ function generateBytecode( ast ) {
|
|||
grammar( node ) {
|
||||
|
||||
node.rules.forEach( generate );
|
||||
node.consts = consts;
|
||||
node.literals = literals;
|
||||
node.classes = classes;
|
||||
node.expectations = expectations;
|
||||
node.functions = functions;
|
||||
|
||||
},
|
||||
|
||||
|
@ -330,8 +359,8 @@ function generateBytecode( ast ) {
|
|||
named( node, context ) {
|
||||
|
||||
// Do not generate unused constant, if no need it
|
||||
const nameIndex = context.reportFailures ? addConst(
|
||||
`peg$otherExpectation("${ js.stringEscape( node.name ) }")`
|
||||
const nameIndex = context.reportFailures ? addExpectedConst(
|
||||
{ type: "rule", value: node.name }
|
||||
) : null;
|
||||
const expressionCode = generate( node.expression, {
|
||||
sp: context.sp,
|
||||
|
@ -393,7 +422,7 @@ function generateBytecode( ast ) {
|
|||
} );
|
||||
const match = node.expression.match|0;
|
||||
const functionIndex = emitCall && match >= 0
|
||||
? addFunctionConst( Object.keys( env ), node.code )
|
||||
? addFunctionConst( false, Object.keys( env ), node.code )
|
||||
: null;
|
||||
|
||||
return emitCall === false
|
||||
|
@ -450,6 +479,7 @@ function generateBytecode( ast ) {
|
|||
} else if ( context.action ) {
|
||||
|
||||
const functionIndex = addFunctionConst(
|
||||
false,
|
||||
Object.keys( context.env ),
|
||||
context.action.code
|
||||
);
|
||||
|
@ -623,16 +653,15 @@ function generateBytecode( ast ) {
|
|||
|
||||
const match = node.match|0;
|
||||
const needConst = match === 0 || ( match > 0 && ! node.ignoreCase );
|
||||
const stringIndex = needConst ? addConst( `"${ js.stringEscape(
|
||||
const stringIndex = needConst ? addLiteralConst(
|
||||
node.ignoreCase ? node.value.toLowerCase() : node.value
|
||||
) }"` ) : null;
|
||||
// Do not generate unused constant, if no need it
|
||||
const expectedIndex = context.reportFailures ? addConst(
|
||||
"peg$literalExpectation("
|
||||
+ `"${ js.stringEscape( node.value ) }", `
|
||||
+ node.ignoreCase
|
||||
+ ")"
|
||||
) : null;
|
||||
// Do not generate unused constant, if no need it
|
||||
const expectedIndex = context.reportFailures ? addExpectedConst( {
|
||||
type: "literal",
|
||||
value: node.value,
|
||||
ignoreCase: node.ignoreCase
|
||||
} ) : null;
|
||||
|
||||
// For case-sensitive strings the value must match the beginning of the
|
||||
// remaining input exactly. As a result, we can use |ACCEPT_STRING| and
|
||||
|
@ -653,53 +682,27 @@ function generateBytecode( ast ) {
|
|||
|
||||
}
|
||||
|
||||
const stringIndex = addConst( "\"\"" );
|
||||
return [ op.PUSH, stringIndex ];
|
||||
return [ op.PUSH_EMPTY_STRING ];
|
||||
|
||||
},
|
||||
|
||||
class( node, context ) {
|
||||
|
||||
const regexp = "/^["
|
||||
+ ( node.inverted ? "^" : "" )
|
||||
+ node.parts
|
||||
.map( part =>
|
||||
( Array.isArray( part )
|
||||
? js.regexpClassEscape( part[ 0 ] )
|
||||
+ "-"
|
||||
+ js.regexpClassEscape( part[ 1 ] )
|
||||
: js.regexpClassEscape( part ) )
|
||||
)
|
||||
.join( "" )
|
||||
+ "]/"
|
||||
+ ( node.ignoreCase ? "i" : "" );
|
||||
|
||||
const parts = "["
|
||||
+ node.parts
|
||||
.map( part =>
|
||||
( Array.isArray( part )
|
||||
? `["${ js.stringEscape( part[ 0 ] ) }", "${ js.stringEscape( part[ 1 ] ) }"]`
|
||||
: "\"" + js.stringEscape( part ) + "\"" )
|
||||
)
|
||||
.join( ", " )
|
||||
+ "]";
|
||||
|
||||
const match = node.match|0;
|
||||
const regexpIndex = match === 0 ? addConst( regexp ) : null;
|
||||
const classIndex = match === 0 ? addClassConst( node ) : null;
|
||||
// Do not generate unused constant, if no need it
|
||||
const expectedIndex = context.reportFailures ? addConst(
|
||||
"peg$classExpectation("
|
||||
+ parts + ", "
|
||||
+ node.inverted + ", "
|
||||
+ node.ignoreCase
|
||||
+ ")"
|
||||
) : null;
|
||||
const expectedIndex = context.reportFailures ? addExpectedConst( {
|
||||
type: "class",
|
||||
value: node.parts,
|
||||
inverted: node.inverted,
|
||||
ignoreCase: node.ignoreCase
|
||||
} ) : null;
|
||||
|
||||
return buildSequence(
|
||||
context.reportFailures ? [ op.EXPECT, expectedIndex ] : [],
|
||||
buildCondition(
|
||||
match,
|
||||
[ op.MATCH_REGEXP, regexpIndex ],
|
||||
[ op.MATCH_CLASS, classIndex ],
|
||||
[ op.ACCEPT_N, 1 ],
|
||||
[ op.PUSH_FAILED ]
|
||||
)
|
||||
|
@ -711,7 +714,7 @@ function generateBytecode( ast ) {
|
|||
|
||||
// Do not generate unused constant, if no need it
|
||||
const expectedIndex = context.reportFailures
|
||||
? addConst( "peg$anyExpectation()" )
|
||||
? addExpectedConst( { type: "any" } )
|
||||
: null;
|
||||
|
||||
return buildSequence(
|
||||
|
|
|
@ -22,13 +22,92 @@ function generateJS( ast, options ) {
|
|||
|
||||
}
|
||||
|
||||
const l = i => "peg$c" + i; // |literals[i]| of the abstract machine
|
||||
const r = i => "peg$r" + i; // |classes[i]| of the abstract machine
|
||||
const e = i => "peg$e" + i; // |expectations[i]| of the abstract machine
|
||||
const f = i => "peg$f" + i; // |actions[i]| of the abstract machine
|
||||
|
||||
function generateTables() {
|
||||
|
||||
function buildLiteral( literal ) {
|
||||
|
||||
return `"${ js.stringEscape( literal ) }"`;
|
||||
|
||||
}
|
||||
|
||||
function buildRegexp( cls ) {
|
||||
|
||||
return "/^["
|
||||
+ ( cls.inverted ? "^" : "" )
|
||||
+ cls.value
|
||||
.map( part =>
|
||||
( Array.isArray( part )
|
||||
? js.regexpClassEscape( part[ 0 ] )
|
||||
+ "-"
|
||||
+ js.regexpClassEscape( part[ 1 ] )
|
||||
: js.regexpClassEscape( part ) )
|
||||
)
|
||||
.join( "" )
|
||||
+ "]/"
|
||||
+ ( cls.ignoreCase ? "i" : "" );
|
||||
|
||||
}
|
||||
|
||||
function buildExpectation( e ) {
|
||||
|
||||
switch ( e.type ) {
|
||||
|
||||
case "rule":
|
||||
return `peg$otherExpectation("${ js.stringEscape( e.value ) }")`;
|
||||
case "literal":
|
||||
return "peg$literalExpectation(\""
|
||||
+ js.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 ) }"` )
|
||||
);
|
||||
|
||||
return "peg$classExpectation(["
|
||||
+ parts.join( ", " ) + "], "
|
||||
+ e.inverted + ", "
|
||||
+ e.ignoreCase
|
||||
+ ")";
|
||||
|
||||
}
|
||||
case "any": return "peg$anyExpectation()";
|
||||
// istanbul ignore next
|
||||
default: throw new Error( `Unknown expectation type (${ JSON.stringify( e ) })` );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function buildFunc( f ) {
|
||||
|
||||
return `function(${ f.params.join( ", " ) }) {${ f.body }}`;
|
||||
|
||||
}
|
||||
|
||||
if ( options.optimize === "size" ) {
|
||||
|
||||
return [
|
||||
"var peg$consts = [",
|
||||
indent2( ast.consts.join( ",\n" ) ),
|
||||
"var peg$literals = [",
|
||||
indent2( ast.literals.map( buildLiteral ).join( ",\n" ) ),
|
||||
"];",
|
||||
"var peg$regexps = [",
|
||||
indent2( ast.classes.map( buildRegexp ).join( ",\n" ) ),
|
||||
"];",
|
||||
"var peg$expectations = [",
|
||||
indent2( ast.expectations.map( buildExpectation ).join( ",\n" ) ),
|
||||
"];",
|
||||
"var peg$functions = [",
|
||||
indent2( ast.functions.map( buildFunc ).join( ",\n" ) ),
|
||||
"];",
|
||||
"",
|
||||
"var peg$bytecode = [",
|
||||
|
@ -48,7 +127,15 @@ function generateJS( ast, options ) {
|
|||
|
||||
}
|
||||
|
||||
return ast.consts.map( ( c, i ) => "var peg$c" + i + " = " + c + ";" ).join( "\n" );
|
||||
return ast.literals.map(
|
||||
( c, i ) => "var " + l( i ) + " = " + buildLiteral( c ) + ";"
|
||||
).concat( "", ast.classes.map(
|
||||
( c, i ) => "var " + r( i ) + " = " + buildRegexp( c ) + ";" )
|
||||
).concat( "", ast.expectations.map(
|
||||
( c, i ) => "var " + e( i ) + " = " + buildExpectation( c ) + ";" )
|
||||
).concat( "", ast.functions.map(
|
||||
( c, i ) => "var " + f( i ) + " = " + buildFunc( c ) + ";"
|
||||
) ).join( "\n" );
|
||||
|
||||
}
|
||||
|
||||
|
@ -220,7 +307,7 @@ function generateJS( ast, options ) {
|
|||
"stack.splice(",
|
||||
" stack.length - bc[ip + 2],",
|
||||
" bc[ip + 2],",
|
||||
" peg$consts[bc[ip + 1]].apply(null, params)",
|
||||
" peg$functions[bc[ip + 1]].apply(null, params)",
|
||||
");",
|
||||
"",
|
||||
"ip += " + baseLength + " + " + paramsLengthCode + ";",
|
||||
|
@ -275,9 +362,9 @@ function generateJS( ast, options ) {
|
|||
" while (true) {",
|
||||
" while (ip < end) {",
|
||||
" switch (bc[ip]) {",
|
||||
" case " + op.PUSH + ":", // PUSH c
|
||||
" stack.push(peg$consts[bc[ip + 1]]);",
|
||||
" ip += 2;",
|
||||
" case " + op.PUSH_EMPTY_STRING + ":", // PUSH_EMPTY_STRING
|
||||
" stack.push('');",
|
||||
" ip++;",
|
||||
" break;",
|
||||
"",
|
||||
" case " + op.PUSH_UNDEFINED + ":", // PUSH_UNDEFINED
|
||||
|
@ -363,19 +450,19 @@ function generateJS( ast, options ) {
|
|||
"",
|
||||
" case " + op.MATCH_STRING + ":", // MATCH_STRING s, a, f, ...
|
||||
indent10( generateCondition(
|
||||
"input.substr(peg$currPos, peg$consts[bc[ip + 1]].length) === peg$consts[bc[ip + 1]]",
|
||||
"input.substr(peg$currPos, peg$literals[bc[ip + 1]].length) === peg$literals[bc[ip + 1]]",
|
||||
1
|
||||
) ),
|
||||
"",
|
||||
" case " + op.MATCH_STRING_IC + ":", // MATCH_STRING_IC s, a, f, ...
|
||||
indent10( generateCondition(
|
||||
"input.substr(peg$currPos, peg$consts[bc[ip + 1]].length).toLowerCase() === peg$consts[bc[ip + 1]]",
|
||||
"input.substr(peg$currPos, peg$literals[bc[ip + 1]].length).toLowerCase() === peg$literals[bc[ip + 1]]",
|
||||
1
|
||||
) ),
|
||||
"",
|
||||
" case " + op.MATCH_REGEXP + ":", // MATCH_REGEXP r, a, f, ...
|
||||
" case " + op.MATCH_CLASS + ":", // MATCH_CLASS c, a, f, ...
|
||||
indent10( generateCondition(
|
||||
"peg$consts[bc[ip + 1]].test(input.charAt(peg$currPos))",
|
||||
"peg$regexps[bc[ip + 1]].test(input.charAt(peg$currPos))",
|
||||
1
|
||||
) ),
|
||||
"",
|
||||
|
@ -386,14 +473,14 @@ function generateJS( ast, options ) {
|
|||
" break;",
|
||||
"",
|
||||
" case " + op.ACCEPT_STRING + ":", // ACCEPT_STRING s
|
||||
" stack.push(peg$consts[bc[ip + 1]]);",
|
||||
" peg$currPos += peg$consts[bc[ip + 1]].length;",
|
||||
" stack.push(peg$literals[bc[ip + 1]]);",
|
||||
" peg$currPos += peg$literals[bc[ip + 1]].length;",
|
||||
" ip += 2;",
|
||||
" break;",
|
||||
"",
|
||||
" case " + op.EXPECT + ":", // EXPECT e
|
||||
" if (peg$silentFails === 0) {",
|
||||
" peg$expect(peg$consts[bc[ip + 1]]);",
|
||||
" peg$expect(peg$expectations[bc[ip + 1]]);",
|
||||
" }",
|
||||
" ip += 2;",
|
||||
" break;",
|
||||
|
@ -463,11 +550,6 @@ function generateJS( ast, options ) {
|
|||
const parts = [];
|
||||
const stackVars = [];
|
||||
|
||||
function c( i ) {
|
||||
|
||||
return "peg$c" + i;
|
||||
|
||||
} // |consts[i]| of the abstract machine
|
||||
function s( i ) {
|
||||
|
||||
return "s" + i;
|
||||
|
@ -596,7 +678,7 @@ function generateJS( ast, options ) {
|
|||
const baseLength = 4;
|
||||
const paramsLength = bc[ ip + baseLength - 1 ];
|
||||
|
||||
const value = c( bc[ ip + 1 ] )
|
||||
const value = f( bc[ ip + 1 ] )
|
||||
+ "("
|
||||
+ bc
|
||||
.slice( ip + baseLength, ip + baseLength + paramsLength )
|
||||
|
@ -614,9 +696,9 @@ function generateJS( ast, options ) {
|
|||
|
||||
switch ( bc[ ip ] ) {
|
||||
|
||||
case op.PUSH: // PUSH c
|
||||
parts.push( stack.push( c( bc[ ip + 1 ] ) ) );
|
||||
ip += 2;
|
||||
case op.PUSH_EMPTY_STRING: // PUSH_EMPTY_STRING
|
||||
parts.push( stack.push( "''" ) );
|
||||
ip++;
|
||||
break;
|
||||
|
||||
case op.PUSH_CURR_POS: // PUSH_CURR_POS
|
||||
|
@ -624,7 +706,7 @@ function generateJS( ast, options ) {
|
|||
ip++;
|
||||
break;
|
||||
|
||||
case op.PUSH_UNDEFINED: // PUSH_UNDEFINED
|
||||
case op.PUSH_UNDEFINED: // PUSH_UNDEFINED
|
||||
parts.push( stack.push( "undefined" ) );
|
||||
ip++;
|
||||
break;
|
||||
|
@ -708,13 +790,13 @@ function generateJS( ast, options ) {
|
|||
|
||||
case op.MATCH_STRING: // MATCH_STRING s, a, f, ...
|
||||
compileCondition(
|
||||
eval( ast.consts[ bc[ ip + 1 ] ] ).length > 1
|
||||
ast.literals[ bc[ ip + 1 ] ].length > 1
|
||||
? "input.substr(peg$currPos, "
|
||||
+ eval( ast.consts[ bc[ ip + 1 ] ] ).length
|
||||
+ ast.literals[ bc[ ip + 1 ] ].length
|
||||
+ ") === "
|
||||
+ c( bc[ ip + 1 ] )
|
||||
+ l( bc[ ip + 1 ] )
|
||||
: "input.charCodeAt(peg$currPos) === "
|
||||
+ eval( ast.consts[ bc[ ip + 1 ] ] ).charCodeAt( 0 )
|
||||
+ ast.literals[ bc[ ip + 1 ] ].charCodeAt( 0 )
|
||||
, 1
|
||||
);
|
||||
break;
|
||||
|
@ -722,15 +804,15 @@ function generateJS( ast, options ) {
|
|||
case op.MATCH_STRING_IC: // MATCH_STRING_IC s, a, f, ...
|
||||
compileCondition(
|
||||
"input.substr(peg$currPos, "
|
||||
+ eval( ast.consts[ bc[ ip + 1 ] ] ).length
|
||||
+ ast.literals[ bc[ ip + 1 ] ].length
|
||||
+ ").toLowerCase() === "
|
||||
+ c( bc[ ip + 1 ] )
|
||||
+ l( bc[ ip + 1 ] )
|
||||
, 1
|
||||
);
|
||||
break;
|
||||
|
||||
case op.MATCH_REGEXP: // MATCH_REGEXP r, a, f, ...
|
||||
compileCondition( c( bc[ ip + 1 ] ) + ".test(input.charAt(peg$currPos))", 1 );
|
||||
case op.MATCH_CLASS: // MATCH_CLASS c, a, f, ...
|
||||
compileCondition( r( bc[ ip + 1 ] ) + ".test(input.charAt(peg$currPos))", 1 );
|
||||
break;
|
||||
|
||||
case op.ACCEPT_N: // ACCEPT_N n
|
||||
|
@ -748,17 +830,17 @@ function generateJS( ast, options ) {
|
|||
break;
|
||||
|
||||
case op.ACCEPT_STRING: // ACCEPT_STRING s
|
||||
parts.push( stack.push( c( bc[ ip + 1 ] ) ) );
|
||||
parts.push( stack.push( l( bc[ ip + 1 ] ) ) );
|
||||
parts.push(
|
||||
eval( ast.consts[ bc[ ip + 1 ] ] ).length > 1
|
||||
? "peg$currPos += " + eval( ast.consts[ bc[ ip + 1 ] ] ).length + ";"
|
||||
ast.literals[ bc[ ip + 1 ] ].length > 1
|
||||
? "peg$currPos += " + ast.literals[ bc[ ip + 1 ] ].length + ";"
|
||||
: "peg$currPos++;"
|
||||
);
|
||||
ip += 2;
|
||||
break;
|
||||
|
||||
case op.EXPECT: // EXPECT e
|
||||
parts.push( "if (peg$silentFails === 0) { peg$expect(" + c( bc[ ip + 1 ] ) + "); }" );
|
||||
parts.push( "if (peg$silentFails === 0) { peg$expect(" + e( bc[ ip + 1 ] ) + "); }" );
|
||||
ip += 2;
|
||||
break;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -104,7 +104,7 @@ Grammar
|
|||
return new ast.Grammar(
|
||||
extractOptional(initializer, 0),
|
||||
extractList(rules, 0),
|
||||
location(),
|
||||
location()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,9 +18,14 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
}
|
||||
|
||||
function constsDetails( consts ) {
|
||||
function constsDetails( literals, classes, expectations, functions ) {
|
||||
|
||||
return { consts: consts };
|
||||
return {
|
||||
literals: literals,
|
||||
classes: classes,
|
||||
expectations: expectations,
|
||||
functions: functions
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
@ -34,9 +39,9 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
"c = 'c'"
|
||||
].join( "\n" ), {
|
||||
rules: [
|
||||
{ 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 ] }
|
||||
{ bytecode: [ 23, 0, 18, 0, 2, 1, 22, 0, 3 ] },
|
||||
{ bytecode: [ 23, 1, 18, 1, 2, 1, 22, 1, 3 ] },
|
||||
{ bytecode: [ 23, 2, 18, 2, 2, 1, 22, 2, 3 ] }
|
||||
]
|
||||
} );
|
||||
|
||||
|
@ -48,14 +53,16 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
"a = 'a'",
|
||||
"b = 'b'",
|
||||
"c = 'c'"
|
||||
].join( "\n" ), constsDetails( [
|
||||
"\"a\"",
|
||||
"peg$literalExpectation(\"a\", false)",
|
||||
"\"b\"",
|
||||
"peg$literalExpectation(\"b\", false)",
|
||||
"\"c\"",
|
||||
"peg$literalExpectation(\"c\", false)"
|
||||
] ) );
|
||||
].join( "\n" ), constsDetails(
|
||||
[ "a", "b", "c" ],
|
||||
[],
|
||||
[
|
||||
{ type: "literal", value: "a", ignoreCase: false },
|
||||
{ type: "literal", value: "b", ignoreCase: false },
|
||||
{ type: "literal", value: "c", ignoreCase: false }
|
||||
],
|
||||
[]
|
||||
) );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -66,7 +73,7 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( "start = 'a'", bytecodeDetails( [
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3 // <expression>
|
||||
23, 0, 18, 0, 2, 1, 22, 0, 3 // <expression>
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
@ -92,13 +99,13 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
expect( pass ).to.changeAST( grammar2, bytecodeDetails( [
|
||||
23, 0, // EXPECT <0>
|
||||
28, // SILENT_FAILS_ON
|
||||
18, 1, 2, 1, 22, 1, 3, // <expression>
|
||||
18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
29 // SILENT_FAILS_OFF
|
||||
] ) );
|
||||
expect( pass ).to.changeAST( grammar3, bytecodeDetails( [
|
||||
23, 0, // EXPECT <0>
|
||||
28, // SILENT_FAILS_ON
|
||||
20, 1, 2, 1, 21, 1, 3, // <expression>
|
||||
20, 0, 2, 1, 21, 1, 3, // <expression>
|
||||
29 // SILENT_FAILS_OFF
|
||||
] ) );
|
||||
|
||||
|
@ -106,17 +113,24 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar1, constsDetails( [
|
||||
"peg$otherExpectation(\"start\")"
|
||||
] ) );
|
||||
expect( pass ).to.changeAST( grammar2, constsDetails( [
|
||||
"peg$otherExpectation(\"start\")",
|
||||
"\"a\""
|
||||
] ) );
|
||||
expect( pass ).to.changeAST( grammar3, constsDetails( [
|
||||
"peg$otherExpectation(\"start\")",
|
||||
"/^[a]/"
|
||||
] ) );
|
||||
expect( pass ).to.changeAST( grammar1, constsDetails(
|
||||
[],
|
||||
[],
|
||||
[ { type: "rule", value: "start" } ],
|
||||
[]
|
||||
) );
|
||||
expect( pass ).to.changeAST( grammar2, constsDetails(
|
||||
[ "a" ],
|
||||
[],
|
||||
[ { type: "rule", value: "start" } ],
|
||||
[]
|
||||
) );
|
||||
expect( pass ).to.changeAST( grammar3, constsDetails(
|
||||
[],
|
||||
[ { value: [ "a" ], inverted: false, ignoreCase: false } ],
|
||||
[ { type: "rule", value: "start" } ],
|
||||
[]
|
||||
) );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -140,13 +154,15 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar1, constsDetails( [] ), {}, { reportFailures: false } );
|
||||
expect( pass ).to.changeAST( grammar2, constsDetails( [
|
||||
"\"a\""
|
||||
] ), {}, { reportFailures: false } );
|
||||
expect( pass ).to.changeAST( grammar3, constsDetails( [
|
||||
"/^[a]/"
|
||||
] ), {}, { reportFailures: false } );
|
||||
expect( pass ).to.changeAST( grammar1, constsDetails(
|
||||
[], [], [], []
|
||||
), {}, { reportFailures: false } );
|
||||
expect( pass ).to.changeAST( grammar2, constsDetails(
|
||||
[ "a" ], [], [], []
|
||||
), {}, { reportFailures: false } );
|
||||
expect( pass ).to.changeAST( grammar3, constsDetails(
|
||||
[], [ { value: [ "a" ], inverted: false, ignoreCase: false } ], [], []
|
||||
), {}, { reportFailures: false } );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -159,13 +175,13 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( "start = 'a' / 'b' / 'c'", bytecodeDetails( [
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <alternatives[0]>
|
||||
23, 0, 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]>
|
||||
23, 1, 18, 1, 2, 1, 22, 1, 3, // <alternatives[1]>
|
||||
14, 10, 0, // IF_ERROR
|
||||
6, // * POP
|
||||
23, 5, 18, 4, 2, 1, 22, 4, 3 // <alternatives[2]>
|
||||
23, 2, 18, 2, 2, 1, 22, 2, 3 // <alternatives[2]>
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
@ -182,10 +198,10 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
5, // PUSH_CURR_POS
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
23, 0, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
15, 6, 0, // IF_NOT_ERROR
|
||||
24, 1, // * LOAD_SAVED_POS
|
||||
26, 2, 1, 0, // CALL
|
||||
26, 0, 1, 0, // CALL <0>
|
||||
9 // NIP
|
||||
] ) );
|
||||
|
||||
|
@ -193,11 +209,12 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, constsDetails( [
|
||||
"\"a\"",
|
||||
"peg$literalExpectation(\"a\", false)",
|
||||
"function() { code }"
|
||||
] ) );
|
||||
expect( pass ).to.changeAST( grammar, constsDetails(
|
||||
[ "a" ],
|
||||
[],
|
||||
[ { type: "literal", value: "a", ignoreCase: false } ],
|
||||
[ { predicate: false, params: [], body: " code " } ]
|
||||
) );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -211,10 +228,10 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
5, // PUSH_CURR_POS
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
23, 0, 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
|
||||
26, 0, 1, 1, 0, // CALL <0>
|
||||
9 // NIP
|
||||
] ) );
|
||||
|
||||
|
@ -222,11 +239,12 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, constsDetails( [
|
||||
"\"a\"",
|
||||
"peg$literalExpectation(\"a\", false)",
|
||||
"function(a) { code }"
|
||||
] ) );
|
||||
expect( pass ).to.changeAST( grammar, constsDetails(
|
||||
[ "a" ],
|
||||
[],
|
||||
[ { type: "literal", value: "a", ignoreCase: false } ],
|
||||
[ { predicate: false, params: [ "a" ], body: " code " } ]
|
||||
) );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -240,14 +258,14 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
5, // PUSH_CURR_POS
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <elements[0]>
|
||||
23, 0, 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]>
|
||||
23, 1, 18, 1, 2, 1, 22, 1, 3, // * <elements[1]>
|
||||
15, 25, 4, // IF_NOT_ERROR
|
||||
23, 5, 18, 4, 2, 1, 22, 4, 3, // * <elements[2]>
|
||||
23, 2, 18, 2, 2, 1, 22, 2, 3, // * <elements[2]>
|
||||
15, 9, 4, // IF_NOT_ERROR
|
||||
24, 3, // * LOAD_SAVED_POS
|
||||
26, 6, 4, 3, 2, 1, 0, // CALL <6>
|
||||
26, 0, 4, 3, 2, 1, 0, // CALL <0>
|
||||
8, 3, // * POP_N
|
||||
7, // POP_CURR_POS
|
||||
3, // PUSH_FAILED
|
||||
|
@ -263,15 +281,16 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, constsDetails( [
|
||||
"\"a\"",
|
||||
"peg$literalExpectation(\"a\", false)",
|
||||
"\"b\"",
|
||||
"peg$literalExpectation(\"b\", false)",
|
||||
"\"c\"",
|
||||
"peg$literalExpectation(\"c\", false)",
|
||||
"function(a, b, c) { code }"
|
||||
] ) );
|
||||
expect( pass ).to.changeAST( grammar, constsDetails(
|
||||
[ "a", "b", "c" ],
|
||||
[],
|
||||
[
|
||||
{ type: "literal", value: "a", ignoreCase: false },
|
||||
{ type: "literal", value: "b", ignoreCase: false },
|
||||
{ type: "literal", value: "c", ignoreCase: false }
|
||||
],
|
||||
[ { predicate: false, params: [ "a", "b", "c" ], body: " code " } ]
|
||||
) );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -287,11 +306,11 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
5, // PUSH_CURR_POS
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <elements[0]>
|
||||
23, 0, 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]>
|
||||
23, 1, 18, 1, 2, 1, 22, 1, 3, // * <elements[1]>
|
||||
15, 19, 4, // IF_NOT_ERROR
|
||||
23, 5, 18, 4, 2, 1, 22, 4, 3, // * <elements[2]>
|
||||
23, 2, 18, 2, 2, 1, 22, 2, 3, // * <elements[2]>
|
||||
15, 3, 4, // IF_NOT_ERROR
|
||||
11, 3, // * WRAP
|
||||
9, // NIP
|
||||
|
@ -310,14 +329,16 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, constsDetails( [
|
||||
"\"a\"",
|
||||
"peg$literalExpectation(\"a\", false)",
|
||||
"\"b\"",
|
||||
"peg$literalExpectation(\"b\", false)",
|
||||
"\"c\"",
|
||||
"peg$literalExpectation(\"c\", false)"
|
||||
] ) );
|
||||
expect( pass ).to.changeAST( grammar, constsDetails(
|
||||
[ "a", "b", "c" ],
|
||||
[],
|
||||
[
|
||||
{ type: "literal", value: "a", ignoreCase: false },
|
||||
{ type: "literal", value: "b", ignoreCase: false },
|
||||
{ type: "literal", value: "c", ignoreCase: false }
|
||||
],
|
||||
[]
|
||||
) );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -328,7 +349,7 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( "start = a:'a'", bytecodeDetails( [
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3 // <expression>
|
||||
23, 0, 18, 0, 2, 1, 22, 0, 3 // <expression>
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
@ -341,7 +362,7 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
expect( pass ).to.changeAST( "start = $'a'", bytecodeDetails( [
|
||||
5, // PUSH_CURR_POS
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
23, 0, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
15, 2, 1, // IF_NOT_ERROR
|
||||
6, // * POP
|
||||
12, // TEXT
|
||||
|
@ -361,7 +382,7 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
5, // PUSH_CURR_POS
|
||||
38, // EXPECT_NS_BEGIN
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
23, 0, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
39, 0, // EXPECT_NS_END <false>
|
||||
15, 3, 3, // IF_NOT_ERROR
|
||||
6, // * POP
|
||||
|
@ -376,10 +397,12 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, constsDetails( [
|
||||
"\"a\"",
|
||||
"peg$literalExpectation(\"a\", false)"
|
||||
] ) );
|
||||
expect( pass ).to.changeAST( grammar, constsDetails(
|
||||
[ "a" ],
|
||||
[],
|
||||
[ { type: "literal", value: "a", ignoreCase: false } ],
|
||||
[]
|
||||
) );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -394,7 +417,7 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
5, // PUSH_CURR_POS
|
||||
38, // EXPECT_NS_BEGIN
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
23, 0, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
39, 1, // EXPECT_NS_END <true>
|
||||
14, 3, 3, // IF_ERROR
|
||||
6, // * POP
|
||||
|
@ -409,10 +432,12 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, constsDetails( [
|
||||
"\"a\"",
|
||||
"peg$literalExpectation(\"a\", false)"
|
||||
] ) );
|
||||
expect( pass ).to.changeAST( grammar, constsDetails(
|
||||
[ "a" ],
|
||||
[],
|
||||
[ { type: "literal", value: "a", ignoreCase: false } ],
|
||||
[]
|
||||
) );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -425,7 +450,7 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
23, 0, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
14, 2, 0, // IF_ERROR
|
||||
6, // * POP
|
||||
2 // PUSH_NULL
|
||||
|
@ -435,10 +460,12 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, constsDetails( [
|
||||
"\"a\"",
|
||||
"peg$literalExpectation(\"a\", false)"
|
||||
] ) );
|
||||
expect( pass ).to.changeAST( grammar, constsDetails(
|
||||
[ "a" ],
|
||||
[],
|
||||
[ { type: "literal", value: "a", ignoreCase: false } ],
|
||||
[]
|
||||
) );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -452,10 +479,10 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
4, // PUSH_EMPTY_ARRAY
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
23, 0, 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>
|
||||
23, 0, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
6 // POP
|
||||
] ) );
|
||||
|
||||
|
@ -463,10 +490,12 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, constsDetails( [
|
||||
"\"a\"",
|
||||
"peg$literalExpectation(\"a\", false)"
|
||||
] ) );
|
||||
expect( pass ).to.changeAST( grammar, constsDetails(
|
||||
[ "a" ],
|
||||
[],
|
||||
[ { type: "literal", value: "a", ignoreCase: false } ],
|
||||
[]
|
||||
) );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -480,11 +509,11 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
4, // PUSH_EMPTY_ARRAY
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
23, 0, 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>
|
||||
23, 0, 18, 0, 2, 1, 22, 0, 3, // <expression>
|
||||
6, // POP
|
||||
6, // * POP
|
||||
6, // POP
|
||||
|
@ -495,10 +524,12 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, constsDetails( [
|
||||
"\"a\"",
|
||||
"peg$literalExpectation(\"a\", false)"
|
||||
] ) );
|
||||
expect( pass ).to.changeAST( grammar, constsDetails(
|
||||
[ "a" ],
|
||||
[],
|
||||
[ { type: "literal", value: "a", ignoreCase: false } ],
|
||||
[]
|
||||
) );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -511,17 +542,19 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3 // <expression>
|
||||
23, 0, 18, 0, 2, 1, 22, 0, 3 // <expression>
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, constsDetails( [
|
||||
"\"a\"",
|
||||
"peg$literalExpectation(\"a\", false)"
|
||||
] ) );
|
||||
expect( pass ).to.changeAST( grammar, constsDetails(
|
||||
[ "a" ],
|
||||
[],
|
||||
[ { type: "literal", value: "a", ignoreCase: false } ],
|
||||
[]
|
||||
) );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -537,7 +570,7 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
25, // UPDATE_SAVED_POS
|
||||
26, 0, 0, 0, // CALL
|
||||
26, 0, 0, 0, // CALL <0>
|
||||
13, 2, 2, // IF
|
||||
6, // * POP
|
||||
1, // PUSH_UNDEFINED
|
||||
|
@ -551,7 +584,7 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
expect( pass ).to.changeAST(
|
||||
grammar,
|
||||
constsDetails( [ "function() { code }" ] )
|
||||
constsDetails( [], [], [], [ { predicate: true, params: [], body: " code " } ] )
|
||||
);
|
||||
|
||||
} );
|
||||
|
@ -566,14 +599,14 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
5, // PUSH_CURR_POS
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <elements[0]>
|
||||
23, 0, 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]>
|
||||
23, 1, 18, 1, 2, 1, 22, 1, 3, // * <elements[1]>
|
||||
15, 41, 4, // IF_NOT_ERROR
|
||||
23, 5, 18, 4, 2, 1, 22, 4, 3, // * <elements[2]>
|
||||
23, 2, 18, 2, 2, 1, 22, 2, 3, // * <elements[2]>
|
||||
15, 25, 4, // IF_NOT_ERROR
|
||||
25, // * UPDATE_SAVED_POS
|
||||
26, 6, 0, 3, 2, 1, 0, // CALL
|
||||
26, 0, 0, 3, 2, 1, 0, // CALL <0>
|
||||
13, 2, 2, // IF
|
||||
6, // * POP
|
||||
1, // PUSH_UNDEFINED
|
||||
|
@ -600,15 +633,16 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, constsDetails( [
|
||||
"\"a\"",
|
||||
"peg$literalExpectation(\"a\", false)",
|
||||
"\"b\"",
|
||||
"peg$literalExpectation(\"b\", false)",
|
||||
"\"c\"",
|
||||
"peg$literalExpectation(\"c\", false)",
|
||||
"function(a, b, c) { code }"
|
||||
] ) );
|
||||
expect( pass ).to.changeAST( grammar, constsDetails(
|
||||
[ "a", "b", "c" ],
|
||||
[],
|
||||
[
|
||||
{ type: "literal", value: "a", ignoreCase: false },
|
||||
{ type: "literal", value: "b", ignoreCase: false },
|
||||
{ type: "literal", value: "c", ignoreCase: false }
|
||||
],
|
||||
[ { predicate: true, params: [ "a", "b", "c" ], body: " code " } ]
|
||||
) );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -626,7 +660,7 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
25, // UPDATE_SAVED_POS
|
||||
26, 0, 0, 0, // CALL
|
||||
26, 0, 0, 0, // CALL <0>
|
||||
13, 2, 2, // IF
|
||||
6, // * POP
|
||||
3, // PUSH_FAILED
|
||||
|
@ -640,7 +674,7 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
expect( pass ).to.changeAST(
|
||||
grammar,
|
||||
constsDetails( [ "function() { code }" ] )
|
||||
constsDetails( [], [], [], [ { predicate: true, params: [], body: " code " } ] )
|
||||
);
|
||||
|
||||
} );
|
||||
|
@ -655,14 +689,14 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
5, // PUSH_CURR_POS
|
||||
23, 1, 18, 0, 2, 1, 22, 0, 3, // <elements[0]>
|
||||
23, 0, 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]>
|
||||
23, 1, 18, 1, 2, 1, 22, 1, 3, // * <elements[1]>
|
||||
15, 41, 4, // IF_NOT_ERROR
|
||||
23, 5, 18, 4, 2, 1, 22, 4, 3, // * <elements[2]>
|
||||
23, 2, 18, 2, 2, 1, 22, 2, 3, // * <elements[2]>
|
||||
15, 25, 4, // IF_NOT_ERROR
|
||||
25, // * UPDATE_SAVED_POS
|
||||
26, 6, 0, 3, 2, 1, 0, // CALL
|
||||
26, 0, 0, 3, 2, 1, 0, // CALL <0>
|
||||
13, 2, 2, // IF
|
||||
6, // * POP
|
||||
3, // PUSH_FAILED
|
||||
|
@ -689,15 +723,16 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, constsDetails( [
|
||||
"\"a\"",
|
||||
"peg$literalExpectation(\"a\", false)",
|
||||
"\"b\"",
|
||||
"peg$literalExpectation(\"b\", false)",
|
||||
"\"c\"",
|
||||
"peg$literalExpectation(\"c\", false)",
|
||||
"function(a, b, c) { code }"
|
||||
] ) );
|
||||
expect( pass ).to.changeAST( grammar, constsDetails(
|
||||
[ "a", "b", "c" ],
|
||||
[],
|
||||
[
|
||||
{ type: "literal", value: "a", ignoreCase: false },
|
||||
{ type: "literal", value: "b", ignoreCase: false },
|
||||
{ type: "literal", value: "c", ignoreCase: false }
|
||||
],
|
||||
[ { predicate: true, params: [ "a", "b", "c" ], body: " code " } ]
|
||||
) );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -736,14 +771,14 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
0, 0 // PUSH
|
||||
0 // PUSH_EMPTY_STRING
|
||||
] ) );
|
||||
|
||||
} );
|
||||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, constsDetails( [ "\"\"" ] ) );
|
||||
expect( pass ).to.changeAST( grammar, constsDetails( [], [], [], [] ) );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -756,9 +791,9 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
23, 1, // EXPECT <1>
|
||||
23, 0, // EXPECT <0>
|
||||
18, 0, 2, 1, // MATCH_STRING <0>
|
||||
22, 0, // * ACCEPT_STRING
|
||||
22, 0, // * ACCEPT_STRING <0>
|
||||
3 // * PUSH_FAILED
|
||||
] ) );
|
||||
|
||||
|
@ -766,10 +801,12 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, constsDetails( [
|
||||
"\"a\"",
|
||||
"peg$literalExpectation(\"a\", false)"
|
||||
] ) );
|
||||
expect( pass ).to.changeAST( grammar, constsDetails(
|
||||
[ "a" ],
|
||||
[],
|
||||
[ { type: "literal", value: "a", ignoreCase: false } ],
|
||||
[]
|
||||
) );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -782,9 +819,9 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
23, 1, // EXPECT <1>
|
||||
23, 0, // EXPECT <0>
|
||||
19, 0, 2, 1, // MATCH_STRING_IC <0>
|
||||
21, 1, // * ACCEPT_N
|
||||
21, 1, // * ACCEPT_N <1>
|
||||
3 // * PUSH_FAILED
|
||||
] ) );
|
||||
|
||||
|
@ -792,10 +829,12 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, constsDetails( [
|
||||
"\"a\"",
|
||||
"peg$literalExpectation(\"A\", true)"
|
||||
] ) );
|
||||
expect( pass ).to.changeAST( grammar, constsDetails(
|
||||
[ "a" ],
|
||||
[],
|
||||
[ { type: "literal", value: "A", ignoreCase: true } ],
|
||||
[]
|
||||
) );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -812,14 +851,14 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
0, 0 // PUSH
|
||||
0 // PUSH_EMPTY_STRING
|
||||
] ), {}, { reportFailures: false } );
|
||||
|
||||
} );
|
||||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, constsDetails( [ "\"\"" ] ), {}, { reportFailures: false } );
|
||||
expect( pass ).to.changeAST( grammar, constsDetails( [], [], [], [] ), {}, { reportFailures: false } );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -833,7 +872,7 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
18, 0, 2, 1, // MATCH_STRING <0>
|
||||
22, 0, // * ACCEPT_STRING
|
||||
22, 0, // * ACCEPT_STRING <0>
|
||||
3 // * PUSH_FAILED
|
||||
] ), {}, { reportFailures: false } );
|
||||
|
||||
|
@ -841,9 +880,9 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, constsDetails( [
|
||||
"\"a\""
|
||||
] ), {}, { reportFailures: false } );
|
||||
expect( pass ).to.changeAST( grammar, constsDetails(
|
||||
[ "a" ], [], [], []
|
||||
), {}, { reportFailures: false } );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -857,7 +896,7 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
19, 0, 2, 1, // MATCH_STRING_IC <0>
|
||||
21, 1, // * ACCEPT_N
|
||||
21, 1, // * ACCEPT_N <1>
|
||||
3 // * PUSH_FAILED
|
||||
] ), {}, { reportFailures: false } );
|
||||
|
||||
|
@ -865,9 +904,9 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( grammar, constsDetails( [
|
||||
"\"a\""
|
||||
] ), {}, { reportFailures: false } );
|
||||
expect( pass ).to.changeAST( grammar, constsDetails(
|
||||
[ "a" ], [], [], []
|
||||
), {}, { reportFailures: false } );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -884,9 +923,9 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( "start = [a]", bytecodeDetails( [
|
||||
23, 1, // EXPECT <1>
|
||||
20, 0, 2, 1, // MATCH_REGEXP <0>
|
||||
21, 1, // * ACCEPT_N
|
||||
23, 0, // EXPECT <0>
|
||||
20, 0, 2, 1, // MATCH_CLASS <0>
|
||||
21, 1, // * ACCEPT_N <1>
|
||||
3 // * PUSH_FAILED
|
||||
] ) );
|
||||
|
||||
|
@ -896,10 +935,12 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( "start = [a]", constsDetails( [
|
||||
"/^[a]/",
|
||||
"peg$classExpectation([\"a\"], false, false)"
|
||||
] ) );
|
||||
expect( pass ).to.changeAST( "start = [a]", constsDetails(
|
||||
[],
|
||||
[ { value: [ "a" ], inverted: false, ignoreCase: false } ],
|
||||
[ { type: "class", value: [ "a" ], inverted: false, ignoreCase: false } ],
|
||||
[]
|
||||
) );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -909,10 +950,12 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( "start = [^a]", constsDetails( [
|
||||
"/^[^a]/",
|
||||
"peg$classExpectation([\"a\"], true, false)"
|
||||
] ) );
|
||||
expect( pass ).to.changeAST( "start = [^a]", constsDetails(
|
||||
[],
|
||||
[ { value: [ "a" ], inverted: true, ignoreCase: false } ],
|
||||
[ { type: "class", value: [ "a" ], inverted: true, ignoreCase: false } ],
|
||||
[]
|
||||
) );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -922,10 +965,12 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( "start = [a]i", constsDetails( [
|
||||
"/^[a]/i",
|
||||
"peg$classExpectation([\"a\"], false, true)"
|
||||
] ) );
|
||||
expect( pass ).to.changeAST( "start = [a]i", constsDetails(
|
||||
[],
|
||||
[ { value: [ "a" ], inverted: false, ignoreCase: true } ],
|
||||
[ { type: "class", value: [ "a" ], inverted: false, ignoreCase: true } ],
|
||||
[]
|
||||
) );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -935,10 +980,25 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( "start = [ab-def-hij-l]", constsDetails( [
|
||||
"/^[ab-def-hij-l]/",
|
||||
"peg$classExpectation([\"a\", [\"b\", \"d\"], \"e\", [\"f\", \"h\"], \"i\", [\"j\", \"l\"]], false, false)"
|
||||
] ) );
|
||||
expect( pass ).to.changeAST( "start = [ab-def-hij-l]", constsDetails(
|
||||
[],
|
||||
[
|
||||
{
|
||||
value: [ "a", [ "b", "d" ], "e", [ "f", "h" ], "i", [ "j", "l" ] ],
|
||||
inverted: false,
|
||||
ignoreCase: false
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
type: "class",
|
||||
value: [ "a", [ "b", "d" ], "e", [ "f", "h" ], "i", [ "j", "l" ] ],
|
||||
inverted: false,
|
||||
ignoreCase: false
|
||||
}
|
||||
],
|
||||
[]
|
||||
) );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -951,8 +1011,8 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
it( "generates correct bytecode", function () {
|
||||
|
||||
expect( pass ).to.changeAST( "start = [a]", bytecodeDetails( [
|
||||
20, 0, 2, 1, // MATCH_REGEXP <0>
|
||||
21, 1, // * ACCEPT_N
|
||||
20, 0, 2, 1, // MATCH_CLASS <0>
|
||||
21, 1, // * ACCEPT_N <1>
|
||||
3 // * PUSH_FAILED
|
||||
] ), {}, { reportFailures: false } );
|
||||
|
||||
|
@ -962,9 +1022,9 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( "start = [a]", constsDetails( [
|
||||
"/^[a]/"
|
||||
] ), {}, { reportFailures: false } );
|
||||
expect( pass ).to.changeAST( "start = [a]", constsDetails(
|
||||
[], [ { value: [ "a" ], inverted: false, ignoreCase: false } ], [], []
|
||||
), {}, { reportFailures: false } );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -974,9 +1034,9 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( "start = [^a]", constsDetails( [
|
||||
"/^[^a]/"
|
||||
] ), {}, { reportFailures: false } );
|
||||
expect( pass ).to.changeAST( "start = [^a]", constsDetails(
|
||||
[], [ { value: [ "a" ], inverted: true, ignoreCase: false } ], [], []
|
||||
), {}, { reportFailures: false } );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -986,9 +1046,9 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( "start = [a]i", constsDetails( [
|
||||
"/^[a]/i"
|
||||
] ), {}, { reportFailures: false } );
|
||||
expect( pass ).to.changeAST( "start = [a]i", constsDetails(
|
||||
[], [ { value: [ "a" ], inverted: false, ignoreCase: true } ], [], []
|
||||
), {}, { reportFailures: false } );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -998,9 +1058,18 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
it( "defines correct constants", function () {
|
||||
|
||||
expect( pass ).to.changeAST( "start = [ab-def-hij-l]", constsDetails( [
|
||||
"/^[ab-def-hij-l]/"
|
||||
] ), {}, { reportFailures: false } );
|
||||
expect( pass ).to.changeAST( "start = [ab-def-hij-l]", constsDetails(
|
||||
[],
|
||||
[
|
||||
{
|
||||
value: [ "a", [ "b", "d" ], "e", [ "f", "h" ], "i", [ "j", "l" ] ],
|
||||
inverted: false,
|
||||
ignoreCase: false
|
||||
}
|
||||
],
|
||||
[],
|
||||
[]
|
||||
), {}, { reportFailures: false } );
|
||||
|
||||
} );
|
||||
|
||||
|
@ -1021,7 +1090,7 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
23, 0, // EXPECT <0>
|
||||
17, 2, 1, // MATCH_ANY
|
||||
21, 1, // * ACCEPT_N
|
||||
21, 1, // * ACCEPT_N <1>
|
||||
3 // * PUSH_FAILED
|
||||
] ) );
|
||||
|
||||
|
@ -1031,7 +1100,7 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
expect( pass ).to.changeAST(
|
||||
grammar,
|
||||
constsDetails( [ "peg$anyExpectation()" ] )
|
||||
constsDetails( [], [], [ { type: "any" } ], [] )
|
||||
);
|
||||
|
||||
} );
|
||||
|
@ -1046,7 +1115,7 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
expect( pass ).to.changeAST( grammar, bytecodeDetails( [
|
||||
17, 2, 1, // MATCH_ANY
|
||||
21, 1, // * ACCEPT_N
|
||||
21, 1, // * ACCEPT_N <1>
|
||||
3 // * PUSH_FAILED
|
||||
] ), {}, { reportFailures: false } );
|
||||
|
||||
|
@ -1056,7 +1125,7 @@ describe( "compiler pass |generateBytecode|", function () {
|
|||
|
||||
expect( pass ).to.changeAST(
|
||||
grammar,
|
||||
constsDetails( [] ),
|
||||
constsDetails( [], [], [], [] ),
|
||||
{},
|
||||
{ reportFailures: false }
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue