Advertisement
zhykzhykzhyk

CCOS 0.2 for ComputerCraft

Jan 19th, 2012
748
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 18.08 KB | None | 0 0
  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
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement