Advertisement
Guest User

Untitled

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