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}}== |