/bootcore.lua Secret
Created
February 2, 2016 20:56
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local CR,P,SMT,k,v,i=component,computer,setmetatable | |
local function cwrap(addr)return SMT({},{__index=function(t,k) | |
return function(...)return CR.invoke(addr,k,...)end end, | |
__call=function(t) return addr end})end | |
local C=SMT({},{__index=function(t,k)return CR[k] or cwrap(CR.list(k)())end}) | |
for i=1,4 do P.beep(220*i,0.1)end | |
local SR=P.pullSignal | |
while SR(0.05) do end | |
local G=C.gpu | |
G.bind(C.screen()) | |
G.setBackground(0) | |
G.setForeground(0xFFFFFF) | |
G.setResolution(G.maxResolution()) | |
local E,Ec,gcpoll={},{} | |
function E.ignore(e,f)local i | |
if Ec[e]then for i=1,#Ec[e]do if f==Ec[e]then | |
table.remove(Ec[e],i)return end end end end | |
function E.listen(e,f)E.ignore(e,f) | |
if not Ec[e]then Ec[e]={}end | |
Ec[e][#Ec[e]+1]=f end | |
function E.pull(t)gcpoll()local l={SR(t)}--TODO name filter | |
local n,i=l[1]if n and Ec[n]then | |
for i=1,#Ec[n]do Ec[n](table.unpack(l))end end | |
return table.unpack(l)end | |
local T={} | |
do | |
local tx,ty=1,1 | |
local tw,th | |
local getr=function()tw,th=G.getResolution()end | |
getr() | |
function T.isAvailable()return true end | |
function T.getCursor()return tx,ty end | |
function T.setCursor(x,y)tx,ty=x,y end | |
function T.clear()G.fill(1,1,tw,th," ")tx,ty=1,1 end | |
function T.write(s,wrap)getr()local b,bx,i="" | |
local function unbuf()if b~=""then | |
if bx<tw then G.copy(bx,ty,tw-bx,1,#b,0)end | |
G.set(bx,ty,b)bx=nil b=""end end | |
for i=1,#s do | |
local c=s:sub(i,i) | |
if c=="\n"then unbuf()tx=1 ty=ty+1 | |
elseif c=="\r"then unbuf()tx=1 | |
elseif c=="\t"then unbuf()tx=((tx-1)-((tx-1)%8))+9 | |
elseif c=="\b"then unbuf()tx=math.max(1,tx-1)G.set(tx,ty," ") | |
else bx=bx or tx b=b..c tx=tx+1 | |
end | |
if tx>tw then unbuf()if wrap then tx=1 ty=ty+1 else tx=tw end end | |
if ty>th then unbuf()ty=th G.copy(1,2,tw,th-1,0,-1) G.fill(1,th,tw,1," ") end | |
end unbuf() | |
end | |
function T.read(hi,db,fh,pw) | |
local b,a,c="" | |
while true do | |
a={E.pull()} | |
if a[1]=="key_down"then | |
if a[3]>=32 then c=utf8.char(a[3])T.write(c)b=b..c | |
elseif a[3]==13 then T.write("\n")return b | |
elseif a[3]==8 and#b>0 then T.write("\b") | |
if 127<b:byte(#b)then | |
while 192>b:byte(#b)and#b>0 do b=b:sub(1,#b-1)T.write("\b")end end | |
b=b:sub(1,#b-1) | |
else --print(a[3],a[4]) | |
end | |
end | |
end | |
end | |
end | |
function print(...) | |
local a,i={...}for i=1,#a do T.write(tostring(a[i]),true) | |
if i<#a then T.write("\t",true)end end | |
T.write("\n",true)end | |
T.clear() | |
print("Bootcore loading!") | |
local G1,G2={},SMT({},{__mode="v"}) | |
function gcable(o,f) | |
assert(o and f) | |
local i=#G1+1 | |
G1[i]=f | |
G2[i]=o | |
return o | |
end | |
gcpoll=function() | |
while #G1~=#G2 do | |
local t,f=#G2+1,#G1 | |
assert(pcall(G1[t])) | |
if t==f then G1[t],G2[t]=nil end | |
G1[t],G2[t],G1[f],G2[f]=G1[f],G2[f] | |
end | |
end | |
local dnt={} | |
local D={byname={},ntyp=dnt} | |
for k,v in C.list"filesystem" do | |
local d,n,f={id=k},"dh",cwrap(k) | |
d.fs=f | |
if f.isReadOnly()then n="rom" | |
elseif f.getLabel()=="tmpfs" then n="ram" | |
elseif f.spaceTotal()==512*1024 then n="df" | |
end | |
dnt[n]=(dnt[n] or 0)+1 | |
n=n..(dnt[n]-1) | |
d.name=n | |
D.byname[n]=d | |
end | |
local iofs=((D.byname.dh0 and"dh0") | |
or(D.byname.df0 and"df0") | |
or(D.byname.rom0 and"rom0")) | |
do local ba=D.byname[iofs].id function P.getBootAddress()return ba end end | |
local iocd="/" | |
local function Dfix(n) | |
while n:find("//")do n=n:gsub("//","/")end | |
--while n:find("..")do n end--TODO! | |
return n | |
end | |
local function Dpath(n) | |
local pc,ps,cfs | |
cfs=iofs | |
pc,ps=n:find(":"),n:find("/") | |
if pc and((not ps) or pc<ps)then return n:sub(1,pc-1),Dfix("/"..n:sub(pc+1)) | |
elseif ps==1 then return iofs,Dfix(n) | |
else return iofs,Dfix(iocd.."/"..n) | |
end | |
end | |
io={ | |
stdin={read=function()return T.read()end}, | |
stdout={write=function(s)return T.write(s,true)end, | |
setvbuf=function()end}, | |
input=function()return io.stdin end, | |
output=function()return io.stdout end, | |
open=function(n,m) | |
local dn,pn,fs,fd=Dpath(n) | |
fs=D.byname[dn].fs | |
fd=fs.open(pn,m or"r") | |
assert(fd,dn.."|"..pn) | |
return gcable({ | |
read=function(t,a) | |
local r,s="" | |
if a=="*a" then repeat s=fs.read(fd,999)if s then r=r..s end until s=="" or not s return r | |
elseif a=="*l"or a=="*L"or not a then while true do | |
s=fs.read(fd,1) if s=="\n" or s==""or not s then | |
if a=="*L"then r=r..(s or"")end | |
if r==""then return nil else return r end end r=r..s end | |
else return fs.read(fd,a) | |
end | |
end, | |
close=function()fs.close(fd)fd=nil end | |
},function()if fd then fs.close(fd)end end) | |
end, | |
write=function(s)return T.write(s,true)end, | |
} | |
io.stderr=io.stdout | |
local env={} | |
os.getenv=function(n)if n=="PWD"then return shell.getWorkingDirectory()end | |
return env[n]end | |
os.setenv=function(n,v)if n=="PWD"then return shell.setWorkingDirectory(v)end | |
env[n]=v end | |
os.execute=function(s) | |
local p,i={} | |
while true do i=s:find(" ")if i | |
then p[#p+1],s=s:sub(1,i-1),s:sub(i+1) else p[#p+1]=s break end | |
end | |
local n=loadfile("/bin/"..p[1]..".lua")(table.unpack(p,2)) | |
return "exit",n or 0 | |
end | |
shell={ | |
getWorkingDirectory=function()return iofs..":"..iocd end, | |
setWorkingDirectory=function(w)iofs,iocd=Dpath(w)end, | |
resolve=function(n,x)assert(not x,x)n,x=Dpath(n)return n..":"..x end, | |
parse=function(...)local a,o,p,i,j,v,s={},{},{...}for i=1,#p do | |
v=p[i]if v:sub(1,1)=="-"then for j=2,#v do o[v:sub(j,j)]=true end | |
else a[#a+1]=v end | |
end return a,o end | |
} | |
local text={ | |
trim=function(s)return s end,--TODO! | |
} | |
function loadfile(fn)local f,s | |
f=io.open(fn,"r")s=f:read("*a")f:close()return load(s,fn)end | |
function dofile(fn,...)return loadfile(fn)(...)end | |
function Dinvoker(n,z)return function(p,...) | |
local a,d=Dpath(p)d=D.byname[a]return(d and d.fs[n](...))or error(n) end end | |
local fsm fsm=SMT({ | |
get=function(s)local a=(Dpath(s))return D.byname[a].fs,a..":"end, | |
},{__index=function(t,k)return rawget(t,k)or Dinvoker(k)end}) | |
local MB={gpu=G,term=T,component=C,computer=P,event=E,shell=shell, | |
text=text,filesystem=fsm} | |
function require(n)return MB[n]end | |
while true do | |
k,v=pcall(dofile,"dh0:/bin/sh.lua") | |
if not k then print(v or"nil",debug.traceback())end | |
end | |
print("HALTED")while true do E.pull(1.0)end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment