Arithmetic evaluation: Difference between revisions

Content added Content deleted
m (Added Sidef)
Line 3,936: Line 3,936:


This example was made rather more complex by the requirement of generating an AST tree. With a Scala distribution there are many examples of arithmetic parsers, as small as half a dozen lines.
This example was made rather more complex by the requirement of generating an AST tree. With a Scala distribution there are many examples of arithmetic parsers, as small as half a dozen lines.

=={{header|Sidef}}==

Translation of [[JavaScript]].

<lang ruby>func evalArithmeticExp(s) {

func evalExp(s) {

func operate(s, op) {
s.split(op).map{|c|c.toNum}.reduce(op);
}

func add(s) {
operate(s.replace(/^\+/,'').replace(/\++/,'+'), '+');
}

func subtract(s) {
s.gReplace!(/(\+-|-\+)/,'-');

if (s.match(/--/)) {
return(add(s.replace(/--/,'+')));
}

b = (s.split('-')).len == 3
? (-1 * b[1].toNum - b[2].toNum)
: (operate(s, '-'))
}

s.gReplace!(/[()]/,'').gReplace!(/-\+/, '-');

var reM = /\*/;
var reMD = qr"(\d+\.?\d*\s*[*/]\s*[+-]?\d+\.?\d*)";

var reA = /\d\+/;
var reAS = /(-?\d+\.?\d*\s*[+-]\s*[+-]?\d+\.?\d*)/;

var match;
while (match = s.match(reMD)) {
cap = (match.captures.first) =~ reM ??
? (s.replace!(reMD, operate(cap, '*').to_s))
: (s.replace!(reMD, operate(cap, '/').to_s))
}

while (match = s.match(reAS)) {
cap = (match.captures.first) =~ reA ??
? (s.replace!(reAS, add(cap).to_s))
: (s.replace!(reAS, subtract(cap).to_s));
}

return(s);
}

var rePara = /(\([^\(\)]*\))/;
s = (s.split.join('').replace(/^\+/,''));

while (var match = s.match(rePara)) {
s.replace!(rePara, evalExp(match.captures.first));
}

return(evalExp(s).toNum);
}</lang>

Testing the function:
<lang ruby>for [
['2+3' => 5],
['-4-3' => -7],
['-+2+3/4' => -1.25],
['2*3-4' => 2],
['2*(3+4)+2/4' => 2/4 + 14],
['2*-3--4+-0.25' => -2.25],
['2 * (3 + (4 * 5 + (6 * 7) * 8) - 9) * 10' => 7000],
] { |expr, res|

var num = (evalArithmeticExp(expr)) == res || (
"Error occurred on expression '#{expr}': got '#{num}' instead of '#{res}'\n".die;
);

"%-45s == %10g\n".printf(expr, num);
}</lang>


=={{header|Tcl}}==
=={{header|Tcl}}==