silentmatt / expr-eval

Mathematical expression evaluator in JavaScript
http://silentmatt.com/javascript-expression-evaluator/
MIT License
1.19k stars 239 forks source link

is it possible to overload arithmetic operators to support own bigint objects? #198

Closed mgttt closed 5 years ago

mgttt commented 5 years ago

dear, is it possible to overload the operators to support own bigint? e. g. parse("a**b%c", {a:new BN("123456789"),b:new BN("654321"),c:new BN("76584")})

silentmatt commented 5 years ago

Yes, you can although you'll need to be careful how you handle numeric literals in the expression, since those will be parsed as native JavaScript numbers. The Parser class has a couple properties that provide the implementation for the various built-in operators and functions. You can replace those with your own implementation, or add/remove functions. Here's a quick made-up example that should give you an idea. You can look at the Parser constructor for the full list of operators and functions.

var parser = new Parser();

// Note that the exponentiation operator is ^, not **
parser.binaryOps['^'] = function (a, b) {
    // Convert JavaScript numbers to big integers
    if (!BN.isBN(a)) {
        a = new BN(a);
    }
    if (!BN.isBN(b)) {
        b = new BN(b);
    }
    return a.pow(b);
};

parser.binaryOps['%'] = function (a, b) {
    if (!BN.isBN(a)) {
        a = new BN(a);
    }
    if (!BN.isBN(b)) {
        b = new BN(b);
    }
    return a.mod(b);
};

// etc. for unaryOps, binaryOps, ternaryOps, functions, and/or consts

var answer = parser.parse("a^b%c", {a:new BN("123456789"),b:new BN("654321"),c:new BN("76584")}).evaluate()