Skip to content

Instantly share code, notes, and snippets.

@iamgreaser
Created February 2, 2016 20:56
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