Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- This program is public domain. Do whatever you want with it.
- local expr
- local spacechars = " \t\n\r"
- local function skipspaces()
- while spacechars:find(expr:sub(1, 1),1,true) ~= nil and expr:len() > 0 do
- expr = expr:sub(2)
- end
- end
- local function acceptch(ch)
- skipspaces()
- if expr:sub(1,1) == ch then
- expr = expr:sub(2)
- return true
- else
- return false
- end
- end
- local function acceptnum()
- skipspaces()
- -- I'm sure there's a better way
- for len = expr:len(), 1, -1 do
- local success, n = pcall(tonumber, expr:sub(1, len))
- if success and n ~= nil then
- expr = expr:sub(len + 1)
- return n
- end
- end
- return nil
- end
- local alpha = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
- local alnum = alpha .. "0123456789"
- local function acceptident()
- local n = 0
- skipspaces()
- if alpha:find(expr:sub(1, 1),1,true) == nil then return nil end
- while alnum:find(expr:sub(n+1, n+1),1,true) ~= nil and expr:len() > n do
- n = n + 1
- end
- local ident = expr:sub(1, n)
- expr = expr:sub(n+1)
- return ident
- end
- local function parse_error(s)
- error(s and ("parse error: " .. s) or "parse error")
- end
- local expression_root
- local math_functions = {
- abs = math.abs,
- acos = math.acos,
- asin = math.asin,
- atan = math.atan,
- atan2 = math.atan2,
- ceil = math.ceil,
- floor = math.floor,
- cos = math.cos,
- sin = math.sin,
- tan = math.tan,
- cosh = math.cosh,
- sinh = math.sinh,
- tanh = math.tanh,
- -- math.deg, math.rad
- exp = math.exp,
- ln = math.log,
- log = math.log10,
- pow = math.pow,
- min = math.min,
- max = math.max,
- sqrt = math.sqrt,
- random = math.random
- }
- local math_constants = {
- pi = math.pi,
- e = math.exp(1),
- inf = math.huge,
- nan = math.huge - math.huge
- }
- local function call_function(id, arglist)
- if math_functions[id] == nil then
- error("no such function: " .. id)
- end
- return math_functions[id](unpack(arglist))
- end
- local function get_constant(id)
- return math_constants[id] or error("no such constant: "..id)
- end
- local function num_or_brackets()
- if acceptch("(") then
- local n = expression_root()
- if not acceptch(")") then parse_error("non-matching parentheses") end
- return n
- elseif acceptch("-") then
- return -expression_root()
- else
- local id = acceptident()
- if id ~= nil then
- if not acceptch("(") then
- return get_constant(id)
- elseif acceptch(")") then
- return call_function(id, {})
- else
- local arglist = {}
- local done = false
- while not done do
- table.insert(arglist, expression_root())
- if acceptch(")") then
- done = true
- elseif not acceptch(",") then
- parse_error("expected , or )")
- end
- end
- return call_function(id, arglist)
- end
- else
- local n = acceptnum()
- if n == nil then parse_error("expected number or bracketed expression") end
- return n
- end
- end
- end
- local function division()
- local n1 = num_or_brackets()
- while acceptch("/") do
- n1 = n1 / num_or_brackets()
- end
- return n1
- end
- local function multiplication()
- local n1 = division()
- while acceptch("*") do
- n1 = n1 * division()
- end
- return n1
- end
- local function subtraction()
- local n1 = multiplication()
- while acceptch("-") do
- n1 = n1 - multiplication()
- end
- return n1
- end
- local function addition()
- local n1 = subtraction()
- while acceptch("+") do
- n1 = n1 + subtraction()
- end
- return n1
- end
- expression_root = addition
- local function parse(e)
- expr = e
- local success, result = pcall(expression_root)
- if success and expr ~= "" then
- print("Garbage after expression?")
- end
- if success then
- print("Answer: " .. tostring(result))
- else
- print(result)
- print("Near: " .. (expr == "" and "end of expression" or expr))
- end
- end
- local function mainloop()
- local quitting = false
- print("")
- print("Kalkulator by Hogohin v1.0")
- print("")
- print("Wpisuj rownania i zatwierdz enter")
- print("Wpisz 'wyjdz' aby wyjsc")
- print("")
- while not quitting do
- local line = io.read()
- if line == "wyjdz" then
- quitting = true
- else
- parse(line)
- print("")
- end
- end
- end
- mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement