Arithmetic evaluation: Difference between revisions

m
Added Sidef
m (Added Sidef)
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.
 
=={{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}}==
2,747

edits