Abhi
Abhi

Reputation: 83

Using a variable as arithmetic operator in Lua

I want to use a variable that references an arithmetic operator within an if statement expression as shown below:

str = { '>60', '>60', '>-60', '=0' }
del = 75

function decode_prog(var1, var2)
    op = string.sub(var1, 1, 1)
    vb = tonumber(string.sub(var1, 2, 3))

    if var2 op vb then
        print("condition met")
    else 
        print('condition not meet')
    end
end
for i = 1, #str do
    decode_prog(str[i], del)
end

When the above code executes, it should either print "condition met" or "condition not met" based on the result of the operation, however I am instead receiving an error.

Upvotes: 2

Views: 1068

Answers (3)

Skully
Skully

Reputation: 3116

You cannot substitute a native Lua operator with a variable that references a function, the only way to go about what you are attempted to do is to create a set of functions within an associative array and set the index as a reference to the respective operation you want to conduct.

Looking at your list, you have a greater than (>) and equal to (=). We create a table for these operations that takes two parameters as follows.

local operators = {
    [">"] = function(x, y) return x > y end,
    ["="] = function(x, y) return x == y end,
    -- Add more operations as required.
}

You can then invoke the respective function from the decode_prog function by obtaining the operation character from the string, along with the numeric value itself - this is possible because you can obtain the function from the associative array where the index is the string of the operation we want to conduct.

local result = operators[op](var2, number)

This calls upon the operators array, uses the op to determine which index we need to go to for our appropriate operation, and returns the value.

Final Code:

str = { '>60', '>60', '>-60', '=0' }
del = 75

local operators = {
    [">"] = function(x, y) return x > y end,
    ["="] = function(x, y) return x == y end,
}

function decode_prog(var1, var2)
    local op = string.sub(var1, 1, 1) -- Fetch the arithmetic operator we intend to use.
    local number = tonumber(string.sub(var1, 2)) -- Strip the operator from the number string and convert the result to a numeric value.

    local result = operators[op](var2, number) -- Invoke the respective function from the operators table based on what character we see at position one.

    if result then
        print("condition met")
    else 
        print('condition not met')
    end
end

for i = 1, #str do
    decode_prog(str[i], del)
end

Upvotes: 4

Piglet
Piglet

Reputation: 28940

I can't make much sense of your code or what you want to achieve doing that but if could simply use load. You build your expression as a string and run it. Of course you should take care of two character operators like >= which I did not and you should validate your input.

local str={'>60','>60','>-60','=0'}
local del=75

function decode_prog(var1, var2)
  local operator = var1:sub(1,1):gsub("=", "==")
  local expr = string.format("return %d %s %s", var2,operator, var1:sub(2))
  print(string.format("condition %smet", load(expr)() and "" or "not "))
end

for i,v in ipairs(str) do
  decode_prog(v, del)
end

Upvotes: 2

IsawU
IsawU

Reputation: 450

A very simple way would be to add a condition for each supported operator:

function decode_prog(var1, var2)
  op = string.sub(var1, 1, 1)
  vb = tonumber(string.sub(var1, 2))  --remove the last argument and use tonumber()
  if vb == nil then return end  --if the string does not contain number

  if (op == ">" and var2 > vb) or (op == "=" and var2 == vb) --[[add more conditions here]] then
     print("condition met")
  else 
     print("condition not met")
  end
end

I changed the vb=string.sub(var1,2,3) line too. This form vb = tonumber(string.sub(var1, 2)) will allow use of numbers that have any number of digits and added tonumber() which will allow us to catch not-a-number errors when comparison would probably fail.

Then I added a logic to determine what the operator is and if the condition is met.

Operator limitations: This will only work with operators that are one character and operator such as >= will not be possible unless you use a different character for it. will not play nicely, since it is multiple characters.

Upvotes: 0

Related Questions