Advertisement
dimipan80

Exams - Clojure Parser

Dec 29th, 2014
187
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* The parser should execute lines of basic Clojure commands (defining function and some math operations).
  2.  Also It has to print the result of the last given line of code. Each line starts with “(“and ends with “)”.
  3.  There could be more than one whitespace between the characters. For example
  4.  (     +           4   1         )  //Also has to return 5
  5.  Also you can use old functions in the definitions of the new one.
  6.  If you meet a function in a command it’ll be always defined in some of the lines before!
  7.  There will be no more than 1 nested function in the definition of a new one.
  8.  Example: Command can be (def func (+ 23 4 8 4 5 7)), but it won’t be (def func (+ 23 4 (* 2 2) 4 5 7)).
  9.  There will be no nested functions in the last line. Only math operation and a sequence of numbers and functions.
  10.  Example: Last line can be (+ 23 4 8 myFunc 5 7), but it won’t be (+ 23 4 (* 2 myFunc) 4 newFunc 7)).
  11.  You are given an array of strings (commands). Execute all the commands and print the result
  12.  only from the last line! */
  13.  
  14. "use strict";
  15.  
  16. function solve(args) {
  17.     var funcList = {};
  18.     for (var row = 0; row < args.length; row += 1) {
  19.         var currentRow = args[row].trim();
  20.         currentRow = currentRow.replace(/\s+/g, ' ');
  21.        
  22.         var funcName = '', funcValue, temp;
  23.         var params = [];
  24.         if (currentRow.lastIndexOf('(') && row < args.length - 1) {
  25.             var outerStr = currentRow.substring(1, currentRow.lastIndexOf('('));
  26.             var nestedStr = currentRow.substring((currentRow.lastIndexOf('(') + 1), currentRow.length - 2);
  27.             var funcParams = outerStr.split(/\s/).filter(Boolean);
  28.             if (funcParams[0] === 'def' && funcParams.length == 2) {
  29.                 funcName = funcParams[1];
  30.             }
  31.             params = nestedStr.split(/\s/).filter(Boolean);
  32.             temp = calculateFuncExpression(params);
  33.            
  34.         } else {
  35.             currentRow = currentRow.substring(1, currentRow.length - 1);
  36.             currentRow = currentRow.split(/\s/).filter(Boolean);
  37.             if (currentRow[0] === 'def' && currentRow.length == 3) {
  38.                 if (row < args.length - 1) {
  39.                     funcName = currentRow[1];
  40.                 }
  41.                 if (isFinite(currentRow[2])) {
  42.                     funcValue = parseInt(currentRow[2]);
  43.                 } else if (funcList.hasOwnProperty(currentRow[2])) {
  44.                     funcValue = funcList[currentRow[2]];
  45.                 }
  46.                
  47.                 if (row < args.length - 1 && !(funcName in funcList) && funcName.length &&
  48.                     (typeof funcValue == 'number')) {
  49.                     funcList[funcName] = funcValue;
  50.                 } else if (row == args.length - 1 && (typeof funcValue == 'number')) {
  51.                     return console.log(funcValue);
  52.                 }
  53.                
  54.             } else if (row == args.length - 1 && (currentRow[0] == '+' || currentRow[0] == '-' ||
  55.                 currentRow[0] == '*' || currentRow[0] == '/')) {
  56.                 temp = calculateFuncExpression(currentRow);
  57.             }
  58.         }
  59.        
  60.         if (temp === 'Error') {
  61.             return console.log('Division by zero! At Line:' + (row + 1));
  62.         }
  63.        
  64.         funcValue = temp;
  65.        
  66.         if (row < args.length - 1 && funcName.length && !(funcName in funcList) &&
  67.             (typeof funcValue == 'number')) {
  68.             funcList[funcName] = funcValue;
  69.         } else if (row == args.length - 1 && typeof funcValue == 'number') {
  70.             console.log(funcValue);
  71.         }
  72.     }
  73.    
  74.     function calculateFuncExpression(params) {
  75.         var operation = '';
  76.         if (params[0] == '+' || params[0] == '-' || params[0] == '*' || params[0] == '/') {
  77.             operation = params[0];
  78.         }
  79.        
  80.         params = parsingFuncArguments(params);
  81.         var i, result;
  82.         switch (operation) {
  83.             case '+':
  84.                 result = 0;
  85.                 for (i = 0; i < params.length; i += 1) {
  86.                     result += params[i];
  87.                 }
  88.                 return result;
  89.             case '-':
  90.                 result = params[0];
  91.                 for (i = 1; i < params.length; i += 1) {
  92.                     result -= params[i];
  93.                 }
  94.                 return result;
  95.             case '*':
  96.                 result = 1;
  97.                 for (i = 0; i < params.length; i += 1) {
  98.                     result *= params[i];
  99.                 }
  100.                 return result;
  101.             case '/':
  102.                 result = params[0];
  103.                 for (i = 1; i < params.length; i += 1) {
  104.                     if (params[i] === 0) {
  105.                         return 'Error';
  106.                     }
  107.                     result /= params[i];
  108.                 }
  109.                 return parseInt(result);
  110.         }
  111.     }
  112.    
  113.     function parsingFuncArguments(argums) {
  114.         var newArgs = [];
  115.         for (var i = 1; i < argums.length; i += 1) {
  116.             if (isFinite(argums[i])) {
  117.                 newArgs.push(parseInt(argums[i]));
  118.             } else if (funcList.hasOwnProperty(argums[i])) {
  119.                 newArgs.push(funcList[argums[i]]);
  120.             }
  121.         }
  122.        
  123.         return newArgs;
  124.     }
  125. }
  126.  
  127. solve([
  128.     '(def myFunc 5)',
  129.     '(def myNewFunc (+  myFunc  myFunc 2))',
  130.     '(def MyFunc (* 2  myNewFunc))',
  131.     '(/   MyFunc  myFunc)'
  132. ]);
  133.  
  134. solve([
  135.     '(def func 10)',
  136.     '(def newFunc (+  func 2))',
  137.     '(def sumFunc (+ func func newFunc 0 0 0))',
  138.     '(* sumFunc 2)'
  139. ]);
  140.  
  141. solve([
  142.     '(def func (+ 5 2))',
  143.     '(def func2 (/  func 5 2 1 0))',
  144.     '(def func3 (/ func 2))',
  145.     '(+ func3 func)'
  146. ]);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement