Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local lexer = (function()local a=(function()local b=(function()local function c(d)for e,f in pairs(d)do d[f]=true end;return d end;local function g(d)local h=0;for e in pairs(d)do h=h+1 end;return h end;local function i(d,j)if d.Print then return d.Print()end;j=j or 0;local k=g(d)>1;local l=string.rep(' ',j+1)local m="{"..(k and'\n'or'')for n,f in pairs(d)do if type(f)~='function'then m=m..(k and l or'')if type(n)=='number'then elseif type(n)=='string'and n:match("^[A-Za-z_][A-Za-z0-9_]*$")then m=m..n.." = "elseif type(n)=='string'then m=m.."[\""..n.."\"] = "else m=m.."["..tostring(n).."] = "end;if type(f)=='string'then m=m.."\""..f.."\""elseif type(f)=='number'then m=m..f elseif type(f)=='table'then m=m..i(f,j+(k and 1 or 0))else m=m..tostring(f)end;if next(d,n)then m=m..","end;if k then m=m..'\n'end end end;m=m..(k and string.rep(' ',j)or'').."}"return m end;local function o(p)if p:match("\n")then local q={}for r in p:gmatch("[^\n]*")do table.insert(q,r)end;assert(#q>0)return q else return{p}end end;local function s(t,...)return print(string.format(t,...))end;return{PrintTable=i,CountTable=g,lookupify=c,splitLines=o,printf=s}end)()local c=b.lookupify;local u=c{' ','\n','\t','\r'}local v={['\r']='\\r',['\n']='\\n',['\t']='\\t',['"']='\\"',["'"]="\\'"}local w=c{'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}local x=c{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}local y=c{'0','1','2','3','4','5','6','7','8','9'}local z=c{'0','1','2','3','4','5','6','7','8','9','A','a','B','b','C','c','D','d','E','e','F','f'}local A=c{'+','-','*','/','^','%',',','{','}','[',']','(',')',';','#'}local B=(function()local B={new=function(self,C)local D={Parent=C,Locals={},Globals={},oldLocalNamesMap={},oldGlobalNamesMap={},Children={}}if C then table.insert(C.Children,D)end;return setmetatable(D,{__index=self})end,AddLocal=function(self,f)table.insert(self.Locals,f)end,AddGlobal=function(self,f)table.insert(self.Globals,f)end,CreateLocal=function(self,E)local f;f=self:GetLocal(E)if f then return f end;f={}f.Scope=self;f.Name=E;f.IsGlobal=false;f.CanRename=true;f.References=1;self:AddLocal(f)return f end,GetLocal=function(self,E)for n,F in pairs(self.Locals)do if F.Name==E then return F end end;if self.Parent then return self.Parent:GetLocal(E)end end,GetOldLocal=function(self,E)if self.oldLocalNamesMap[E]then return self.oldLocalNamesMap[E]end;return self:GetLocal(E)end,mapLocal=function(self,E,F)self.oldLocalNamesMap[E]=F end,GetOldGlobal=function(self,E)if self.oldGlobalNamesMap[E]then return self.oldGlobalNamesMap[E]end;return self:GetGlobal(E)end,mapGlobal=function(self,E,F)self.oldGlobalNamesMap[E]=F end,GetOldVariable=function(self,E)return self:GetOldLocal(E)or self:GetOldGlobal(E)end,RenameLocal=function(self,G,H)G=type(G)=='string'and G or G.Name;local I=false;local F=self:GetLocal(G)if F then F.Name=H;self:mapLocal(G,F)I=true end;if not I and self.Parent then self.Parent:RenameLocal(G,H)end end,RenameGlobal=function(self,G,H)G=type(G)=='string'and G or G.Name;local I=false;local F=self:GetGlobal(G)if F then F.Name=H;self:mapGlobal(G,F)I=true end;if not I and self.Parent then self.Parent:RenameGlobal(G,H)end end,RenameVariable=function(self,G,H)G=type(G)=='string'and G or G.Name;if self:GetLocal(G)then self:RenameLocal(G,H)else self:RenameGlobal(G,H)end end,GetAllVariables=function(self)local J=self:getVars(true)for n,f in pairs(self:getVars(false))do table.insert(J,f)end;return J end,getVars=function(self,K)local J={}if K then for n,f in pairs(self.Children)do for L,M in pairs(f:getVars(true))do table.insert(J,M)end end else for n,f in pairs(self.Locals)do table.insert(J,f)end;for n,f in pairs(self.Globals)do table.insert(J,f)end;if self.Parent then for n,f in pairs(self.Parent:getVars(false))do table.insert(J,f)end end end;return J end,CreateGlobal=function(self,E)local f;f=self:GetGlobal(E)if f then return f end;f={}f.Scope=self;f.Name=E;f.IsGlobal=true;f.CanRename=true;f.References=1;self:AddGlobal(f)return f end,GetGlobal=function(self,E)for n,f in pairs(self.Globals)do if f.Name==E then return f end end;if self.Parent then return self.Parent:GetGlobal(E)end end,GetVariable=function(self,E)return self:GetLocal(E)or self:GetGlobal(E)end,ObfuscateLocals=function(self,N,O)N=N or 7;local P=O or"QWERTYUIOPASDFGHJKLZXCVBNMqwertyuioplkjhgfdsazxcvbnm_"local Q=O or"QWERTYUIOPASDFGHJKLZXCVBNMqwertyuioplkjhgfdsazxcvbnm_1234567890"for e,F in pairs(self.Locals)do local R=""local S=0;repeat local T=math.random(1,#P)R=R..P:sub(T,T)for U=1,math.random(0,S>5 and 30 or N)do local T=math.random(1,#Q)R=R..Q:sub(T,T)end;S=S+1 until not self:GetVariable(R)self:RenameLocal(F.Name,R)end end}return B end)()local V=c{'and','break','do','else','elseif','end','false','for','function','goto','if','in','local','nil','not','or','repeat','return','then','true','until','while'}return function(W)local X={}local Y,Z=pcall(function()local _=1;local r=1;local a0=1;local function a1()local h=W:sub(_,_)if h=='\n'then a0=1;r=r+1 else a0=a0+1 end;_=_+1;return h end;local function a2(T)T=T or 0;return W:sub(_+T,_+T)end;local function a3(P)local h=a2()for U=1,#P do if h==P:sub(U,U)then return a1()end end end;local function a4(Z)return error(">> :"..r..":"..a0 ..": "..Z,0)end;local function a5()local a6=_;if a2()=='['then local a7=0;local a8=1;while a2(a7+1)=='='do a7=a7+1 end;if a2(a7+1)=='['then for e=0,a7+1 do a1()end;local a9=_;while true do if a2()==''then a4("Expected `]"..string.rep('=',a7).."]` near <eof>.",3)end;local aa=true;if a2()==']'then for U=1,a7 do if a2(U)~='='then aa=false end end;if a2(a7+1)~=']'then aa=false end else if a2()=='['then local ab=true;for U=1,a7 do if a2(U)~='='then ab=false;break end end;if a2(a7+1)=='['and ab then a8=a8+1;for U=1,a7+2 do a1()end end end;aa=false end;if aa then a8=a8-1;if a8==0 then break else for U=1,a7+2 do a1()end end else a1()end end;local ac=W:sub(a9,_-1)for U=0,a7+1 do a1()end;local ad=W:sub(a6,_-1)return ac,ad else return nil end else return nil end end;while true do local ae={}local af=''local ag=false;while true do local h=a2()if h=='#'and a2(1)=='!'and r==1 then a1()a1()af="#!"while a2()~='\n'and a2()~=''do af=af..a1()end;local ah={Type='Comment',CommentType='Shebang',Data=af,Line=r,Char=a0}ah.Print=function()return"<"..(ah.Type..string.rep(' ',7-#ah.Type)).." "..(ah.Data or'').." >"end;af=""table.insert(ae,ah)end;if h==' 'or h=='\t'then local ai=a1()table.insert(ae,{Type='Whitespace',Line=r,Char=a0,Data=ai})elseif h=='\n'or h=='\r'then local aj=a1()if af~=""then local ah={Type='Comment',CommentType=ag and'LongComment'or'Comment',Data=af,Line=r,Char=a0}ah.Print=function()return"<"..(ah.Type..string.rep(' ',7-#ah.Type)).." "..(ah.Data or'').." >"end;table.insert(ae,ah)af=""end;table.insert(ae,{Type='Whitespace',Line=r,Char=a0,Data=aj})elseif h=='-'and a2(1)=='-'then a1()a1()af=af..'--'local e,ak=a5()if ak then af=af..ak;ag=true else while a2()~='\n'and a2()~=''do af=af..a1()end end else break end end;if af~=""then local ah={Type='Comment',CommentType=ag and'LongComment'or'Comment',Data=af,Line=r,Char=a0}ah.Print=function()return"<"..(ah.Type..string.rep(' ',7-#ah.Type)).." "..(ah.Data or'').." >"end;table.insert(ae,ah)end;local al=r;local am=a0;local an=":"..r..":"..a0 ..":> "local h=a2()local ao=nil;if h==''then ao={Type='Eof'}elseif x[h]or w[h]or h=='_'then local a6=_;repeat a1()h=a2()until not(x[h]or w[h]or y[h]or h=='_')local ap=W:sub(a6,_-1)if V[ap]then ao={Type='Keyword',Data=ap}else ao={Type='Ident',Data=ap}end elseif y[h]or a2()=='.'and y[a2(1)]then local a6=_;if h=='0'and a2(1)=='x'then a1()a1()while z[a2()]do a1()end;if a3('Pp')then a3('+-')while y[a2()]do a1()end end else while y[a2()]do a1()end;if a3('.')then while y[a2()]do a1()end end;if a3('Ee')then a3('+-')while y[a2()]do a1()end end end;ao={Type='Number',Data=W:sub(a6,_-1)}elseif h=='\''or h=='\"'then local a6=_;local aq=a1()local a9=_;while true do local h=a1()if h=='\\'then a1()elseif h==aq then break elseif h==''then a4("Unfinished string near <eof>")end end;local ar=W:sub(a9,_-2)local as=W:sub(a6,_-1)ao={Type='String',Data=as,Constant=ar}elseif h=='['then local ar,at=a5()if at then ao={Type='String',Data=at,Constant=ar}else a1()ao={Type='Symbol',Data='['}end elseif a3('>=<')then if a3('=')then ao={Type='Symbol',Data=h..'='}else ao={Type='Symbol',Data=h}end elseif a3('~')then if a3('=')then ao={Type='Symbol',Data='~='}else a4("Unexpected symbol `~` in source.",2)end elseif a3('.')then if a3('.')then if a3('.')then ao={Type='Symbol',Data='...'}else ao={Type='Symbol',Data='..'}end else ao={Type='Symbol',Data='.'}end elseif a3(':')then if a3(':')then ao={Type='Symbol',Data='::'}else ao={Type='Symbol',Data=':'}end elseif A[h]then a1()ao={Type='Symbol',Data=h}else local au,av=a5()if au then ao={Type='String',Data=av,Constant=au}else a4("Unexpected Symbol `"..h.."` in source.",2)end end;ao.LeadingWhite=ae;ao.Line=al;ao.Char=am;ao.Print=function()return"<"..(ao.Type..string.rep(' ',7-#ao.Type)).." "..(ao.Data or'').." >"end;X[#X+1]=ao;if ao.Type=='Eof'then break end end end)if not Y then return false,Z end;local aw={}local ax={}local _=1;function aw:getp()return _ end;function aw:setp(T)_=T end;function aw:getTokenList()return X end;function aw:Peek(T)T=T or 0;return X[math.min(#X,_+T)]end;function aw:Get(ay)local az=X[_]_=math.min(_+1,#X)if ay then table.insert(ay,az)end;return az end;function aw:Is(az)return aw:Peek().Type==az end;function aw:Save()ax[#ax+1]=_ end;function aw:Commit()ax[#ax]=nil end;function aw:Restore()_=ax[#ax]ax[#ax]=nil end;function aw:ConsumeSymbol(aA,ay)local az=self:Peek()if az.Type=='Symbol'then if aA then if az.Data==aA then self:Get(ay)return true else return nil end else self:Get(ay)return az end else return nil end end;function aw:ConsumeKeyword(aB,ay)local az=self:Peek()if az.Type=='Keyword'and az.Data==aB then self:Get(ay)return true else return nil end end;function aw:IsKeyword(aB)local az=aw:Peek()return az.Type=='Keyword'and az.Data==aB end;function aw:IsSymbol(D)local az=aw:Peek()return az.Type=='Symbol'and az.Data==D end;function aw:IsEof()return aw:Peek().Type=='Eof'end;return true,aw end end)()local function aC(aD)return({a(aD)})[2].getTokenList()end;local function aE(X)local aF={}local function aG(type,aH)local aI=aF[#aF]if aI~=nil and aI.type==type then aI.data=aI.data..aH else aF[#aF+1]={type=type,data=aH}end end;for az=1,#X do local ah=X[az]for aJ=1,#ah.LeadingWhite do local aK=ah.LeadingWhite[aJ]if aK.Data~=nil and aK.Data:len()>0 then aG(aK.Type,aK.Data)end end;if ah.Data~=nil and ah.Data:len()>0 then aG(ah.Type,ah.Data)end end;return aF end;local function aL(aF)local function aM(X)local aN={}local aO={}for U=1,#X do local ah=X[U]local aH=ah.data;local aP=aH:find('\n')if aP then local aQ=aH:sub(1,aP-1)local aR=aH:sub(aP+1)if aQ:len()>0 then aN[#aN+1]={type=ah.type,data=aQ}end;if aR:len()>0 then aO[#aO+1]={type=ah.type,data=aR}end;for aS=U+1,#X do aO[#aO+1]={type=X[aS].type,data=X[aS].data}end;return aN,aO else aN[#aN+1]={type=ah.type,data=aH}end end;return aN,nil end;local q={}local aT=aF;while aT and#aT>0 do local aN,aO=aM(aT)aT=aO;q[#q+1]=aN end;return q end;return{getTokens=aC,flattenTokens=aE,flatToLines=aL,getLines=function(aD)return aL(aE(aC(aD)))end}end)()local inspect = (function()local a={_VERSION='inspect.lua 3.1.0',_URL='http://github.com/kikito/inspect.lua',_DESCRIPTION='human-readable representations of tables',_LICENSE=[[ MIT LICENSE
- Copyright (c) 2013 Enrique GarcÃa Cota
- Permission is hereby granted, free of charge, to any person obtaining a
- copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- ]]}local tostring=tostring;a.KEY=setmetatable({},{__tostring=function()return'inspect.KEY'end})a.METATABLE=setmetatable({},{__tostring=function()return'inspect.METATABLE'end})local function b(c)if c:match('"')and not c:match("'")then return"'"..c.."'"end;return'"'..c:gsub('"','\\"')..'"'end;local d={["\a"]="\\a",["\b"]="\\b",["\f"]="\\f",["\n"]="\\n",["\r"]="\\r",["\t"]="\\t",["\v"]="\\v"}local e={}for f=0,31 do local g=string.char(f)if not d[g]then d[g]="\\"..f;e[g]=string.format("\\%03d",f)end end;local function h(c)return c:gsub("\\","\\\\"):gsub("(%c)%f[0-9]",e):gsub("%c",d)end;local function i(c)return type(c)=='string'and c:match("^[_%a][_%a%d]*$")end;local function j(k,l)return type(k)=='number'and 1<=k and k<=l and math.floor(k)==k end;local m={['number']=1,['boolean']=2,['string']=3,['table']=4,['function']=5,['userdata']=6,['thread']=7}local function n(o,p)local q,r=type(o),type(p)if q==r and(q=='string'or q=='number')then return o<p end;local s,t=m[q],m[r]if s and t then return m[q]<m[r]elseif s then return true elseif t then return false end;return q<r end;local function u(v)local w=1;local x=rawget(v,w)while x~=nil do w=w+1;x=rawget(v,w)end;return w-1 end;local function y(v)local z={}local l=u(v)for k,A in pairs(v)do if not j(k,l)then table.insert(z,k)end end;table.sort(z,n)return z,l end;local function B(v,C)local D=type(C)=='table'and rawget(C,'__tostring')local c,E;if type(D)=='function'then E,c=pcall(D,v)c=E and c or'error: '..tostring(c)end;if type(c)=='string'and#c>0 then return c end end;local function F(v,G)G=G or{}if type(v)=='table'then if not G[v]then G[v]=1;for k,x in pairs(v)do F(k,G)F(x,G)end;F(getmetatable(v),G)else G[v]=G[v]+1 end end;return G end;local H=function(I)local J,w={},#I;for f=1,w do J[f]=I[f]end;return J,w end;local function K(L,...)local z={...}local M,w=H(L)for f=1,#z do M[w+f]=z[f]end;return M end;local function N(O,P,L,Q)if P==nil then return nil end;if Q[P]then return Q[P]end;local R=O(P,L)if type(R)=='table'then local S={}Q[P]=S;local T;for k,x in pairs(R)do T=N(O,k,K(L,k,a.KEY),Q)if T~=nil then S[T]=N(O,x,K(L,T),Q)end end;local C=N(O,getmetatable(R),K(L,a.METATABLE),Q)setmetatable(S,C)R=S end;return R end;local U={}local V={__index=U}function U:puts(...)local W={...}local X=self.buffer;local w=#X;for f=1,#W do w=w+1;X[w]=W[f]end end;function U:down(Y)self.level=self.level+1;Y()self.level=self.level-1 end;function U:tabify()self:puts(self.newline,string.rep(self.indent,self.level))end;function U:alreadyVisited(x)return self.ids[x]~=nil end;function U:getId(x)local Z=self.ids[x]if not Z then local _=type(x)Z=(self.maxIds[_]or 0)+1;self.maxIds[_]=Z;self.ids[x]=Z end;return tostring(Z)end;function U:putKey(k)if i(k)then return self:puts(k)end;self:puts("[")self:putValue(k)self:puts("]")end;function U:putTable(v)if v==a.KEY or v==a.METATABLE then self:puts(tostring(v))elseif self:alreadyVisited(v)then self:puts('<table ',self:getId(v),'>')elseif self.level>=self.depth then self:puts('{...}')else if self.tableAppearances[v]>1 then self:puts('<',self:getId(v),'>')end;local a0,l=y(v)local C=getmetatable(v)local a1=B(v,C)self:puts('{')self:down(function()if a1 then self:puts(' -- ',h(a1))if l>=1 then self:tabify()end end;local a2=0;for f=1,l do if a2>0 then self:puts(',')end;self:puts(' ')self:putValue(v[f])a2=a2+1 end;for A,k in ipairs(a0)do if a2>0 then self:puts(',')end;self:tabify()self:putKey(k)self:puts(' = ')self:putValue(v[k])a2=a2+1 end;if C then if a2>0 then self:puts(',')end;self:tabify()self:puts('<metatable> = ')self:putValue(C)end end)if#a0>0 or C then self:tabify()elseif l>0 then self:puts(' ')end;self:puts('}')end end;function U:putValue(x)local _=type(x)if _=='string'then self:puts(b(h(x)))elseif _=='number'or _=='boolean'or _=='nil'then self:puts(tostring(x))elseif _=='table'then self:putTable(x)else self:puts('<',_,' ',self:getId(x),'>')end end;function a.inspect(a3,a4)a4=a4 or{}local a5=a4.depth or math.huge;local a6=a4.newline or'\n'local a7=a4.indent or' 'local O=a4.process;if O then a3=N(O,a3,{},{})end;local a8=setmetatable({depth=a5,level=0,buffer={},ids={},maxIds={},newline=a6,indent=a7,tableAppearances=F(a3)},V)a8:putValue(a3)return table.concat(a8.buffer)end;setmetatable(a,{__call=function(A,...)return a.inspect(...)end})return a;end)()
- local args = {...}
- if #args > 1 then
- print('too many arguments')
- return
- elseif #args < 1 then
- print('too few arguments')
- return
- end
- local path = args[1]
- if not fs.exists(path) or fs.isDir(path) then
- print('path must be a file that exists')
- return
- end
- local handle = fs.open(path, 'r')
- local lines = lexer.getLines(handle.readAll())
- handle.close()
- local apis = {
- -- tables
- biginteger = true,
- bit = true,
- bit32 = true,
- bitop = true,
- colors = true,
- colours = true,
- coroutine = true,
- data = true,
- disk = true,
- fs = true,
- gps = true,
- help = true,
- http = true,
- io = true,
- keys = true,
- math = true,
- os = true,
- paintutils = true,
- parallel = true,
- peripheral = true,
- rednet = true,
- redstone = true,
- rs = true,
- shell = true,
- socket = true,
- string = true,
- table = true,
- term = true,
- textutils = true,
- vector = true,
- window = true,
- -- functions
- assert = true,
- collectgarbage = true,
- dofile = true,
- error = true,
- getfenv = true,
- getmetatable = true,
- ipairs = true,
- loadfile = true,
- loadstring = true,
- module = true,
- next = true,
- pairs = true,
- pcall = true,
- print = true,
- rawequal = true,
- rawget = true,
- rawset = true,
- require = true,
- select = true,
- setfenv = true,
- setmetatable = true,
- tonumber = true,
- tostring = true,
- type = true,
- unpack = true,
- xpcall = true,
- write = true
- }
- local lineLen = tostring(#lines):len()
- for line = 1, #lines do
- local tokens = lines[line]
- term.setTextColor(colors.gray)
- term.write((' '):rep(lineLen - tostring(line):len()) .. tostring(line) .. ' ')
- for i = 1, #tokens do
- local token = tokens[i]
- if token.type == 'Keyword' then
- term.setTextColor(colors.yellow)
- elseif token.type == 'Number' then
- term.setTextColor(colors.purple)
- elseif token.type == 'Comment' then
- term.setTextColor(colors.gray)
- elseif token.type == 'Ident' and apis[token.data] then
- term.setTextColor(colors.cyan)
- elseif token.type == 'String' then
- term.setTextColor(colors.red)
- else
- term.setTextColor(colors.white)
- end
- term.write(token.data)
- end
- write('\n')
- end
- --[[
- multiline
- comment
- ]] return
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement