SHARE
TWEET

Untitled

a guest Mar 26th, 2019 62 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. function Operation() {
  2.     this.operands = arguments;
  3. }
  4.  
  5. Operation.prototype.evaluate = function () {
  6.     var operResult = [];
  7.     for (var i = 0; i < this.operands.length; i++) {
  8.         operResult.push(this.operands[i].evaluate.apply(this.operands[i], arguments));
  9.     }
  10.     return this.count.apply(null, operResult);
  11. };
  12.  
  13. Operation.prototype.diff = function (name) {
  14.     var operResult = [];
  15.     for (var i = 0; i < this.operands.length; i++) {
  16.         operResult.push(this.operands[i]);
  17.         operResult.push(this.operands[i].diff(name));
  18.     }
  19.     return this.countDiff.apply(null, operResult);
  20. };
  21.  
  22. Operation.prototype.toString = function () {
  23.     var resString = '';
  24.  
  25.     for (var i = 0; i < this.operands.length; i++) {
  26.         resString += this.operands[i].toString() + ' ';
  27.     }
  28.     return resString + this.operation;
  29. };
  30.  
  31. /* Constant class implementation */
  32. function Const(a) {
  33.     this.value = a;
  34. }
  35.  
  36. Const.prototype.evaluate = function () {
  37.     return this.value;
  38. };
  39.  
  40. Const.prototype.diff = function (name) {
  41.     return new Const(0);
  42. };
  43.  
  44. Const.prototype.toString = function () {
  45.     return this.value.toString();
  46. };
  47.  
  48. const vars = ['x', 'y', 'z'];
  49.  
  50. function Variable(name) {
  51.     this.index = vars.indexOf(name);
  52. }
  53.  
  54. Variable.prototype.evaluate = function () {
  55.     return arguments[this.index];
  56. };
  57.  
  58. Variable.prototype.diff = function (name) {
  59.     if (vars[this.index] === name) {
  60.         return new Const(1);
  61.     }
  62.     else {
  63.         return new Const(0);
  64.     }
  65. };
  66.  
  67. Variable.prototype.toString = function () {
  68.     return vars[this.index];
  69. };
  70.  
  71. function Add(a, b) {
  72.     Operation.call(this, a, b);
  73.     this.operation = '+'
  74. }
  75.  
  76. Add.prototype = Object.create(Operation.prototype);
  77. Add.prototype.count = function (a, b) {
  78.     return a + b;
  79. }
  80. Add.prototype.countDiff = function (a, a_dir, b, b_dir) {
  81.     return new Add(a_dir, b_dir);
  82. };
  83.  
  84. function Subtract(a, b) {
  85.     Operation.call(this, a, b);
  86.     this.operation = '-'
  87. }
  88.  
  89. Subtract.prototype = Object.create(Operation.prototype);
  90. Subtract.prototype.count = function (a, b) {
  91.     return a - b;
  92. };
  93. Subtract.prototype.countDiff = function (a, a_dir, b, b_dir) {
  94.     return new Subtract(a_dir, b_dir);
  95. };
  96.  
  97. function Multiply(a, b) {
  98.     Operation.call(this, a, b);
  99.     this.operation = '*'
  100. }
  101.  
  102. Multiply.prototype = Object.create(Operation.prototype);
  103. Multiply.prototype.count = function (a, b) {
  104.     return a * b;
  105. };
  106. Multiply.prototype.countDiff = function (a, a_dir, b, b_dir) {
  107.     return new Add(new Multiply(a, b_dir), new Multiply(a_dir, b));
  108. };
  109.  
  110. function Divide(a, b) {
  111.     Operation.call(this, a, b);
  112.     this.operation = '/'
  113. }
  114.  
  115. Divide.prototype = Object.create(Operation.prototype);
  116. Divide.prototype.count = function (a, b) {
  117.     return a / b;
  118. };
  119. Divide.prototype.countDiff = function (a, a_dir, b, b_dir) {
  120.     return new Divide(new Subtract(new Multiply(a_dir, b), new Multiply(a, b_dir)), new Multiply(b, b));
  121. };
  122.  
  123. function Negate(a) {
  124.     Operation.call(this, a);
  125.     this.operation = 'negate'
  126. }
  127.  
  128. Negate.prototype = Object.create(Operation.prototype);
  129. Negate.prototype.count = function (a) {
  130.     return -a;
  131. };
  132. Negate.prototype.countDiff = function (a, a_dir) {
  133.     return new Negate(a_dir);
  134. };
  135.  
  136. function ArcTan(a) {
  137.     Operation.call(this, a);
  138.     this.operation = 'atan';
  139. }
  140.  
  141. ArcTan.prototype = Object.create(Operation.prototype);
  142. ArcTan.prototype.count = function (a) {
  143.     return Math.atan(a);
  144. };
  145. ArcTan.prototype.countDiff = function (a, da) {
  146.     return new Divide(da, new Add(new Const(1), new Multiply(a, a)));
  147. };
  148.  
  149. function ArcTan2(a, b) {
  150.     Operation.call(this, a, b);
  151.     this.operation = 'atan2';
  152. }
  153.  
  154. ArcTan2.prototype = Object.create(Operation.prototype);
  155. ArcTan2.prototype.count = function (a, b) {
  156.     return Math.atan2(a, b);
  157. };
  158. ArcTan2.prototype.countDiff = function (a, b, da, db) {
  159.     return new Divide(new Subtract(new Multiply(da, b), new Multiply(a, db)), new Add(new Multiply(a, a), new Multiply(b, b)));
  160. };
  161.  
  162. function applyToConstructor(constructor, argArray) {
  163.     var args = [null].concat(argArray);
  164.     var factoryFunction = constructor.bind.apply(constructor, args);
  165.     return new factoryFunction();
  166. }
  167.  
  168. function is_digit(c) {
  169.     return c >= '0' && c <= '9';
  170. }
  171.  
  172. function parse(expr) {
  173.     var OPERATIONS = {
  174.         '+': [Add, 2],
  175.         '-': [Subtract, 2],
  176.         '*': [Multiply, 2],
  177.         '/': [Divide, 2],
  178.         'negate': [Negate, 1],
  179.         'atan': [ArcTan, 1],
  180.         'atan2': [ArcTan2, 2]
  181.     };
  182.     var stack = [];
  183.     var tokens = expr.split(/\s+/);
  184.     for (var i = 0; i < tokens.length; i++) {
  185.         var token = tokens[i];
  186.         if (token in OPERATIONS) {
  187.             var args = [];
  188.             for (var j = 0; j < OPERATIONS[token][1]; j++)
  189.                 args.unshift(stack.pop());
  190.             stack.push(applyToConstructor(OPERATIONS[token][0], args));
  191.         } else if (vars.indexOf(token) !== -1) {
  192.             stack.push(new Variable(token));
  193.         } else if (is_digit(tokens[i][0]) || (tokens[i][0] === '-' && tokens[i].length !== 1)) {
  194.             stack.push(new Const(parseInt(token)));
  195.         }
  196.     }
  197.     return stack.pop();
  198. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top