This week only. Pastebin PRO Accounts Christmas Special! Don't miss out!Want more features on Pastebin? Sign Up, it's FREE!
Guest

CCOS 0.2 for ComputerCraft

By: zhykzhykzhyk on Jan 19th, 2012  |  syntax: Lua  |  size: 18.08 KB  |  views: 655  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. require 'org.luaj.vm2.lib.DebugLib'
  2. require 'org.luaj.vm2.lib.jse.LuajavaLib'
  3. local debug = debug
  4.  
  5. local function duplicate(table, base)
  6.         local t = base or { }
  7.         for i, v in pairs(table) do
  8.                 t[i] = v
  9.         end
  10.         return t
  11. end
  12.  
  13. local function clone(table)
  14.         local t = { }
  15.         local function clones(table)
  16.                 if type(table) ~= 'table' then
  17.                         return table
  18.                 end
  19.                 if not t[table] then
  20.                         t[table] = { }
  21.                         for i, v in pairs(table) do
  22.                                 t[table][i] = clones(v)
  23.                         end
  24.                 end
  25.                 return t[table]
  26.         end
  27.         return clones(table)
  28. end
  29.  
  30. local empty = { }
  31. local userfun = { }
  32. local error
  33.  
  34. local print
  35.  
  36. local function rvpack(...)
  37.         local arg = {...}
  38.         arg.n = select('#', ...)
  39.         arg.s = 1
  40.         return arg
  41. end
  42.  
  43. local function rvunpack(t, s, n)
  44.         return unpack(t, s or t.s, n or t.n)
  45. end
  46.  
  47. local function rvshift(t, d)
  48.         t.s = t.s + d
  49.         return t
  50. end
  51.  
  52. local function protectenv(table, force)
  53.         local t = { }
  54.         local getfenv = getfenv
  55.         local setfenv = setfenv
  56.         local select = select
  57.         local function sub(table)
  58.                 if not t[table] then
  59.                         t[table] = true
  60.                         for i, v in pairs(table) do
  61.                                 if force or userfun[v] then
  62.                                         table[i] = setfenv(function(...)
  63.                                                 local p, err = getfenv(v)
  64.                                                 local f = setfenv(v, getfenv(0))
  65.                                                 local r = rvpack(f(...))
  66.                                                 if p then
  67.                                                         setfenv(v, p)
  68.                                                 end
  69.                                                 return rvunpack(r)
  70.                                         end, empty)
  71.                                 elseif type(v) == 'table' then
  72.                                         sub(v)
  73.                                 end
  74.                         end
  75.                 end
  76.         end
  77.         sub(table)
  78. end
  79.  
  80. local parallels = { }
  81. local currentParallel = nil
  82. local currentProcess = nil
  83. local processInfo = setmetatable({}, { __mode = 'k' })
  84. local handles = setmetatable({}, { __mode = 'k' })
  85. local returnValue
  86. local timers = { }
  87.  
  88. function pullEventRaw()
  89.         local event = rvpack(coroutine.yield())
  90.         if event[1] == 'terminate' then
  91.                 local info = processInfo[parallels[1].currentProcess]
  92.                 info.status = 'dead'
  93.                 info.parent.returnValue = rvpack('error', 'terminated')
  94.         else
  95.                 if event[1] == 'timer' and timers[event[2]] then
  96.                         timers[event[2]]()
  97.                         timers[event[2]] = nil
  98.                 end
  99.                 return event
  100.         end
  101. end
  102.  
  103. local events = { }
  104. events.back = events
  105. local ignoreEvents = false
  106. local waiting = false
  107. local listener = { }
  108.  
  109. local function queueEvent(event)
  110.         local e = { value = event }
  111.         events.back.next = e
  112.         events.back = e
  113. end
  114.  
  115. local function pullEvent(wait)
  116.         if currentParallel.events.next then
  117.                 currentParallel.events = currentParallel.events.next
  118.                 return assert(currentParallel.events.value)
  119.         end
  120.         return nil
  121. end
  122.  
  123. --TODO: work with parallel
  124. local function sleep(time)
  125.         local timer = os.startTimer(time)
  126.         local info = processInfo[currentProcess]
  127.         if info.status ~= 'dead' then
  128.                 info.status = 'wait'
  129.                 info.wait = function() end
  130.                 timers[timer] = function()
  131.                         if info.status ~= 'dead' then
  132.                                 info.status = 'normal'
  133.                         end
  134.                 end
  135.         end
  136. end
  137.  
  138. local function flushEvent()
  139.         --sleep(0)
  140.         coroutine.yield('sleep', 0)
  141. end
  142.  
  143. loadfile = function(fn)
  144.         local file = fs.open(fn, "r")
  145.         if file then
  146.                 local func, err = loadstring(file.readAll(), fn)
  147.                 file.close()
  148.                 return func, err
  149.         end
  150.         return nil, "File not found"
  151. end
  152.  
  153. dofile = function(fn)
  154.         local fun, e = loadfile(fn)
  155.         if fun then
  156.                 return fun()
  157.         else
  158.                 error(e)
  159.         end
  160. end
  161.  
  162. function write( sText )
  163.         local w,h = term.getSize()             
  164.         local x,y = term.getCursorPos()
  165.        
  166.         local nLinesPrinted = 0
  167.         local function newLine()
  168.                 if y + 1 <= h then
  169.                         term.setCursorPos(1, y + 1)
  170.                 else
  171.                         term.scroll(1)
  172.                         term.setCursorPos(1, h)
  173.                 end
  174.                 x, y = term.getCursorPos()
  175.                 nLinesPrinted = nLinesPrinted + 1
  176.         end
  177.        
  178.         -- Print the line with proper word wrapping
  179.         while string.len(sText) > 0 do
  180.                 local whitespace = string.match( sText, "^[ \t]+" )
  181.                 if whitespace then
  182.                         -- Print whitespace
  183.                         term.write( whitespace )
  184.                         x,y = term.getCursorPos()
  185.                         sText = string.sub( sText, string.len(whitespace) + 1 )
  186.                 end
  187.                
  188.                 local newline = string.match( sText, "^\n" )
  189.                 if newline then
  190.                         -- Print newlines
  191.                         newLine()
  192.                         sText = string.sub( sText, 2 )
  193.                 end
  194.                
  195.                 local text = string.match( sText, "^[^ \t\n]+" )
  196.                 if text then
  197.                         sText = string.sub( sText, string.len(text) + 1 )
  198.                         if string.len(text) > w then
  199.                                 -- Print a multiline word                              
  200.                                 while string.len( text ) > 0 do
  201.                                 if x > w then
  202.                                         newLine()
  203.                                 end
  204.                                         term.write( text )
  205.                                         text = string.sub( text, (w-x) + 2 )
  206.                                         x,y = term.getCursorPos()
  207.                                 end
  208.                         else
  209.                                 -- Print a word normally
  210.                                 if x + string.len(text) > w then
  211.                                         newLine()
  212.                                 end
  213.                                 term.write( text )
  214.                                 x,y = term.getCursorPos()
  215.                         end
  216.                 end
  217.         end
  218.        
  219.         return nLinesPrinted
  220. end
  221.  
  222. function print( ... )
  223.         local nLinesPrinted = 0
  224.         for n,v in ipairs( { ... } ) do
  225.                 nLinesPrinted = nLinesPrinted + write( tostring( v ) )
  226.         end
  227.         nLinesPrinted = nLinesPrinted + write( "\n" )
  228.         return nLinesPrinted
  229. end
  230.  
  231. function read( _sReplaceChar, _tHistory )
  232.         setfenv(1, getfenv(0))
  233.         term.setCursorBlink( true )
  234.  
  235.     local sLine = ""
  236.         local nHistoryPos = nil
  237.         local nPos = 0
  238.     if _sReplaceChar then
  239.                 _sReplaceChar = string.sub( _sReplaceChar, 1, 1 )
  240.         end
  241.        
  242.         local w, h = term.getSize()
  243.         local sx, sy = term.getCursorPos()     
  244.         local function redraw()
  245.                 local nScroll = 0
  246.                 if sx + nPos >= w then
  247.                         nScroll = (sx + nPos) - w
  248.                 end
  249.                        
  250.                 term.setCursorPos( sx, sy )
  251.                 term.write( string.rep(" ", w - sx + 1) )
  252.                 term.setCursorPos( sx, sy )
  253.                 if _sReplaceChar then
  254.                         term.write( string.rep(_sReplaceChar, string.len(sLine) - nScroll) )
  255.                 else
  256.                         term.write( string.sub( sLine, nScroll + 1 ) )
  257.                 end
  258.                 term.setCursorPos( sx + nPos - nScroll, sy )
  259.         end
  260.        
  261.         while true do
  262.                 local sEvent, param = os.pullEvent()
  263.                 if sEvent == "char" then
  264.                         sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )
  265.                         nPos = nPos + 1
  266.                         redraw()
  267.                        
  268.                 elseif sEvent == "key" then
  269.                     if param == 28 then
  270.                                 -- Enter
  271.                                 break
  272.                                
  273.                         elseif param == 203 then
  274.                                 -- Left
  275.                                 if nPos > 0 then
  276.                                         nPos = nPos - 1
  277.                                         redraw()
  278.                                 end
  279.                                
  280.                         elseif param == 205 then
  281.                                 -- Right                               
  282.                                 if nPos < string.len(sLine) then
  283.                                         nPos = nPos + 1
  284.                                         redraw()
  285.                                 end
  286.                        
  287.                         elseif param == 200 or param == 208 then
  288.                 -- Up or down
  289.                                 if _tHistory then
  290.                                         if param == 200 then
  291.                                                 -- Up
  292.                                                 if nHistoryPos == nil then
  293.                                                         if #_tHistory > 0 then
  294.                                                                 nHistoryPos = #_tHistory
  295.                                                         end
  296.                                                 elseif nHistoryPos > 1 then
  297.                                                         nHistoryPos = nHistoryPos - 1
  298.                                                 end
  299.                                         else
  300.                                                 -- Down
  301.                                                 if nHistoryPos == #_tHistory then
  302.                                                         nHistoryPos = nil
  303.                                                 elseif nHistoryPos ~= nil then
  304.                                                         nHistoryPos = nHistoryPos + 1
  305.                                                 end                                            
  306.                                         end
  307.                                        
  308.                                         if nHistoryPos then
  309.                         sLine = _tHistory[nHistoryPos]
  310.                         nPos = string.len( sLine )
  311.                     else
  312.                                                 sLine = ""
  313.                                                 nPos = 0
  314.                                         end
  315.                                         redraw()
  316.                 end
  317.                         elseif param == 14 then
  318.                                 -- Backspace
  319.                                 if nPos > 0 then
  320.                                         sLine = string.sub( sLine, 1, nPos - 1 ) .. string.sub( sLine, nPos + 1 )
  321.                                         nPos = nPos - 1                                
  322.                                         redraw()
  323.                                 end
  324.                         end
  325.                 end
  326.         end
  327.        
  328.         term.setCursorBlink( false )
  329.         term.setCursorPos( w + 1, sy )
  330.         print()
  331.        
  332.         return sLine
  333. end
  334.  
  335. local function split(str, sub)
  336.         local t = { }
  337.         local p = 1
  338.         local q = string.find(str, sub, p, true)
  339.         local l = string.len(sub)
  340.         while q do
  341.                 table.insert(t, string.sub(str, p, q - 1))
  342.                 p = q + l
  343.                 q = string.find(str, sub, p, true)
  344.         end
  345. end
  346.  
  347. local tenv = {
  348.         os = {
  349.                 version = function()
  350.                         return 'CCOS 0.2'
  351.                 end,
  352.                 computerID = os.computerID,
  353.                 run = function (env, path, ...)
  354.                         local file, err = loadfile(path)
  355.                         if file then
  356.                                 local ret = rvpack(coroutine.yield('exec', loadfile(path), rvpack(...), nil, setmetatable(env, { __index = _G })))
  357.                                 if ret[1] == 'error' then
  358.                                         ret[1] = false
  359.                                         print(ret[2])
  360.                                 end
  361.                                 return rvunpack(ret)
  362.                         else
  363.                                 return false, err
  364.                         end
  365.                 end,
  366.                 loadAPI = function(path)
  367.                         return false, 'Premission denied'
  368.                 end,
  369.                 unloadAPI = function(name)
  370.                         return false, 'Premission denied'
  371.                 end,
  372.                 pullEvent = function()
  373.                         return coroutine.yield('pull')
  374.                 end,
  375.                 pullEventRaw = function()
  376.                         return coroutine.yield('pull')
  377.                 end,
  378.                 queueEvent = os.queueEvent,
  379.                 clock = os.clock,
  380.                 startTimer = os.startTimer,
  381.                 sleep = function(time, hold)
  382.                         coroutine.yield('sleep', time)
  383.                         if not hold then
  384.                                 coroutine.yield('discard')
  385.                         end
  386.                 end,
  387.                 time = os.time,
  388.                 shutdown = function()
  389.                         coroutine.yield('shutdown')
  390.                 end,
  391.                 reboot = os.reboot,
  392.                 setAlarm = os.setAlarm,
  393.         },
  394.         coroutine = coroutine,
  395.         redstone = redstone,
  396.         term = term,
  397.         math = math,
  398.         table = table,
  399.         fs = fs,
  400.         rs = rs,
  401.         string = string,
  402.         sleep = function(time)
  403.                 coroutine.yield('sleep', time)
  404.         end,
  405.         disk = disk,
  406.         getmetatable = getmetatable,
  407.         unpack = unpack,
  408.         __inext = __inext,
  409.         _VERSION = _VERSION,
  410.         ipairs = ipairs,
  411.         load = load,
  412.         print = print,
  413.         read = read,
  414.         write = write,
  415.         pcall = pcall,
  416.         assert = assert,
  417.         tonumber = tonumber,
  418.         rawequal = rawequal,
  419.         loadstring = loadstring,
  420.         loadfile = loadfile,
  421.         dofile = dofile,
  422.         pairs = pairs,
  423.         collectgarbage = collectgarbage,
  424.         xpcall = xpcall,
  425.         error = error,
  426.         setfenv = setfenv,
  427.         require = function(name)
  428.                 if package.loaded[name] then
  429.                         return package.loaded[name]
  430.                 end
  431.                 for i, v in ipairs(package.loaders) do
  432.                         local f = v(name)
  433.                         if type(f) == 'function' then
  434.                                 package.loaded[name] = f(name)
  435.                                 if not package.loaded[name] == nil then
  436.                                         package.loaded[name] = true
  437.                                 end
  438.                                 return package.loaded[name]
  439.                         end
  440.                 end
  441.                 error('cannot find module ' .. name)
  442.         end,
  443.         module = function(name, ...)
  444.                 local function do_at(fun, table, name, ...)
  445.                         if select('#', ...) ~= 0 then
  446.                                 return do_at(fun, table[name], ...)
  447.                         else
  448.                                 return fun(table, name)
  449.                         end
  450.                 end
  451.                 local l = split(name, '.')
  452.                 local t
  453.                 if package.loaded[name] then
  454.                         t = package.loaded[name]
  455.                 else
  456.                         t = do_at(function(t, n) return t[n] end, _G, unpack(l))
  457.                         if not t then
  458.                                 package.loaded[name] = t
  459.                                 do_at(function(g, n) g[n] = t end, _G, unpack(l))
  460.                         end
  461.                 end
  462.                 t._NAME = name
  463.                 t._M = t
  464.                 t._PACKAGE = string.sub(name, 1, string.len(name) - string.len(l[#l]) - 1)
  465.                 package.loaded[name] = t
  466.                 setfenv(0, t)
  467.                 for i, v in ipairs({...}) do
  468.                         v(t)
  469.                 end
  470.                 return t
  471.         end,
  472.         getfenv = getfenv,
  473.         rawget = rawget,
  474.         type = type,
  475.         rawset = rawset,
  476.         setmetatable = setmetatable,
  477.         select = select,
  478.         tostring = tostring,
  479.         next = next,
  480.         http = http,
  481.         parallel = {
  482.                 create = function(f, ...)
  483.                         if select('#', ...) ~= 0 then
  484.                                 return coroutine.yield('parallel', f), parallel.create(...)
  485.                         else
  486.                                 return coroutine.yield('parallel', f)
  487.                         end
  488.                 end,
  489.                 waitForAny = function(...)
  490.                         coroutine.yield('wait', 1, parallel.create(...))
  491.                 end,
  492.                 waitForAll = function(...)
  493.                         coroutine.yield('wait', select('#', ...), parallel.create(...))
  494.                 end,
  495.         },
  496.         package = {
  497.                 cpath = '/',
  498.                 loaded = { },
  499.                 loaders = {
  500.                         function(name)
  501.                                 return package.preload[name]
  502.                         end,
  503.                         function(name)
  504.                                 name = string.gusb(string.gsub(name, '%.', '/'), '%%', '%%%%')
  505.                                 local s = split(package.path, ';')
  506.                                 for i, v in ipairs(s) do
  507.                                         local fun = loadfile(string.gsub(s[i], '%?', name))
  508.                                         if fun then
  509.                                                 return fun
  510.                                         end
  511.                                 end
  512.                         end,
  513.                         function(name)
  514.                                 return nil
  515.                         end,
  516.                         function(name)
  517.                                 return nil
  518.                         end,
  519.                 },
  520.                 path = '?;?.lua',
  521.                 preload = { },
  522.                 seeall = function(module)
  523.                         setmetatable(module, { __index = _G })
  524.                 end
  525.         },
  526. }
  527.  
  528. userfun[tenv.os.run] = true
  529. userfun[tenv.require] = true
  530. userfun[tenv.module] = true
  531. userfun[tenv.package.seeall] = true
  532. userfun[tenv.read] = true
  533. userfun[tenv.parallel.create] = true
  534. userfun[tenv.parallel.waitForAny] = true
  535. userfun[tenv.parallel.waitForAll] = true
  536. protectenv(tenv.package.loaders, true)
  537. --assert(userfun[nil] ~= true)
  538. local syscall = { }
  539.  
  540. local function cycle()
  541.         while parallels[1].currentProcess do
  542.                 local running = false
  543.                 for i, v in ipairs(parallels) do
  544.                         currentParallel = v
  545.                         currentProcess = v.currentProcess
  546.                         while currentProcess and processInfo[currentProcess].status == 'dead' do
  547.                                 if listener[currentProcess] then
  548.                                         for i, v in ipairs(listener[currentProcess]) do
  549.                                                 v()
  550.                                         end
  551.                                 end
  552.                                 listener[currentProcess] = nil
  553.                                 currentProcess = processInfo[currentProcess].parent
  554.                         end
  555.                         v.currentProcess = currentProcess
  556.                         if not currentProcess then
  557.                                 if listener[v] then
  558.                                         for i, f in ipairs(listener[v]) do
  559.                                                 f()
  560.                                         end
  561.                                         listener[v] = nil
  562.                                 end
  563.                         elseif processInfo[currentProcess].status ~= 'wait' or processInfo[currentProcess].wait() then
  564.                                 running = true
  565.                                 returnValue = processInfo[currentProcess].returnValue
  566.                                 local ret = rvpack(coroutine.resume(currentProcess, rvunpack(returnValue)))
  567.                                 if not ret[1] then
  568.                                         processInfo[currentProcess].status = 'dead'
  569.                                         ret[1] = 'error'
  570.                                         local p = processInfo[currentProcess].parent
  571.                                         if p then
  572.                                                 processInfo[p].returnValue = ret
  573.                                         else
  574.                                                 print(rvunpack(ret))
  575.                                         end
  576.                                 elseif coroutine.status(currentProcess) == 'dead' then
  577.                                         processInfo[currentProcess].status = 'dead'
  578.                                         ret[1] = true
  579.                                         local p = processInfo[currentProcess].parent
  580.                                         if p then
  581.                                                 processInfo[p].returnValue = ret
  582.                                         end
  583.                                 else
  584.                                         ret[2] = ret[2] or 'pull'
  585.                                         syscall[ret[2]](rvunpack(ret, 3))
  586.                                 end
  587.                         end
  588.                 end
  589.                 if not running then
  590.                         queueEvent(pullEventRaw())
  591.                 end
  592.         end
  593. end
  594.  
  595. local function createProcess(file, argv, envp, eenv)
  596.         envp = envp or duplicate(processInfo[currentProcess].environment)
  597.         argv = argv or { }
  598.         argv[0] = path
  599.         argv.n = argv.n or #argv
  600.         argv.s = argv.s or 1
  601.         local penv = eenv or clone(tenv)
  602.         penv._G = penv
  603.         local co = coroutine.create(setfenv(file, penv))
  604.         debug.setfenv(co, penv)
  605.         debug.sethook(co, flushEvent, '', 2000)
  606.         processInfo[co] = {
  607.                 environment = envp,
  608.                 arguments = argv,
  609.                 parent = currentProcess,
  610.                 parellel = currentParallel,
  611.                 returnValue = argv
  612.         }
  613.         return co
  614. end
  615.  
  616. local function execf(file, argv, envp, eenv)
  617.         local co = createProcess(file, argv, envp, eenv)
  618.         currentParallel.currentProcess = co
  619. end
  620.  
  621. local function exec(path, argv, envp, eenv)
  622.         if type(path) == 'function' then
  623.                 return execf(path, argv, envp, eenv)
  624.         end
  625.         local file, err = loadfile(path)
  626.         if file then
  627.                 return execf(file, argv, envp, eenv)
  628.         end
  629.         processInfo[currentProcess].returnValue = rvpack(false, err)
  630. end
  631.  
  632. local function pull()
  633.         local e = pullEvent()
  634.         local info = processInfo[currentProcess]
  635.         if e then
  636.                 info.returnValue = e
  637.         elseif info.status ~= 'dead' then
  638.                 info.status = 'wait'
  639.                 e = currentParallel.events
  640.                 info.wait = function()
  641.                         if e.next then
  642.                                 info.returnValue = assert(pullEvent())
  643.                                 info.status = 'normal'
  644.                                 return true
  645.                         end
  646.                 end
  647.         end
  648. end
  649.  
  650. local function discard()
  651.         currentParallel.events = events.back
  652. end
  653.  
  654. local function shutdown()
  655.         os.shutdown()
  656.         while true do
  657.                 coroutine.yield()
  658.         end
  659. end
  660.  
  661. local function parallel(func)
  662.         local co = createProcess(func)
  663.         local parallel = {
  664.                 currentProcess = co,
  665.                 events = currentParallel.events
  666.         }
  667.         local info = processInfo[co]
  668.         info.parent = nil
  669.         info.parallel = parallel
  670.         table.insert(parallels, parallel)
  671.         local v = { }
  672.         handles[v] = parallel
  673.         processInfo[currentProcess].returnValue = rvpack(v)
  674. end
  675.  
  676. function wait(n, ...)
  677.         for i, v in ipairs({...}) do
  678.                 if handles[v] then
  679.                         v = handles[v]
  680.                 end
  681.                 if not listener[v] then
  682.                         listener[v] = { }
  683.                 end
  684.                 if processInfo[v] and processInfo[v].status == 'dead' then
  685.                         n = n - 1
  686.                 end
  687.                 if v and v.currentProcess == nil then
  688.                         n = n - 1
  689.                 end
  690.                 table.insert(listener[v], function()
  691.                         n = n - 1
  692.                         if n <= 0 and info.status ~= 'dead' then
  693.                                 info.status = 'normal'
  694.                         end
  695.                 end)
  696.         end
  697.         local info = processInfo[currentProcess]
  698.         info.wait = function() end
  699.         if info.status ~= 'dead' then
  700.                 info.status = 'wait'
  701.         end
  702. end
  703.  
  704. syscall.exec = execf
  705. syscall.pull = pull
  706. syscall.sleep = sleep
  707. syscall.discard = discard
  708. syscall.shutdown = shutdown
  709. syscall.parallel = parallel
  710. syscall.wait = wait
  711.  
  712. local tAPIsLoading = {}
  713. function os.loadAPI( _sPath )
  714.         local sName = fs.getName( _sPath )
  715.         if tAPIsLoading[sName] == true then
  716.                 return false, "API "..sName.." is already being loaded"
  717.         end
  718.         tAPIsLoading[sName] = true
  719.        
  720.         local tEnv = {}
  721.         setmetatable(tEnv, { __index = tenv })
  722.         local fnAPI, err = loadfile( _sPath )
  723.         if fnAPI then
  724.                 setfenv(fnAPI, tEnv)
  725.                 fnAPI()
  726.         else
  727.                 return false, err
  728.         end
  729.        
  730.         --_G[sName] = duplicate(tEnv)
  731.         tenv[sName] = duplicate(tEnv, tenv[sName])
  732.         tAPIsLoading[sName] = nil
  733.         return true
  734. end
  735.  
  736. function os.unloadAPI( _sName )
  737.         if _sName ~= "_G" and type(_G[_sName] == "table") then
  738.                 tenv[sName] = nil
  739.         end
  740. end
  741.  
  742. -- Install the lua parts of the HTTP api (if enabled)
  743. if http then
  744.         http.get = function( _url )
  745.                 local requestID = http.request( _url )
  746.                 while true do
  747.                         local event, param1, param2 = os.pullEvent()
  748.                         if event == "http_success" and param1 == _url then
  749.                                 return param2
  750.                         elseif event == "http_failure" and param1 == _url then
  751.                                 return nil
  752.                         end
  753.                 end
  754.         end
  755. end
  756.  
  757. -- Load APIs
  758. local tApis = fs.list( "rom/apis" )
  759. for n,sFile in ipairs( tApis ) do
  760.         if not fs.isDir( sFile ) and sFile ~= 'parallel' then
  761.                 os.loadAPI( fs.combine( "rom/apis", sFile ) )
  762.         end
  763. end
  764.  
  765. --tenv = clone(tenv)
  766. protectenv(tenv)
  767. currentProcess = createProcess(function()
  768.                 _G.parallel.create(rednet.run)
  769.                 os.run( {}, "rom/programs/shell" )
  770.         end, nil, { })
  771. local parallel = {
  772.         currentProcess = currentProcess,
  773.         events = events
  774. }
  775. local info = processInfo[currentProcess]
  776. info.parent = nil
  777. info.parallel = parallel
  778. table.insert(parallels, parallel)
  779. print(pcall(cycle))
  780. local x = returnValue
  781. print(rvunpack(returnValue))
  782.  
  783.  
  784. --[[
  785. -- Run the shell
  786. local ok, err = pcall( function()
  787.         parallel.waitForAny(
  788.                 function()
  789.                         rednet.run()
  790.                 end,
  791.                 function()
  792.                         os.run( {}, "rom/programs/shell" )
  793.                 end
  794.         )
  795. end )
  796. if not ok then
  797.         print( err )
  798. end
  799. ]]
  800. -- If the shell didn't shutdown the computer,
  801. -- it probably errored, so let the user read it.
  802.  
  803. pcall( function()
  804.         term.setCursorBlink( false )
  805.         print( "Press any key to continue" )
  806.         repeat
  807.                 local event = pullEventRaw()
  808.         until event[1] == "key"
  809. end )
  810. os.shutdown() -- Just in case
clone this paste RAW Paste Data