Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- "use strict";
- function BinOperation(a, b) {
- this.a = a;
- this.b = b;
- this.toString = () => this.a.toString() + " " + this.b.toString() + " " + this.operator;
- this.evaluate = (...args) => this.evaluateImpl(this.a.evaluate(...args), this.b.evaluate(...args));
- }
- function Add(a, b) {
- BinOperation.call(this, a, b);
- this.operator = '+';
- this.evaluateImpl = (a, b) => a + b;
- this.diff = (diffName) => new Add( this.a.diff(diffName), this.b.diff(diffName) );
- }
- function Subtract(a, b) {
- BinOperation.call(this, a, b);
- this.operator = '-';
- this.evaluateImpl = (a, b) => a - b;
- this.diff = (diffName) => new Subtract( this.a.diff(diffName), this.b.diff(diffName) );
- }
- function Multiply(a, b) {
- BinOperation.call(this, a, b);
- this.operator = '*';
- this.evaluateImpl = (a, b) => a * b;
- this.diff = (diffName) => new Add(
- new Multiply( this.a.diff(diffName), this.b ),
- new Multiply( this.a, this.b.diff(diffName) )
- );
- }
- function Divide(a, b) {
- BinOperation.call(this, a, b);
- this.operator = '/';
- this.evaluateImpl = (a, b) => a / b;
- this.diff = (diffName) => new Divide(
- new Subtract(
- new Multiply(this.a.diff(diffName), this.b),
- new Multiply(this.a, this.b.diff(diffName))
- ),
- new Multiply(this.b, this.b)
- )
- }
- function Negate(a) {
- this.a = a;
- this.toString = () => this.a.toString() + ' negate';
- this.evaluate = (...args) => (-1) * this.a.evaluate(...args);
- this.diff = (diffName) => new Negate(a.diff(diffName));
- }
- function Const(val) {
- this.val = val;
- this.toString = () => this.val.toString();
- this.evaluate = () => this.val;
- this.diff = () => new Const(0);
- }
- function Variable(name) {
- this.name = name;
- this.toString = () => this.name;
- this.evaluate = (...args) => {
- if (name === 'x') return args[0];
- if (name === 'y') return args[1];
- if (name === 'z') return args[2];
- }
- this.diff = (diffName) => new Const( this.name === diffName ? 1 : 0 );
- }
- const operations = [ 'negate', '+', '-', '*', '/' ];
- const variables = [ 'x', 'y', 'z' ];
- const operationToArity = {
- 'negate': 1,
- '+' : 2,
- '-' : 2,
- '*' : 2,
- '/' : 2,
- };
- const tokenToOperation = {
- 'negate': Negate,
- '+' : Add,
- '-' : Subtract,
- '*' : Multiply,
- '/' : Divide
- };
- const parse = function(expression) {
- let stack = [];
- let tokens = expression.split(' ').filter((word) => word !== '');
- for (let token of tokens) {
- if (operations.includes(token)) {
- let arity = operationToArity[token];
- let args = [];
- for (let i = arity - 1; i >= 0; i--) {
- args[i] = stack.pop();
- }
- stack.push(new tokenToOperation[token](...args));
- } else if (variables.includes(token)) {
- stack.push(new Variable(token));
- } else {
- stack.push(new Const(Number.parseInt(token)));
- }
- }
- return stack.pop();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement