@ -1,24 +1,23 @@
"use strict" ;
let asts = require ( "../asts" ) ,
op = require ( "../opcodes" ) ,
js = require ( "../js" ) ;
let asts = require ( "../asts" ) ;
let op = require ( "../opcodes" ) ;
let js = require ( "../js" ) ;
/* Generates parser JavaScript code. */
function generateJS ( ast , options ) {
/* These only indent non-empty lines to avoid trailing whitespace. */
function indent2 ( code ) { return code . replace ( /^(.+)$/gm , ' $1' ) ; }
function indent6 ( code ) { return code . replace ( /^(.+)$/gm , ' $1' ) ; }
function indent10 ( code ) { return code . replace ( /^(.+)$/gm , ' $1' ) ; }
function generateTables ( ) {
if ( options . optimize === "size" ) {
return [
' peg$consts = [',
' var peg$consts = [',
indent2 ( ast . consts . join ( ',\n' ) ) ,
'] , ',
'] ; ',
'' ,
' peg$bytecode = [',
' var peg$bytecode = [',
indent2 ( ast . rules . map ( rule =>
'peg$decode("'
+ js . stringEscape ( rule . bytecode . map (
@ -26,10 +25,10 @@ function generateJS(ast, options) {
) . join ( '' ) )
+ '")'
) . join ( ',\n' ) ) ,
'] , '
'] ; '
] . join ( '\n' ) ;
} else {
return ast . consts . map ( ( c , i ) => ' peg$c' + i + ' = ' + c + ' , ') . join ( '\n' ) ;
return ast . consts . map ( ( c , i ) => ' var peg$c' + i + ' = ' + c + ' ; ') . join ( '\n' ) ;
}
}
@ -51,8 +50,8 @@ function generateJS(ast, options) {
if ( options . cache ) {
parts . push ( [
'var key = peg$currPos * ' + ast . rules . length + ' + ' + ruleIndexCode + ' , ',
' cached = peg$resultsCache[key];',
'var key = peg$currPos * ' + ast . rules . length + ' + ' + ruleIndexCode + ' ; ',
' var cached = peg$resultsCache[key];',
'' ,
'if (cached) {' ,
' peg$currPos = cached.nextPos;' ,
@ -131,9 +130,9 @@ function generateJS(ast, options) {
let parts = [ ] ;
function generateCondition ( cond , argsLength ) {
let baseLength = argsLength + 3 ,
thenLengthCode = 'bc[ip + ' + ( baseLength - 2 ) + ']' ,
elseLengthCode = 'bc[ip + ' + ( baseLength - 1 ) + ']' ;
let baseLength = argsLength + 3 ;
let thenLengthCode = 'bc[ip + ' + ( baseLength - 2 ) + ']' ;
let elseLengthCode = 'bc[ip + ' + ( baseLength - 1 ) + ']' ;
return [
'ends.push(end);' ,
@ -152,8 +151,8 @@ function generateJS(ast, options) {
}
function generateLoop ( cond ) {
let baseLength = 2 ,
bodyLengthCode = 'bc[ip + ' + ( baseLength - 1 ) + ']' ;
let baseLength = 2 ;
let bodyLengthCode = 'bc[ip + ' + ( baseLength - 1 ) + ']' ;
return [
'if (' + cond + ') {' ,
@ -171,8 +170,8 @@ function generateJS(ast, options) {
}
function generateCall ( ) {
let baseLength = 4 ,
paramsLengthCode = 'bc[ip + ' + ( baseLength - 1 ) + ']' ;
let baseLength = 4 ;
let paramsLengthCode = 'bc[ip + ' + ( baseLength - 1 ) + ']' ;
return [
'params = bc.slice(ip + ' + baseLength + ', ip + ' + baseLength + ' + ' + paramsLengthCode + ')' ,
@ -199,24 +198,24 @@ function generateJS(ast, options) {
if ( options . trace ) {
parts . push ( [
' var bc = peg$bytecode[index] , ',
' ip = 0, ',
' ips = [], ',
' end = bc.length, ',
' ends = [], ',
' stack = [], ',
' startPos = peg$currPos, ',
' params;'
' var bc = peg$bytecode[index] ; ',
' var ip = 0; ',
' var ips = []; ',
' var end = bc.length; ',
' var ends = []; ',
' var stack = []; ',
' var startPos = peg$currPos; ',
' var params;'
] . join ( '\n' ) ) ;
} else {
parts . push ( [
' var bc = peg$bytecode[index] , ',
' ip = 0, ',
' ips = [], ',
' end = bc.length, ',
' ends = [], ',
' stack = [], ',
' params;'
' var bc = peg$bytecode[index] ; ',
' var ip = 0; ',
' var ips = []; ',
' var end = bc.length; ',
' var ends = []; ',
' var stack = []; ',
' var params;'
] . join ( '\n' ) ) ;
}
@ -406,9 +405,9 @@ function generateJS(ast, options) {
}
function generateRuleFunction ( rule ) {
let parts = [ ] ,
stackVars = [ ] ,
code ;
let parts = [ ] ;
let stackVars = [ ] ;
let code ;
function c ( i ) { return "peg$c" + i ; } // |consts[i]| of the abstract machine
function s ( i ) { return "s" + i ; } // |stack[i]| of the abstract machine
@ -451,17 +450,17 @@ function generateJS(ast, options) {
} ;
function compile ( bc ) {
let ip = 0 ,
end = bc . length ,
parts = [ ] ,
value ;
let ip = 0 ;
let end = bc . length ;
let parts = [ ] ;
let value ;
function compileCondition ( cond , argCount ) {
let baseLength = argCount + 3 ,
thenLength = bc [ ip + baseLength - 2 ] ,
elseLength = bc [ ip + baseLength - 1 ] ,
baseSp = stack . sp ,
thenCode , elseCode , thenSp , elseSp ;
let baseLength = argCount + 3 ;
let thenLength = bc [ ip + baseLength - 2 ] ;
let elseLength = bc [ ip + baseLength - 1 ] ;
let baseSp = stack . sp ;
let thenCode , elseCode , thenSp , elseSp ;
ip += baseLength ;
thenCode = compile ( bc . slice ( ip , ip + thenLength ) ) ;
@ -491,10 +490,10 @@ function generateJS(ast, options) {
}
function compileLoop ( cond ) {
let baseLength = 2 ,
bodyLength = bc [ ip + baseLength - 1 ] ,
baseSp = stack . sp ,
bodyCode , bodySp ;
let baseLength = 2 ;
let bodyLength = bc [ ip + baseLength - 1 ] ;
let baseSp = stack . sp ;
let bodyCode , bodySp ;
ip += baseLength ;
bodyCode = compile ( bc . slice ( ip , ip + bodyLength ) ) ;
@ -511,8 +510,8 @@ function generateJS(ast, options) {
}
function compileCall ( ) {
let baseLength = 4 ,
paramsLength = bc [ ip + baseLength - 1 ] ;
let baseLength = 4 ;
let paramsLength = bc [ ip + baseLength - 1 ] ;
let value = c ( bc [ ip + 1 ] ) + '('
+ bc . slice ( ip + baseLength , ip + baseLength + paramsLength ) . map (
@ -837,8 +836,8 @@ function generateJS(ast, options) {
' }' ,
'' ,
' function describeExpected(expected) {' ,
' var descriptions = expected.map(describeExpectation) , ',
' i, j;',
' var descriptions = expected.map(describeExpectation) ; ',
' var i, j;',
'' ,
' descriptions.sort();' ,
'' ,
@ -937,7 +936,7 @@ function generateJS(ast, options) {
'function peg$parse(input, options) {' ,
' options = options !== undefined ? options : {};' ,
'' ,
' var peg$FAILED = {} , ',
' var peg$FAILED = {} ; ',
''
] . join ( '\n' ) ) ;
@ -950,8 +949,8 @@ function generateJS(ast, options) {
let startRuleIndex = asts . indexOfRule ( ast , options . allowedStartRules [ 0 ] ) ;
parts . push ( [
' peg$startRuleIndices = ' + startRuleIndices + ', ',
' peg$startRuleIndex = ' + startRuleIndex + ', '
' var peg$startRuleIndices = ' + startRuleIndices + '; ',
' var peg$startRuleIndex = ' + startRuleIndex + '; '
] . join ( '\n' ) ) ;
} else {
let startRuleFunctions = '{ '
@ -962,29 +961,29 @@ function generateJS(ast, options) {
let startRuleFunction = 'peg$parse' + options . allowedStartRules [ 0 ] ;
parts . push ( [
' peg$startRuleFunctions = ' + startRuleFunctions + ', ',
' peg$startRuleFunction = ' + startRuleFunction + ', '
' var peg$startRuleFunctions = ' + startRuleFunctions + '; ',
' var peg$startRuleFunction = ' + startRuleFunction + '; '
] . join ( '\n' ) ) ;
}
parts . push ( '' ) ;
parts . push ( indent 6 ( generateTables ( ) ) ) ;
parts . push ( indent 2 ( generateTables ( ) ) ) ;
parts . push ( [
'' ,
' peg$currPos = 0, ',
' peg$savedPos = 0, ',
' peg$posDetailsCache = [{ line: 1, column: 1 }], ',
' peg$maxFailPos = 0, ',
' peg$maxFailExpected = [], ',
' peg$silentFails = 0, ', // 0 = report failures, > 0 = silence failures
' var peg$currPos = 0; ',
' var peg$savedPos = 0; ',
' var peg$posDetailsCache = [{ line: 1, column: 1 }]; ',
' var peg$maxFailPos = 0; ',
' var peg$maxFailExpected = []; ',
' var peg$silentFails = 0; ', // 0 = report failures, > 0 = silence failures
''
] . join ( '\n' ) ) ;
if ( options . cache ) {
parts . push ( [
' peg$resultsCache = {}, ',
' var peg$resultsCache = {}; ',
''
] . join ( '\n' ) ) ;
}
@ -998,19 +997,19 @@ function generateJS(ast, options) {
+ ']' ;
parts . push ( [
' peg$ruleNames = ' + ruleNames + ', ',
' var peg$ruleNames = ' + ruleNames + '; ',
''
] . join ( '\n' ) ) ;
}
parts . push ( [
' peg$tracer = "tracer" in options ? options.tracer : new peg$DefaultTracer(), ',
' var peg$tracer = "tracer" in options ? options.tracer : new peg$DefaultTracer(); ',
''
] . join ( '\n' ) ) ;
}
parts . push ( [
' peg$result;',
' var peg$result;',
''
] . join ( '\n' ) ) ;
@ -1083,7 +1082,8 @@ function generateJS(ast, options) {
' }' ,
'' ,
' function peg$computePosDetails(pos) {' ,
' var details = peg$posDetailsCache[pos], p;' ,
' var details = peg$posDetailsCache[pos];' ,
' var p;' ,
'' ,
' if (details) {' ,
' return details;' ,
@ -1116,8 +1116,8 @@ function generateJS(ast, options) {
' }' ,
'' ,
' function peg$computeLocation(startPos, endPos) {' ,
' var startPosDetails = peg$computePosDetails(startPos) , ',
' endPosDetails = peg$computePosDetails(endPos);',
' var startPosDetails = peg$computePosDetails(startPos) ; ',
' var endPosDetails = peg$computePosDetails(endPos);',
'' ,
' return {' ,
' start: {' ,
@ -1246,9 +1246,9 @@ function generateJS(ast, options) {
} ,
commonjs : function ( ) {
let parts = [ ] ,
dependencyVars = Object . keys ( options . dependencies ) ,
requires = dependencyVars . map (
let parts = [ ] ;
let dependencyVars = Object . keys ( options . dependencies ) ;
let requires = dependencyVars . map (
variable => variable
+ ' = require("'
+ js . stringEscape ( options . dependencies [ variable ] )
@ -1278,14 +1278,14 @@ function generateJS(ast, options) {
} ,
amd : function ( ) {
let dependencyVars = Object . keys ( options . dependencies ) ,
dependencyIds = dependencyIds . map ( v => options . dependencies [ v ] ) ,
dependencies = '['
let dependencyVars = Object . keys ( options . dependencies ) ;
let dependencyIds = dependencyIds . map ( v => options . dependencies [ v ] ) ;
let dependencies = '['
+ dependencyIds . map (
id => '"' + js . stringEscape ( id ) + '"'
) . join ( ', ' )
+ ']' ,
params = dependencyVars . join ( ', ' ) ;
+ ']' ;
let params = dependencyVars . join ( ', ' ) ;
return [
generateGeneratedByComment ( ) ,
@ -1315,18 +1315,18 @@ function generateJS(ast, options) {
} ,
umd : function ( ) {
let parts = [ ] ,
dependencyVars = Object . keys ( options . dependencies ) ,
dependencyIds = dependencyIds . map ( v => options . dependencies [ v ] ) ,
dependencies = '['
let parts = [ ] ;
let dependencyVars = Object . keys ( options . dependencies ) ;
let dependencyIds = dependencyIds . map ( v => options . dependencies [ v ] ) ;
let dependencies = '['
+ dependencyIds . map (
id => '"' + js . stringEscape ( id ) + '"'
) . join ( ', ' )
+ ']' ,
requires = dependencyIds . map (
+ ']' ;
let requires = dependencyIds . map (
id => 'require("' + js . stringEscape ( id ) + '")'
) . join ( ', ' ) ,
params = dependencyVars . join ( ', ' ) ;
) . join ( ', ' ) ;
let params = dependencyVars . join ( ', ' ) ;
parts . push ( [
generateGeneratedByComment ( ) ,