mcbot/cmds/calc.lua
author Mikael Berthe <mikael@lilotux.net>
Thu, 15 Apr 2010 18:57:38 +0200
changeset 16 064a50911e05
parent 0 89add07d6fe4
permissions -rw-r--r--
Update command infrastructure


local dc = { ["desc"] = "RPN calculator" }
local calc = { ["desc"] = "Calculator" }

local function sbox (untrusted_code)
    -- make environment
    local env = {}

    -- run code under environment
    local untrusted_function, message = loadstring(untrusted_code)
    if not untrusted_function then return nil, message end
    setfenv(untrusted_function, env)
    local success, result = pcall(untrusted_function)
    if success then
        return result
    else
        return nil, result
    end
end

-- ---- ----

function dc.cmd (args)
    if not args then return nil, "Give me an expression" end
    -- Downloaded from http://www.math.bas.bg/bantchev/place/rpn/rpn.lua.html
    tb = {}  z = 0
    for tk in string.gmatch(args,'%S+') do
      if string.find(tk,'^[-+*/]$')  then
        if 2>#tb then z = nil break end
        y,x = table.remove(tb),table.remove(tb)
        loadstring('z=x'..tk..'y')()
      else
        z = tonumber(tk)  if z==nil then break end
      end
      table.insert(tb,z)
    end
    n = #tb
    if n==1 and z then return z
    elseif n>1 or z==nil then return nil, "dc: Error!" end
end

function calc.cmd (args)
    if not args then return nil, "Give me an expression" end
    local f, msg = sbox("return "..args)
    if not f then
        return nil, "calc: Cannot evaluate expression"
    end
    return tostring(f)
end

mcbot_register_command("dc", dc)
mcbot_register_command("calc", calc)