1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- --TFF: Tiny F...ast Felth. Author: notabug.org/debris/ . Fundamental macros have been added.
- --Lua/LuaJIT/Luau/(Untested) Computercraft/OpenComputers- compatible.
- --This file is licensed under the Lesser GNU General Public License version 3 or later.
- local tableremove,tableinsert,tablemove,gmatch,unpack = table.remove,table.insert,table.move,string.gmatch,(unpack or table.unpack)
- local macros = {
- ["!"] = function(front,rear,env) --Arity-conscious apply:
- --Given rear [.. F Z] , pops F, Z, Z elements in .. , and pushes all in F(..) to rear.
- local Z,F = tableremove(rear),tableremove(rear)
- local ARGS = {}
- for I = Z,1,-1 do
- ARGS[I] = tableremove(rear) end
- local R = {F(unpack(ARGS))}
- tablemove({F(unpack(ARGS))},1,#ARGS,#rear+1,rear) end,
- ["DEFV#"] = function(front,rear,env) --Define variable:
- --Define a variable of name (pop front) with value (pop rear).
- env[tableremove(front)]=tableremove(rear) end,
- ["DEFM#"] = function(front,rear,env) --Define macro without arguments:
- --[DEFM# SYMBOLNAME SYMBOLEND .. SYMBOLEND]
- --will define a macro SYMBOLNAME that when called will result in .. being pushed to rear.
- local N,E = tableremove(front),tableremove(front)
- local R = "" --Macro source.
- local C = tableremove(front)
- while C and C~=E do
- R = R .. C .. " "
- C=tableremove(front) end
- local feval = env.feval
- env.macros[N] = function(front2,rear2,env2) feval(R,env2,nil,rear2) end
- end,
- }
- local stdenv = _ENV or getfenv(1) --TODO: Platform compatibility assignment through _VERSION.
- --Arithmetic.
- function sum(s,v,...) if (v) then return sum(s+v, ...) else return s end end
- function dif(s,v,...) if (v) then return dif(s-v, ...) else return s end end
- function mul(s,v,...) if (v) then return mul(s*v, ...) else return s end end
- function divraw(s,v,...) if (v) then return s/mul(v, ...) else return s end end
- function div(s,v,...) if (v) then return s/mul(v, ...) else return 1/s end end
- stdenv["+"],stdenv["-"],stdenv["*"],stdenv["/"],stdenv["div"],stdenv["macros"] = sum,dif,mul,div,divraw, macros
- --The meat of this file.
- local function feval(str,env,front,rear)
- local env,parsed,tokens,n,rear,front = env or stdenv or {macros}, gmatch(str,'[^ ]+'),{},1,rear or {},front or {}
- local macros = env.macros
- for token in parsed do
- tokens[n]=token
- n = n+1 end
- parsed = nil
- for tokeni = #front+1,#front + #tokens do
- front[tokeni] = tableremove(tokens) end --Reverse.
- tokens = nil
- for tokeni = 1,#front do
- local token = tableremove(front)
- local m = macros[token]
- if not m then
- rear[#rear+1] = env[token] or tonumber(token)
- else m(front,rear,env) end end
- return rear end
- local function repl(inputmethod,outputmethod,env)
- repeat local s = inputmethod()
- local res,ret = pcall(feval,s,env)
- outputmethod((res and "=< " or "!< ") , ret) until s == "!<EXIT" end
- stdenv.feval = feval
- return {eval=feval,repl=repl,macros=macros,stdenv=stdenv}
- ----merge repl----
- local function repl_input()
- io.write'=>' return io.read() end
- local function repl_output(q,s)
- io.write(q) print((unpack or table.unpack)(s)) end
- felth.repl(repl_input, repl_output)
|