View Source Math expression to function
⚠️ Consider reading Math to french example first.
The module MathToFunction
can read simple integer math expressions too,
but this time the parse/1 function returns a function that produce the value of the expression when called.
iex> {:ok, calcfn} = MathToFunction.parse("(42-2)*12 / 5")
iex> calcfn.()
96.0
Here follows its declaration, a little bit more chalenging.
defmodule MathToFunction do
use Grammar
rule expression(:term, :expression_cont) do
[term, cont] = params
fn -> (cont || & &1).(term.()) end
end
rule? expression_cont("+", :term, :expression_cont) do
[_, term, cont] = params
fn left -> (cont || & &1).((left + term.())) end
end
rule? expression_cont("-", :term, :expression_cont) do
[_, term, cont] = params
fn left -> (cont || & &1).((left - term.())) end
end
rule term(:factor, :term_cont) do
[factor, cont] = params
fn -> (cont || & &1).(factor.()) end
end
rule? term_cont("*", :factor, :term_cont) do
[_, factor, cont] = params
fn left -> (cont || & &1).((left * factor.())) end
end
rule? term_cont("/", :factor, :term_cont) do
[_, factor, cont] = params
fn left -> (cont || & &1).((left / factor.())) end
end
rule factor(:number) do
[number] = params
number
end
rule factor("(", :expression, ")") do
[_, expression, _] = params
expression
end
rule number(~r/[0-9]+/) do
[number] = params
number_value = String.to_integer(number)
fn -> number_value end
end
end