```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 ``` ```math.calcfuncs = { time = CurTime or function() return os.time() end, } for k,v in pairs(math) do math.calcfuncs[k] = type(v) == "function" and v or function() return v end end local TB = 0 function math.varsnum(n, vars) --print(string.rep("-", TB).."VAR:", n, tonumber(n) or vars[n]) return tonumber(n) or vars[n] or error("Invalid number "..string.format("%q", n)..".", 3) end function math.calc(v, vars) TB = TB+1 v = string.match(tostring(v), "^%s*(.-)%s*\$") --print(string.rep("-", TB).."CALC:", v) if v:sub(1,1) == "\"" or v:sub(1,1) == "'" then return {v:gsub("[%'%\"](.-)[%'%\"]", "%1")} end vars = vars or {} vars.now = CurTime and CurTime() or os.time() local output, count = {} repeat v, count = string.gsub(v, "([^%;]+)%;", function(a) table.insert(output, math.calc(a, vars)[1]) return "" end, 1) until count == 0 repeat v, count = string.gsub(v, "([%w_#]*)%s*(%b())", function(a, b) --print(a, b) if a == "" then --print(string.rep("\t", TB).."thing", string.match(b, "^%(%s*(.-)%s*%)\$") or "0") return math.calc(string.match(b, "^%(%s*(.-)%s*%)\$") or "0")[1] elseif a == "#" then table.insert(output, math.calc(string.match(b, "^%(%s*(.-)%s*%)\$") or "0", vars)[1]) return "" elseif math.calcfuncs[a:lower()] then local worked, result = pcall(math.calcfuncs[a:lower()], unpack(math.calc(string.match(b, "^%(%s*(.-)%s*%)\$") or "", vars))) return worked and (result or "") or error("Error in function "..string.format("%q", a:lower())..": "..tostring(result), 2) end error("No such function "..string.format("%q", a)..".", 2) end, 1) until count == 0 repeat v, count = string.gsub(v, "([%w_%d]+)%s*=%s*([^=;]+)", function(a,c) --print(a, "=", c) vars[a] = math.calc(c, vars)[1] return "" end, 1) until count == 0 repeat v, count = string.gsub(v, "(%-?[%w_%d%.e]+)%s*^%s*(%-?[%w_%d%.e]+)", function(a,c) --print(a, "^", c) return math.varsnum(a, vars)^math.varsnum(c, vars) end, 1) until count == 0 repeat v, count = string.gsub(v, "(%-?[%w_%d%.e]+)%s*([%*%/%%])%s*(%-?[%w%_%d%.e]+)", function(a,b,c) --print(a, b, c) return b == "*" and math.varsnum(a, vars)*math.varsnum(c, vars) or b == "/" and math.varsnum(a, vars)/math.varsnum(c, vars) or b == "%" and math.varsnum(a, vars)%math.varsnum(c, vars) end, 1) until count == 0 repeat v, count = string.gsub(v, "(%-?[%w%_%d%.e]+)%s*([%+%-])%s*(%-?[%w%_%d%.e]+)", function(a,b,c) --print(a, b, c) return b == "+" and math.varsnum(a, vars)+math.varsnum(c, vars) or b == "-" and math.varsnum(a, vars)-math.varsnum(c, vars) end, 1) until count == 0 repeat v, count = string.gsub(v, "(%-?[%w%_%d%.e]+)%s*([!~<>=]+)%s*(%-?[%w%_%d%.e]+)", function(a,b,c) --print(a, b, c) return( b == "==" and math.varsnum(a, vars) == math.varsnum(c, vars) or b == "~=" or b == "!=" and math.varsnum(a, vars) ~= math.varsnum(c, vars) or b == ">" and math.varsnum(a, vars) > math.varsnum(c, vars) or b == "<" and math.varsnum(a, vars) < math.varsnum(c, vars) or b == "<=" and math.varsnum(a, vars) <= math.varsnum(c, vars) or b == ">=" and math.varsnum(a, vars) >= math.varsnum(c, vars) ) and 1 or 0 end, 1) until count == 0 if string.match(v, "%S") then table.insert(output, math.varsnum(v, vars)) end --print(string.rep("-", TB).."RES:", unpack(output)) TB = TB-1 return output end print(table.concat(math.calc[[ (3+6) * 5^( 15 % 2 ) / 3; time(); sin(deg(180))*random(); x = 32+9; y = x/random(); #(y); randomseed(32); a = random(); randomseed(32); b = random(); #("This should be 1:"); a == b; 5*-7; ]], "\n")) ```
 ```1 2 3 4 5 6 7 ``` ```15 1255162944 0.48019262451286 103.95987557242 This should be 1: 1 -35 ```