Advertisement
pexea12

Whitespace

Oct 27th, 2015
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // to help with debugging
  2. function unbleach (n) {
  3.   if (n) return n.replace(/ /g, 's').replace(/\t/g, 't').replace(/\n/g, 'n');
  4. }
  5.  
  6. var SPACE = ' ', TAB = '\t', LF = '\n';
  7.  
  8. function readNumber(code, pos) {
  9.     var sign, c;
  10.     var result = "";
  11.     if (code.charAt(pos) == SPACE) sign = 1;
  12.     else if (code.charAt(pos) == TAB) sign = -1;
  13.    
  14.     while ((c = code.charAt(pos++)) != LF) {
  15.         if (c == SPACE) result += "0";
  16.         if (c == TAB) result += "1";
  17.     }  
  18.    
  19.     --pos;
  20.    
  21.     return sign * parseInt(result, 2);
  22. }
  23.  
  24. var instructions = {
  25.     stackManinpulation: {
  26.         push: function(code, pos, stack) { stack.push(readNumber(code, pos)); },
  27.         duplicate: function(stack) { stack.push(stack[stack.length - 1]); },
  28.         swapTop: function(stack) {
  29.             var temp = stack[stack.length - 1];
  30.             stack[stack.length - 1] = stack[stack.length - 2];
  31.             stack[stack.length - 2] = temp;
  32.         },
  33.         discard: function(stack) { stack.pop(); },
  34.     },
  35.    
  36.     arithmetic: {
  37.         add: function(stack) { stack.push(stack.pop() + stack.pop()); },
  38.         subtract: function(stack) { stack.push(-stack.pop() + stack.pop()); },
  39.         multiply: function(stack) { stack.push(stack.pop() * stack.pop()); },
  40.         divide: function(stack) {
  41.             var first = stack.pop(), second = stack.pop();
  42.             stack.push(Math.floor(second / first));
  43.         },
  44.         mod: function(stack) {
  45.             var first = stack.pop(), second = stack.pop();
  46.             stack.push(second % first);
  47.         },
  48.     },
  49.    
  50.     heapAccess: {
  51.         store: function(stack, memory) {
  52.             var address = stack[stack.length - 2];
  53.             var value = stack[stack.length - 1];
  54.             memory[address] = value;
  55.         },
  56.         retrieve: function(stack, memory) {
  57.             var address = stack[stack.length - 1];
  58.             stack.push(memory[address]);
  59.         }
  60.     },
  61.    
  62.     flowControl: {
  63.         markLocation: function(code, pos, location) { location[readNumber(code, pos)] = pos - 1; },
  64.         callSubroutine: function(code, pos, location, endSub) {
  65.             var locationName = readNumber(code, pos);
  66.             endSub.push(pos);
  67.             pos = location[locationName];
  68.         },
  69.         jumpAnyway: function(code, pos, location) { pos = location[readNumber(code, pos)]; },
  70.         jumpIfZero: function(code, pos, stack, location) {
  71.             var locationName = readNumber(code, pos);
  72.             if (stack[stack.length - 1] == 0) pos = location[locationName];
  73.         },
  74.         jumpIfNegative: function(code, pos, stack, location) {
  75.             var locationName = readNumber(code, pos);
  76.             if (stack[stack.length - 1] < 0) pos = location[locationName];
  77.         },
  78.         endSubroutine: function(pos, endSub) { pos = endSub.pop(); }
  79.     },
  80.    
  81.     inAndOut: {
  82.         outputChar: function(stack, output) { output += String.fromCharCode(stack.pop()); },
  83.         outputNum: function(stack, output) { output += stack.pop().toString(); },
  84.         readChar: function(stack, input, memory) {
  85.             memory[stack[stack.length - 1]] = input.charAt(0);
  86.             input = input.substr(1);
  87.         },
  88.         readNum: function(stack, input, memory) {
  89.             memory[stack[stack.length - 1]] = input.charCodeAt(0);
  90.             input = input.substr(1);
  91.         }
  92.     }
  93. }
  94.  
  95. // solution
  96. function whitespace(code, input) {
  97.    
  98.     console.log(print(code));
  99.    
  100.     code = code.replace(/[^\s\t\n]/g, '');
  101.    
  102.     var output = '', stack = [], heap = {};
  103.     var location = {}, memory = {}, endSub = [];
  104.     var pos = 0;
  105.    
  106.  
  107.    
  108.     while (pos < code.length) {
  109.         console.log(stack);
  110.         console.log(output + " pos " + pos);
  111.         switch(code.charAt(pos++)) {
  112.             case SPACE: {
  113.                 var stackManinpulation = instructions.stackManinpulation;
  114.                 switch(code.charAt(pos++)) {
  115.                     case SPACE:
  116.                         stackManinpulation.push(code, pos, stack);
  117.                         break;
  118.                     case LF:
  119.                         switch(code.charAt(pos++)) {
  120.                             case SPACE:
  121.                                 stackManinpulation.duplicate(stack);
  122.                                 break;
  123.                             case TAB:
  124.                                 stackManinpulation.swapTop(stack);
  125.                                 break;
  126.                             case LF:
  127.                                 stackManinpulation.discard(stack);
  128.                                 break;
  129.                         }
  130.                         break;
  131.                   }
  132.                   break;
  133.             }
  134.            
  135.             case TAB: {
  136.                 switch(code.charAt(pos++)) {
  137.                     case SPACE: {
  138.                         var arithmetic = instructions.arithmetic;
  139.                         switch(code.substr(pos, 2)) {
  140.                             case (SPACE + SPACE):
  141.                                 arithmetic.add(stack); break;
  142.                             case (SPACE + TAB):
  143.                                 arithmetic.subtract(stack); break;
  144.                             case (SPACE + LF):
  145.                                 arithmetic.multiply(stack); break;
  146.                             case (TAB + SPACE):
  147.                                 arithmetic.divide(stack); break;
  148.                             case (TAB + TAB):
  149.                                 arithmetic.mod(stack); break;
  150.                         }
  151.                         pos += 2;
  152.                         break;
  153.                     }
  154.                     case TAB: {
  155.                         var heapAccess = instructions.heapAccess;
  156.                         switch(code.charAt(pos++)) {
  157.                             case SPACE:
  158.                                 heapAccess.store(stack, memory); break;
  159.                             case TAB:
  160.                                 heapAccess.retrieve(stack, memory); break;
  161.                         }
  162.                         break;
  163.                     }
  164.                     case LF: {
  165.                         var inAndOut = instructions.inAndOut;
  166.                         switch(code.substr(pos, 2)) {
  167.                             case (SPACE + SPACE):
  168.                                 inAndOut.outputChar(stack, ouput); break;
  169.                             case (SPACE + TAB):
  170.                                 inAndOut.outputNum(stack, output); break;
  171.                             case (TAB + SPACE):
  172.                                 inAndOut.readChar(stack, input, memory); break;
  173.                             case (TAB + TAB):
  174.                                 inAndOut.readNum(stack, input, memory); break;
  175.                         }
  176.                         pos += 2;
  177.                         break;
  178.                     }
  179.                 }
  180.                 break;
  181.             }
  182.            
  183.            
  184.             case LF: {
  185.                 var flowControl = instructions.flowControl;
  186.                 switch(code.substr(pos, 2)) {
  187.                     case (SPACE + SPACE): {
  188.                         flowControl.markLocation(code, pos, location);
  189.                         break;
  190.                     }
  191.                     case (SPACE + TAB): {
  192.                         flowControl.callSubroutine(code, pos, location, endSub);
  193.                         break;
  194.                     }
  195.                     case (SPACE + LF): {
  196.                         flowControl.jumpAnyway(code, pos, location);
  197.                         break;
  198.                     }
  199.                     case (TAB + SPACE): {
  200.                         flowControl.jumpIfZero(code, pos, stack, location);
  201.                         break;
  202.                     }
  203.                     case (TAB + TAB): {
  204.                         flowControl.jumpIfNegative(code, pos, stack, location);
  205.                         break;
  206.                     }
  207.                     case (TAB + LF): {
  208.                         flowControl.endSubroutine(pos, endSub);
  209.                         break;
  210.                     }
  211.                     case (LF + LF): {
  212.                         pos = code.length + 1;
  213.                         break;
  214.                     }
  215.                 }
  216.                 pos += 2;
  217.             }
  218.                
  219.         }
  220.     }
  221.  
  222.     return output;
  223. };
  224.  
  225. function print(code) {
  226.     var output = "";
  227.     for (var i = 0; i < code.length; ++i)
  228.         switch(code.charAt(i)) {
  229.             case SPACE: output += 's'; break;
  230.             case TAB: output += 't'; break;
  231.             case LF: output += 'n'; break;
  232.         }
  233.     return output;
  234. }
  235.  
  236. console.log(whitespace("   \t\n\t\n \t\n\n\n"));
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement