Advertisement
Guest User

Untitled

a guest
Jul 4th, 2017
145
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const Parsimmon = require('parsimmon');
  2. const {fail, lazy} = Parsimmon;
  3.  
  4. const SIN_MAX = 10;
  5. const indLog = (...args) => console.log(logIndent, ...args);
  6. const logDebug = false;
  7. const logAnnotations = false;
  8. const fullValues = true;
  9. const okDetails = true;
  10. const logFails = true;
  11.  
  12. let sinCounter = 0;
  13. let logIndent = '';
  14. let stack = [];
  15.  
  16. const captureStack = (type, tag, i) => {
  17.     stack = [...stack, [type, tag, i]];
  18. };
  19.  
  20. const reportStack = (stack, input) => {
  21.     return stack
  22.         .map(([type, tag, i]) =>
  23.             logIndent + '   ' + tag + ' : '.yellow +
  24.             reportPos(input, i) + ' ' +
  25.             shortCodeRef(input, i)
  26.         )
  27.         .join('\n');
  28. };
  29.  
  30. const reportPos = (inp, i) => {
  31.     const lines = inp.slice(0, i).split(/([\n\r][\n\r]?)/g);
  32.     const pos = i - lines.slice(0, -1).join('').length;
  33.     return `${Math.round(lines.length/2)}:${pos}`;
  34. };
  35.  
  36. const shortCodeRef = (input, i) => JSON.stringify(input.slice(i, i + 30) + '...');
  37.  
  38. Parsimmon.prototype.breakOnRepeat = function (tag) {
  39.     let visited = {};
  40.     let n = 0;
  41.     return Parsimmon((input, i) => {
  42.         const visitLabel = tag + '-' + n++;
  43.         indLog(visitLabel.yellow, shortCodeRef(input, i));
  44.         captureStack('break', visitLabel, i);
  45.         if (visited[i]) {
  46.             sinCounter++;
  47.             indLog((`${tag} already visited position ${i} (${shortCodeRef(input, i)}). Visit label was ` + `${visited[i][0]}`.yellow).bgRed);
  48.             if (sinCounter >= SIN_MAX) {
  49.                 console.log('\n\n\n');
  50.                 indLog('stack was: ');
  51.                 console.log(reportStack(visited[i][1], input));
  52.                 indLog('stack now:');
  53.                 console.log(reportStack(stack, input));
  54.                 console.log('\n\n\n');
  55.                 throw new Error(`you are bloody sinner`);
  56.             }
  57.         }
  58.         visited[i] = [visitLabel, stack];
  59.         const result = this._(input, i);
  60.         stack = stack.slice(0, -1);
  61.         return result;
  62.     });
  63. };
  64.  
  65. const stripMiddle = (s, n=50) => s.length < (n + 3) ? s : s.slice(0, n/2) + '...' + s.slice(-n/2);
  66.  
  67. Parsimmon.prototype.log = function (tag, highlightTag = false) {
  68.     if (highlightTag) {
  69.         tag = '['.bgBlue + tag + ']'.bgBlue
  70.     }
  71.     require('colors');
  72.     return Parsimmon((input, i) => {
  73.         const oldLogIndent = logIndent;
  74.         indLog(tag, shortCodeRef(input, i));
  75.         logIndent += '  ';
  76.         captureStack('log', tag, i);
  77.         const result = this._(input, i);
  78.         stack = stack.slice(0, -1);
  79.  
  80.         if (result.status) {
  81.             const before = '...' + JSON.stringify(input.slice(i - 5, i)).slice(1, -1);
  82.             const match = '['.yellow + stripMiddle(JSON.stringify(input.slice(i, result.index)).slice(1, -1)).green + ']'.yellow;
  83.             const after = JSON.stringify(input.slice(result.index, result.index + 5)).slice(1, -1) + '...';
  84.  
  85.             const valueReport = fullValues ? JSON.stringify(result.value) : stripMiddle(JSON.stringify(result.value));
  86.             const okDetailsReport = okDetails ? before + match + after + ' => ' + valueReport : valueReport;
  87.             indLog(`ok(${tag})`.green, okDetailsReport);
  88.         } else {
  89.             logFails && indLog(`fail(${tag}) ${shortCodeRef(input, i)}`.red);
  90.         }
  91.  
  92.         logIndent = oldLogIndent;
  93.  
  94.         return result;
  95.     });
  96. };
  97.  
  98. const seqAnnotate = (tag, ...parsers) => Parsimmon.seq(...parsers).annotate(tag);
  99.  
  100. Parsimmon.prototype.debug = function (tag, hightlightTag) {
  101.     if (logDebug) {
  102.         return this.log(tag, hightlightTag);
  103.     }
  104.     return this;
  105. };
  106.  
  107. const value = (v) => Parsimmon((input, i) => Parsimmon.makeSuccess(i, v));
  108. const offset = Parsimmon((input, i) => Parsimmon.makeSuccess(i, i));
  109.  
  110. Parsimmon.prototype.annotate = function (type, highlightTag = false) {
  111.     const parser = Parsimmon.seqObj(
  112.         ['type', value(type)],
  113.         ['start', offset],
  114.         ['value', this],
  115.         ['end', offset]
  116.     );
  117.  
  118.     if (logAnnotations) {
  119.         return parser.log(type, highlightTag);
  120.     }
  121.     return parser;
  122. };
  123.  
  124. Parsimmon.prototype.spaced = function () {
  125.     return spaced(this);
  126. };
  127.  
  128. const logger = tag => x => {
  129.     console.log(tag, JSON.stringify(x));
  130.     return x;
  131. };
  132.  
  133. const stats = {};
  134. const count = tag => x => {
  135.     stats[tag] = (stats[tag] || 0) + 1;
  136.     return x;
  137. };
  138.  
  139. module.exports = {
  140.     logger,
  141.     spaced,
  142.     count,
  143.     stats,
  144.     seqAnnotate
  145. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement