In love2D I have a string that represents a mathematical expression, for example:
local expr1 = "[p35] div [p36]"
local expr2 = "((([p35]*100) div [p36]) mod 100)"
local params = {p35 = 15025, p36 = 100}
local value1 = evaluateExpression(expr1, params) -- expected 150
local value2 = evaluateExpression(expr1, params) -- expected 25
How can I evaluate this expression?
I've tried to parse p values, than convert SQL-like functions with the Lua.
local function evaluateExpression(expr, params)
if not expr or not params then return nil end
expr = expr:gsub("%[p(%d+)%]", function(num)
local key = "p"..num
local val = params[key]
if val == nil then val = 0 end
return tostring(val)
end)
expr = expr:gsub("(%d+)%s+div%s+(%d+)", "math.floor(%1 / %2)")
expr = expr:gsub("div", "/")
expr = expr:gsub("mod", "%")
-- "math.floor(15025 / 100)+(((15025*100) / 100) % 100)/100"
local f, err = loadstring("return " .. expr)
if not f then
print("parse error:", err)
return nil
end
local success, result = pcall(f)
if not success or type(result) ~= "number" then
print("runtime error:", result)
return nil
end
return result
end
In this replacement string, % is used as an escape character.
expr = expr:gsub("mod", "%")
Lua 5.1: string.gsub (s, pattern, repl [, n])
If repl is a string, then its value is used for replacement. The character % works as an escape character: any sequence in repl of the form %n, with n between 1 and 9, stands for the value of the n-th captured substring (see below). The sequence %0 stands for the whole match. The sequence %% stands for a single %.
Escaping the % makes your example work fine:
expr = expr:gsub("mod", "%%")