Quick links
Nemathode is array based mathematical expression notation (further in the text: nematode/s, expression/s).
[0, '+', 1] === (0 + 1)
[0, '+', 1, '*', [2, '/', 3, '-', 4]] === (0 + 1б * (2 / 3 - 4))
Nemathode.js is a JavaScript library for nemathodes evaluation. It lets you to combine any number of libraries while leaving the format of the expressions unchanged (aggregator of solutions under one format)
const res1 = nemathode.evaluate([0, '+', 1]); // 1
const res2 = nemathode.evaluate([0, '+', 1, '*', [2, '/', 1, '-', 3]]); // -1
$ npm install --save nemathode
or
$ yarn add nemathode
Read article here
- binary operators
const sumOperator = nemathode.evaluate([1, '+', 1]); // 2
const mulOperator = nemathode.evaluate([1, '*', 1]); // 1
- functions
const customFunction = nemathode.evaluate([1, '+', ['abs', 1, 2, 3]]); //a rguments are not evaluated (future)
const singleFunction = nemathode.evaluate([['abs', 1, 2, 3]]; // single function syntax (it's not convinient, but for now it's only way)
const boolResult = nemathode.evaluate([['areEqual', 1, 2, 3]]); // returns boolean
// etc
- math constants
const piConst = nemathode.mathConstants.PI;
const piConstInUse = nemathode.evaluate([1, '+', 'PI']);
- nested expressions
const resOfNestedExp = nemathode.evaluate([1, '+', 'PI', '*', ['abs', 1, 2, 3], '-', [1, '+', [1, '/', 25]]]);
Literally, mathematical constants
Set of records with implementations
It seems excessive but not everyone using pure js functionality. There are set of libraries where intermediate type is not a number, for example: bignumber.js, decimal.js etc (we have on our website set of configs for most popular libs). So you can configure entry handler for them like
const toInputType = (val: unknown): Decimal | unknown => {
if (typeof val === 'number') {
const input = new Decimal(val);
return input;
}
return val;
};
Opposite of toInputType. See at an example
const toOutputValue = (val: unknown): number | boolean => {
if (val instanceof Decimal) {
return val.toNumber();
}
return val;
};
Let's look at one of examples
...
'+': {
precedence: 1,
implementation: (l: number, r: number): number => {
return l + r;
},
}
...
It's a configuration for operator that consists from two (by now) fields: precedence, implementation (the same as in functions).
const config = {
mathConstants: {
'E': Math.E,
'LN2': Math.LN2,
'LN10': Math.LN10,
'LOG10E': Math.LOG10E,
'LOG2E': Math.LOG2E,
'PI': Math.PI,
'SQRT1_2': Math.SQRT1_2,
'SQRT2': Math.SQRT2,
},
functions: {
'abs': {
implementation: Math.abs,
},
'min': {
implementation: Math.min,
},
'areEqual': {
implementation: (...args: number[]): boolean => {
return args.every(v => v === args[0]);
},
},
},
toInputType: (val: unknown): unknown => val,
toOutputValue: (val: unknown): number | boolean => val as number | boolean,
binaryOperators: {
'+': {
precedence: 1,
implementation: (l: number, r: number): number => {
return l + r;
},
},
'-': {
precedence: 1,
implementation: (l: number, r: number): number => {
return l - r;
},
},
'*': {
precedence: 2,
implementation: (l: number, r: number): number => {
return l * r;
},
},
'/': {
precedence: 2,
implementation: (l: number, r: number): number => {
return l / r;
},
},
'%': {
precedence: 2,
implementation: (l: number, r: number): number => {
return l % r;
},
},
},
};
import Nemathode from 'nemathode';
import { config } from './config';
const nemathode = Nemathode({
...config,
});
// method for expression evaluation
const res = nemathode.evaluate([...]);
// example of getting math constant
nemathode.mathConstants.SOME_CONST;
MIT © Kas Elvirov