• API
• FAQ
• Tools
• Archive
SHARE
TWEET

Untitled

a guest Mar 26th, 2020 63 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.
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,
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. }
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.
Top