monolithic.lua 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. --TFF: Tiny F...ast Felth. Author: notabug.org/debris/ . Fundamental macros have been added.
  2. --Lua/LuaJIT/Luau/(Untested) Computercraft/OpenComputers- compatible.
  3. --This file is licensed under the Lesser GNU General Public License version 3 or later.
  4. local tableremove,tableinsert,tablemove,gmatch,unpack = table.remove,table.insert,table.move,string.gmatch,(unpack or table.unpack)
  5. local macros = {
  6. ["!"] = function(front,rear,env) --Arity-conscious apply:
  7. --Given rear [.. F Z] , pops F, Z, Z elements in .. , and pushes all in F(..) to rear.
  8. local Z,F = tableremove(rear),tableremove(rear)
  9. local ARGS = {}
  10. for I = Z,1,-1 do
  11. ARGS[I] = tableremove(rear) end
  12. local R = {F(unpack(ARGS))}
  13. tablemove({F(unpack(ARGS))},1,#ARGS,#rear+1,rear) end,
  14. ["DEFV#"] = function(front,rear,env) --Define variable:
  15. --Define a variable of name (pop front) with value (pop rear).
  16. env[tableremove(front)]=tableremove(rear) end,
  17. ["DEFM#"] = function(front,rear,env) --Define macro without arguments:
  18. --[DEFM# SYMBOLNAME SYMBOLEND .. SYMBOLEND]
  19. --will define a macro SYMBOLNAME that when called will result in .. being pushed to rear.
  20. local N,E = tableremove(front),tableremove(front)
  21. local R = "" --Macro source.
  22. local C = tableremove(front)
  23. while C and C~=E do
  24. R = R .. C .. " "
  25. C=tableremove(front) end
  26. local feval = env.feval
  27. env.macros[N] = function(front2,rear2,env2) feval(R,env2,nil,rear2) end
  28. end,
  29. }
  30. local stdenv = _ENV or getfenv(1) --TODO: Platform compatibility assignment through _VERSION.
  31. --Arithmetic.
  32. function sum(s,v,...) if (v) then return sum(s+v, ...) else return s end end
  33. function dif(s,v,...) if (v) then return dif(s-v, ...) else return s end end
  34. function mul(s,v,...) if (v) then return mul(s*v, ...) else return s end end
  35. function divraw(s,v,...) if (v) then return s/mul(v, ...) else return s end end
  36. function div(s,v,...) if (v) then return s/mul(v, ...) else return 1/s end end
  37. stdenv["+"],stdenv["-"],stdenv["*"],stdenv["/"],stdenv["div"],stdenv["macros"] = sum,dif,mul,div,divraw, macros
  38. --The meat of this file.
  39. local function feval(str,env,front,rear)
  40. local env,parsed,tokens,n,rear,front = env or stdenv or {macros}, gmatch(str,'[^ ]+'),{},1,rear or {},front or {}
  41. local macros = env.macros
  42. for token in parsed do
  43. tokens[n]=token
  44. n = n+1 end
  45. parsed = nil
  46. for tokeni = #front+1,#front + #tokens do
  47. front[tokeni] = tableremove(tokens) end --Reverse.
  48. tokens = nil
  49. for tokeni = 1,#front do
  50. local token = tableremove(front)
  51. local m = macros[token]
  52. if not m then
  53. rear[#rear+1] = env[token] or tonumber(token)
  54. else m(front,rear,env) end end
  55. return rear end
  56. local function repl(inputmethod,outputmethod,env)
  57. repeat local s = inputmethod()
  58. local res,ret = pcall(feval,s,env)
  59. outputmethod((res and "=< " or "!< ") , ret) until s == "!<EXIT" end
  60. stdenv.feval = feval
  61. return {eval=feval,repl=repl,macros=macros,stdenv=stdenv}
  62. ----merge repl----
  63. local function repl_input()
  64. io.write'=>' return io.read() end
  65. local function repl_output(q,s)
  66. io.write(q) print((unpack or table.unpack)(s)) end
  67. felth.repl(repl_input, repl_output)