Advertisement
Guest User

Untitled

a guest
Mar 26th, 2020
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. "use strict";
  2.  
  3. function BinOperation(a, b) {
  4.     this.a = a;
  5.     this.b = b;
  6.  
  7.     this.toString = () => this.a.toString() + " " + this.b.toString() + " " + this.operator;
  8.     this.evaluate = (...args) => this.evaluateImpl(this.a.evaluate(...args), this.b.evaluate(...args));
  9. }
  10.  
  11. function Add(a, b) {
  12.     BinOperation.call(this, a, b);
  13.  
  14.     this.operator = '+';
  15.     this.evaluateImpl = (a, b) => a + b;
  16.     this.diff = (diffName) => new Add( this.a.diff(diffName), this.b.diff(diffName) );
  17. }
  18.  
  19. function Subtract(a, b) {
  20.     BinOperation.call(this, a, b);
  21.  
  22.     this.operator = '-';
  23.     this.evaluateImpl = (a, b) => a - b;
  24.     this.diff = (diffName) => new Subtract( this.a.diff(diffName), this.b.diff(diffName) );
  25. }
  26.  
  27. function Multiply(a, b) {
  28.     BinOperation.call(this, a, b);
  29.  
  30.     this.operator = '*';
  31.     this.evaluateImpl = (a, b) => a * b;
  32.     this.diff = (diffName) => new Add(
  33.         new Multiply( this.a.diff(diffName), this.b ),
  34.         new Multiply( this.a, this.b.diff(diffName) )
  35.     );
  36. }
  37.  
  38. function Divide(a, b) {
  39.     BinOperation.call(this, a, b);
  40.  
  41.     this.operator = '/';
  42.     this.evaluateImpl = (a, b) => a / b;
  43.     this.diff = (diffName) => new Divide(
  44.         new Subtract(
  45.             new Multiply(this.a.diff(diffName), this.b),
  46.             new Multiply(this.a, this.b.diff(diffName))
  47.         ),
  48.         new Multiply(this.b, this.b)
  49.     )
  50. }
  51.  
  52. function Negate(a) {
  53.     this.a = a;
  54.  
  55.     this.toString = () => this.a.toString() + ' negate';
  56.     this.evaluate = (...args) => (-1) * this.a.evaluate(...args);
  57.     this.diff = (diffName) => new Negate(a.diff(diffName));
  58. }
  59.  
  60. function Const(val) {
  61.     this.val = val;
  62.  
  63.     this.toString = () => this.val.toString();
  64.     this.evaluate = () => this.val;
  65.     this.diff = () => new Const(0);
  66. }
  67.  
  68. function Variable(name) {
  69.     this.name = name;
  70.  
  71.     this.toString = () => this.name;
  72.     this.evaluate = (...args) => {
  73.         if (name === 'x') return args[0];
  74.         if (name === 'y') return args[1];
  75.         if (name === 'z') return args[2];
  76.     }
  77.     this.diff = (diffName) => new Const( this.name === diffName ? 1 : 0 );
  78. }
  79.  
  80. const operations = [ 'negate', '+', '-', '*', '/' ];
  81. const variables = [ 'x', 'y', 'z' ];
  82.  
  83. const operationToArity = {
  84.     'negate': 1,
  85.     '+' : 2,
  86.     '-' : 2,
  87.     '*' : 2,
  88.     '/' : 2,
  89. };
  90.  
  91. const tokenToOperation = {
  92.     'negate': Negate,
  93.     '+' : Add,
  94.     '-' : Subtract,
  95.     '*' : Multiply,
  96.     '/' : Divide
  97. };
  98.  
  99. const parse = function(expression) {
  100.     let stack = [];
  101.     let tokens = expression.split(' ').filter((word) => word !== '');
  102.     for (let token of tokens) {
  103.         if (operations.includes(token)) {
  104.             let arity = operationToArity[token];
  105.             let args = [];
  106.             for (let i = arity - 1; i >= 0; i--) {
  107.                 args[i] = stack.pop();
  108.             }
  109.             stack.push(new tokenToOperation[token](...args));
  110.         } else if (variables.includes(token)) {
  111.             stack.push(new Variable(token));
  112.         } else {
  113.             stack.push(new Const(Number.parseInt(token)));
  114.         }
  115.     }
  116.     return stack.pop();
  117. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement