TangentFox

Terminal WIP (for minetest luacontrollers)

May 21st, 2019 (edited)
278
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.07 KB | None | 0 0
  1. if not event then
  2.   -- compat running outside of minetest
  3.   digiline_send = function(c, ...) print(...) end
  4.   event = { type = "program" }
  5. else
  6.   -- compat running inside minetest
  7.   string.rep = function(str, c)
  8.     local out = ""
  9.     while c > 0 do
  10.       out = out .. str
  11.       c = c - 1
  12.     end
  13.     return out
  14.   end
  15. end
  16.  
  17. local print_table -- basic debug output / pretty print for objects
  18. print_table = function(t,d)
  19.   local str = ""
  20.   d = d or 0
  21.   for k,v in pairs(t) do
  22.     str = str .. string.rep(" ", d) .. tostring(k) .. " = " .. tostring(v) .. "\n"
  23.     if type(v) == "table" then str = str .. print_table(v,d+1) end
  24.   end
  25.   return str
  26. end
  27.  
  28. local tokenize -- translate string into tokens of parenthesis & sequences of non-space characters
  29. tokenize = function(str)
  30.   local tokens = {}
  31.   local currentToken = ""
  32.   while #str > 0 do
  33.     local t = str:sub(1, 1)
  34.     if t == " " then
  35.       if #currentToken > 0 then
  36.         table.insert(tokens, currentToken)
  37.         currentToken = ""
  38.       end
  39.     elseif t == "(" then
  40.       if #currentToken > 0 then
  41.         table.insert(tokens, currentToken)
  42.         currentToken = ""
  43.       end
  44.       table.insert(tokens, "(")
  45.     elseif t == ")" then
  46.       if #currentToken > 0 then
  47.         table.insert(tokens, currentToken)
  48.         currentToken = ""
  49.       end
  50.       table.insert(tokens, ")")
  51.     else
  52.       currentToken = currentToken .. t
  53.     end
  54.     str = str:sub(2)
  55.   end
  56.   if #currentToken > 0 then
  57.     table.insert(tokens, currentToken)
  58.   end
  59.   return tokens
  60. end
  61.  
  62. local store -- store tokens into an abstract syntax tree
  63. store = function(tokens)
  64.   local ast = {}
  65.   local ret
  66.   while #tokens > 0 do
  67.     if tokens[1] == "(" then
  68.       table.remove(tokens, 1)
  69.       ret, tokens = store(tokens)
  70.       table.insert(ast, ret)
  71.     elseif tokens[1] == ")" then
  72.       table.remove(tokens, 1)
  73.       return ast, tokens
  74.     else
  75.       table.insert(ast, table.remove(tokens, 1))
  76.     end
  77.   end
  78.   if #ast == 1 then
  79.     return ast[1]
  80.   else
  81.     return ast
  82.   end
  83. end
  84.  
  85. local run, fns, print
  86. run = function(str_or_ast, args)
  87.   local program, fn
  88.   if "string" == type(str_or_ast) then
  89.     program = store(tokenize(str_or_ast))
  90.   else
  91.     program = str_or_ast
  92.   end
  93.   if "string" == type(program) then
  94.     fn = program
  95.     program = {}
  96.   else
  97.     fn = table.remove(program, 1)
  98.   end
  99.   if "string" == type(fn) then
  100.     if fns[fn] then
  101.       if args then
  102.         return fns[fn](args, unpack(program))
  103.       else
  104.         return fns[fn](unpack(program))
  105.       end
  106.     elseif _G[fn] then
  107.       if args then
  108.         return _G[fn](args, unpack(program))
  109.       else
  110.         return _G[fn](unpack(program))
  111.       end
  112.     else
  113.       print("error! function '"..tostring(fn).."' doesn't exist")
  114.     end
  115.   else
  116.     return run(fn, args)
  117.   end
  118. end
  119.  
  120. print = function(...) -- slightly modified version of print, and also goes to our display instead of the server console
  121.   local args = {...}
  122.   if #args > 1 then
  123.     digiline_send("display", table.concat(args, "\t"))
  124.   elseif #args == 1 then
  125.     if "table" == type(args[1]) then
  126.       digiline_send("display", print_table(args[1]))
  127.     else
  128.       digiline_send("display", tostring(args[1]))
  129.     end
  130.   end
  131. end
  132.  
  133. local function _if(condition, codeT, codeF)
  134.   if run(condition) then
  135.     return run(codeT)
  136.   elseif codeF then
  137.     return run(codeF)
  138.   end
  139. end
  140.  
  141. local function _while(condition, loop)
  142.   while run(condition) do
  143.     run(loop)
  144.   end
  145. end
  146.  
  147. local function _for(iterate, code)
  148.   local res = run(iterate)
  149.   while res do
  150.     run(code, res)
  151.   end
  152. end
  153.  
  154. fns = { -- available to custom code
  155.   print = print,
  156.   ["$"] = run,
  157.   ["if"] = _if,
  158.   ["while"] = _while,
  159.   ["for"] = _for,
  160.   ["true"] = function() return true end,
  161.   ["false"] = function() return false end,
  162. }
  163.  
  164. -- local example_code = "digiline_send display Hello!"
  165. -- local example_code = "print Hello world!"
  166. -- local example_code = "$(print hi there)"
  167. local example_code = "if false (print This is true.) (print This is false.)"
  168.  
  169. if event.type == "program" then
  170.   run(example_code)
  171. end
Add Comment
Please, Sign In to add comment