nerdamer-ts
Version:
javascript light-weight symbolic math expression evaluator
306 lines • 9.07 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.OperatorDictionary = void 0;
const Settings_1 = require("../Settings");
// @ts-ignore
const Symbol_1 = require("../Types/Symbol");
const Core_1 = require("../Functions/Core");
class OperatorDictionary {
constructor() {
this.operators = {};
this.brackets = {
'(': {
type: 'round',
id: 1,
is_open: true,
is_close: false
},
')': {
type: 'round',
id: 2,
is_open: false,
is_close: true
},
'[': {
type: 'square',
id: 3,
is_open: true,
is_close: false,
maps_to: 'vector'
},
']': {
type: 'square',
id: 4,
is_open: false,
is_close: true
},
'{': {
type: 'curly',
id: 5,
is_open: true,
is_close: false,
maps_to: 'Set'
},
'}': {
type: 'curly',
id: 6,
is_open: false,
is_close: true
}
};
this.operators = {
'\\': {
precedence: 8,
operator: '\\',
action: 'slash',
prefix: true,
postfix: false,
leftAssoc: true,
operation: function (e) {
return e; //bypass the slash
}
},
'!!': {
precedence: 7,
operator: '!!',
action: 'dfactorial',
prefix: false,
postfix: true,
leftAssoc: true,
operation: (e) => {
return (0, Symbol_1.symfunction)(Settings_1.Settings.DOUBLEFACTORIAL, [e]); //wrap it in a factorial function
}
},
'!': {
precedence: 7,
operator: '!',
action: 'factorial',
prefix: false,
postfix: true,
leftAssoc: true,
operation: (e) => {
return (0, Core_1.factorial)(e); //wrap it in a factorial function
}
},
'^': {
precedence: 6,
operator: '^',
action: 'pow',
prefix: false,
postfix: false,
leftAssoc: true
},
'**': {
precedence: 6,
operator: '**',
action: 'pow',
prefix: false,
postfix: false,
leftAssoc: true
},
'%': {
precedence: 4,
operator: '%',
action: 'percent',
prefix: false,
postfix: true,
leftAssoc: true,
overloaded: true,
overloadAction: 'mod',
overloadLeftAssoc: false,
operation: (x) => {
return (0, Core_1.divide)(x, new Symbol_1.Symbol(100));
}
},
'*': {
precedence: 4,
operator: '*',
action: 'multiply',
prefix: false,
postfix: false,
leftAssoc: false
},
'/': {
precedence: 4,
operator: '/',
action: 'divide',
prefix: false,
postfix: false,
leftAssoc: false
},
'+': {
precedence: 3,
operator: '+',
action: 'add',
prefix: true,
postfix: false,
leftAssoc: false,
operation: (x) => {
return x;
}
},
'plus': {
precedence: 3,
operator: 'plus',
action: 'add',
prefix: true,
postfix: false,
leftAssoc: false,
operation: (x) => {
return x;
}
},
'-': {
precedence: 3,
operator: '-',
action: 'subtract',
prefix: true,
postfix: false,
leftAssoc: false,
operation: (x) => {
return x.negate();
}
},
'=': {
precedence: 2,
operator: '=',
action: 'equals',
prefix: false,
postfix: false,
leftAssoc: false
},
'==': {
precedence: 1,
operator: '==',
action: 'eq',
prefix: false,
postfix: false,
leftAssoc: false
},
'<': {
precedence: 1,
operator: '<',
action: 'lt',
prefix: false,
postfix: false,
leftAssoc: false
},
'<=': {
precedence: 1,
operator: '<=',
action: 'lte',
prefix: false,
postfix: false,
leftAssoc: false
},
'>': {
precedence: 1,
operator: '>',
action: 'gt',
prefix: false,
postfix: false,
leftAssoc: false
},
'=>': {
precedence: 1,
operator: '=>',
action: 'gte',
prefix: false,
postfix: false,
leftAssoc: false
},
',': {
precedence: 0,
operator: ',',
action: 'comma',
prefix: false,
postfix: false,
leftAssoc: false
},
':': {
precedence: 0,
operator: ',',
action: 'assign',
prefix: false,
postfix: false,
leftAssoc: false,
vectorFn: 'slice'
},
':=': {
precedence: 0,
operator: ',',
action: 'function_assign',
prefix: false,
postfix: false,
leftAssoc: true
}
};
}
injectOperatorsDeps(depsFunction) {
this.deps = depsFunction;
}
/**
* Replaces nerdamer.setOperator
* @param {object} operator
* @param action
* @param {'over' | 'under'} shift
*/
setOperator(operator, action, shift) {
let name = operator.operator; //take the name to be the symbol
this.operators[name] = operator;
if (action) {
this.deps.registerOperator(operator.action, action);
}
//make the parser aware of the operator
this.deps.registerOperator(name, operator.operation);
//make the action available to the parser if infix
if (!operator.action && !(operator.prefix || operator.postfix)) {
operator.action = name;
}
//if this operator is exclusive then all successive operators should be shifted
if (shift === 'over' || shift === 'under') {
let precedence = operator.precedence;
for (let x in this.operators) {
let o = this.operators[x];
let condition = shift === 'over' ? o.precedence >= precedence : o.precedence > precedence;
if (condition) {
o.precedence++;
}
}
}
}
/**
* Gets an opererator by its symbol
* @param {String} operator
* @returns {OperatorDescriptor}
*/
getOperator(operator) {
return this.operators[operator];
}
aliasOperator(o, n) {
let operator = this.operators[o];
//copy everything over to the new operator
let t = Object.assign({}, operator);
//update the symbol
t.operator = n;
this.setOperator(t);
}
/**
* Returns the list of operators. Caution! Can break parser!
* @returns {object}
*/
getOperators() {
//will replace this with some cloning action in the future
return this.operators;
}
;
getBrackets() {
return this.brackets;
}
;
isOperator(name) {
return (name in this.operators);
}
}
exports.OperatorDictionary = OperatorDictionary;
//# sourceMappingURL=OperatorDictionary.js.map