Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local DISPLAY = "lcd"
- local INPUT = "kbd"
- local run, fns
- if not event then
- -- running outside of minetest
- local _print = print
- print = function(...)
- local args = {...}
- if #args == 1 and type(args[1]) == "table" then
- _print(run(args[1]))
- else
- _print(...)
- end
- end
- digiline_send = function(c, ...) print("digiline_send -> " .. c, ...) end
- event = { type = "program" }
- else
- -- running inside minetest
- print = function(...)
- local args = {...}
- if #args > 1 then
- digiline_send(DISPLAY, table.concat(args, "\t"))
- elseif #args == 1 then
- if "table" == type(args[1]) then
- digiline_send(DISPLAY, run(args[1]))
- else
- digiline_send(DISPLAY, tostring(args[1]))
- end
- end
- end
- string.rep = function(str, c)
- local out = ""
- while c > 0 do
- out = out .. str
- c = c - 1
- end
- return out
- end
- end
- local tokenize -- translate string into tokens of parenthesis & sequences of non-space characters
- tokenize = function(str)
- local tokens = {}
- local currentToken = ""
- while #str > 0 do
- local t = str:sub(1, 1)
- if t == " " then
- if #currentToken > 0 then
- table.insert(tokens, currentToken)
- currentToken = ""
- end
- elseif t == "(" then
- if #currentToken > 0 then
- table.insert(tokens, currentToken)
- currentToken = ""
- end
- table.insert(tokens, "(")
- elseif t == ")" then
- if #currentToken > 0 then
- table.insert(tokens, currentToken)
- currentToken = ""
- end
- table.insert(tokens, ")")
- else
- currentToken = currentToken .. t
- end
- str = str:sub(2)
- end
- if #currentToken > 0 then
- table.insert(tokens, currentToken)
- end
- return tokens
- end
- local store -- store tokens into an abstract syntax tree
- store = function(tokens)
- local ast = {}
- local ret
- while #tokens > 0 do
- if tokens[1] == "(" then
- table.remove(tokens, 1)
- ret, tokens = store(tokens)
- table.insert(ast, ret)
- elseif tokens[1] == ")" then
- table.remove(tokens, 1)
- return ast, tokens
- else
- table.insert(ast, table.remove(tokens, 1))
- end
- end
- if #ast == 1 then
- return ast[1]
- else
- return ast
- end
- end
- run = function(str_or_ast, args)
- local program, fn
- if "string" == type(str_or_ast) then
- program = store(tokenize(str_or_ast))
- else
- program = str_or_ast
- end
- if "string" == type(program) then
- fn = program
- program = {}
- else
- fn = table.remove(program, 1)
- end
- if "string" == type(fn) then
- if fns[fn] then
- if args then
- return fns[fn](args, unpack(program))
- else
- return fns[fn](unpack(program))
- end
- elseif _G[fn] then
- if args then
- return _G[fn](args, unpack(program))
- else
- return _G[fn](unpack(program))
- end
- else
- print("error! function '"..tostring(fn).."' doesn't exist")
- end
- else
- return run(fn, args)
- end
- end
- local show_table -- basic debug output / pretty print for objects
- show_table = function(t,d)
- if type(t) ~= "table" then return tostring(t) end
- local str = ""
- d = d or 0
- for k,v in pairs(t) do
- str = str .. string.rep(" ", d) .. tostring(k) .. " = " .. tostring(v) .. "\n"
- if type(v) == "table" then str = str .. show_table(v,d+1) end
- end
- return str
- end
- local function _if(condition, codeT, codeF)
- if run(condition) then
- return run(codeT)
- elseif codeF then
- return run(codeF)
- end
- end
- local function _while(condition, loop)
- while run(condition) do
- run(loop)
- end
- end
- local function set_env(name, ...)
- if type(name) == "table" then name = run(name) end
- local args = {...}
- local value
- if #args > 1 then
- value = table.concat(args, " ")
- elseif #args == 1 then
- if "table" == type(args[1]) then
- value = run(args[1])
- else
- value = args[1]
- end
- end
- value = tonumber(value) or value
- mem.env[name] = value
- end
- local function get_env(name)
- if type(name) == "table" then name = run(name) end
- return mem.env[name]
- end
- local function send(channel, ...)
- if type(channel) == "table" then channel = run(channel) end
- local args = {...}
- if #args > 1 then
- digiline_send(channel, table.concat(args, " "))
- elseif #args == 1 then
- if "table" == type(args[1]) then
- digiline_send(channel, run(args[1]))
- else
- digiline_send(channel, args[1])
- end
- end
- end
- fns = { -- available to custom code
- echo = print,
- show_table = show_table,
- ["if"] = _if,
- ["while"] = _while,
- ["="] = set_env,
- ["$"] = get_env,
- ["true"] = function() return true end,
- ["false"] = function() return false end,
- -- ["`"] = function(...) return table.concat({...}, " ") end,
- digiline_send = send,
- }
- -- local example_code = "digiline_send lcd Hello!"
- -- local example_code = "print Hello world!"
- -- local example_code = "if false (print This is true.) (print This is false.)"
- if event.type == "digiline" then
- if event.channel == INPUT then
- run(event.msg)
- end
- elseif event.type == "program" then
- mem.env = {}
- print("Ready.")
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement