Advertisement
Guest User

Untitled

a guest
Mar 26th, 2019
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.12 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement