@ -334,6 +334,8 @@ module.exports = function(ast, options) {
' ' ,
' var pos = 0;' ,
' var reportedPos = 0;' ,
' var cachedReportedPos = 0;' ,
' var cachedReportedPosDetails = { line: 1, column: 1, seenCR: false };' ,
' var reportFailures = 0;' , // 0 = report, anything > 0 = do not report
' var rightmostFailuresPos = 0;' ,
' var rightmostFailuresExpected = [];' ,
@ -370,16 +372,48 @@ module.exports = function(ast, options) {
' return \'\\\\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), \'0\', length);' ,
' }' ,
' ' ,
' function computeReportedPosDetails() {' ,
' function advanceCachedReportedPos() {' ,
' var ch;' ,
' ' ,
' for (; cachedReportedPos < reportedPos; cachedReportedPos++) {' ,
' ch = input.charAt(cachedReportedPos);' ,
' if (ch === "\\n") {' ,
' if (!cachedReportedPosDetails.seenCR) { cachedReportedPosDetails.line++; }' ,
' cachedReportedPosDetails.column = 1;' ,
' cachedReportedPosDetails.seenCR = false;' ,
' } else if (ch === "\\r" || ch === "\\u2028" || ch === "\\u2029") {' ,
' cachedReportedPosDetails.line++;' ,
' cachedReportedPosDetails.column = 1;' ,
' cachedReportedPosDetails.seenCR = true;' ,
' } else {' ,
' cachedReportedPosDetails.column++;' ,
' cachedReportedPosDetails.seenCR = false;' ,
' }' ,
' }' ,
' }' ,
' ' ,
' if (cachedReportedPos !== reportedPos) {' ,
' if (cachedReportedPos > reportedPos) {' ,
' cachedReportedPos = 0;' ,
' cachedReportedPosDetails = { line: 1, column: 1, seenCR: false };' ,
' }' ,
' advanceCachedReportedPos();' ,
' }' ,
' ' ,
' return cachedReportedPosDetails;' ,
' }' ,
' ' ,
' function offset() {' ,
' return reportedPos;' ,
' }' ,
' ' ,
' function line() {' ,
' return computePosDetails(reportedPos).line;' ,
' return compute Reported PosDetails().line;',
' }' ,
' ' ,
' function column() {' ,
' return computePosDetails(reportedPos).column;' ,
' return compute Reported PosDetails().column;',
' }' ,
' ' ,
' function matchFailed(failure) {' ,
@ -414,37 +448,6 @@ module.exports = function(ast, options) {
' return cleanExpected;' ,
' }' ,
' ' ,
' function computePosDetails(pos) {' ,
' /*' ,
' * The first idea was to use |String.split| to break the input up to the' ,
' * error position along newlines and derive the line and column from' ,
' * there. However IE\'s |split| implementation is so broken that it was' ,
' * enough to prevent it.' ,
' */' ,
' ' ,
' var line = 1;' ,
' var column = 1;' ,
' var seenCR = false;' ,
' ' ,
' for (var i = 0; i < pos; i++) {' ,
' var ch = input.charAt(i);' ,
' if (ch === "\\n") {' ,
' if (!seenCR) { line++; }' ,
' column = 1;' ,
' seenCR = false;' ,
' } else if (ch === "\\r" || ch === "\\u2028" || ch === "\\u2029") {' ,
' line++;' ,
' column = 1;' ,
' seenCR = true;' ,
' } else {' ,
' column++;' ,
' seenCR = false;' ,
' }' ,
' }' ,
' ' ,
' return { line: line, column: column };' ,
' }' ,
' ' ,
' #if node.initializer' ,
' #block emit(node.initializer)' ,
' #end' ,
@ -476,16 +479,16 @@ module.exports = function(ast, options) {
' * handle these states.' ,
' */' ,
' if (result === null || pos !== input.length) {' ,
' var offset = Math.max(pos, rightmostFailuresPos);',
' var found = offset < input.length ? input.charAt(offset ) : null;',
' var errorPosition = computePosDetails(Math.max(pos, rightmostFailuresPos) );',
' reportedPos = Math.max(pos, rightmostFailuresPos);',
' var found = reportedPos < input.length ? input.charAt(reportedPos ) : null;',
' var reportedPosDetails = computeReportedPosDetails( );',
' ' ,
' throw new this.SyntaxError(' ,
' cleanupExpected(rightmostFailuresExpected),' ,
' found,' ,
' offset ,',
' errorPosition .line,',
' errorPosition .column',
' reportedPos ,',
' reportedPosDetails .line,',
' reportedPosDetails .column',
' );' ,
' }' ,
' ' ,