diff --git a/halyde/core/boot.lua b/halyde/core/boot.lua new file mode 100644 index 0000000..4a06125 --- /dev/null +++ b/halyde/core/boot.lua @@ -0,0 +1,31 @@ +local loadfile = ... +local filesystem = loadfile("/halyde/lib/filesystem.lua")(loadfile) + +_G._OSVERSION = "Halyde 0.1.0" + +function _G.import(module, ...) + local args = table.pack(...) + local modulepath + if module:find("^/") then + if filesystem.exists(module) then + modulepath = module + end + elseif filesystem.exists("/halyde/lib/"..module..".lua") then + modulepath = "/halyde/lib/"..module..".lua" + end + assert(modulepath, "module not found\npossible locations:\n/halyde/lib/"..module..".lua") + local handle = filesystem.open(modulepath) + local data = "" + local tmpdata = "" + repeat + tmpdata = handle:read(math.huge or math.maxinteger) + data = data .. (tmpdata or "") + until not tmpdata + assert(load(data, "="..modulepath))(table.unpack(args)) +end + +--local handle = assert(filesystem.open("/bazinga.txt", "w")) +--assert(handle:write("Bazinga!")) +--handle:close() + +import("/halyde/core/cormgr.lua") \ No newline at end of file diff --git a/halyde/core/cormgr.lua b/halyde/core/cormgr.lua new file mode 100644 index 0000000..7297561 --- /dev/null +++ b/halyde/core/cormgr.lua @@ -0,0 +1,30 @@ +_G.cormgr = {} +_G.cormgr.corList = {} + +function _G.cormgr.loadCoroutine(path) + local cor = coroutine.create(function() + import(path) + end) + table.insert(_G.cormgr.corList, cor) + coroutine.yield() +end + +function handleError(errormsg) + -- nothing for now + assert(false, errormsg) +end + +_G.cormgr.loadCoroutine("/halyde/core/loader.lua") + +while true do + for i = 1, #_G.cormgr.corList do + local result, errormsg = coroutine.resume(_G.cormgr.corList[i]) + if coroutine.status(_G.cormgr.corList[i]) == "dead" then + table.remove(_G.cormgr.corList, i) + if not result then + handleError(errormsg) + end + end + computer.pullSignal(1) + end +end \ No newline at end of file diff --git a/halyde/core/loader.lua b/halyde/core/loader.lua new file mode 100644 index 0000000..3d1fec0 --- /dev/null +++ b/halyde/core/loader.lua @@ -0,0 +1,8 @@ +import("termlib") + +print("wait...") +print("IT WORKS???") +print("abab") +print("abc\ndef") +print("abc\tdef") +print("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") \ No newline at end of file diff --git a/halyde/lib/component.lua b/halyde/lib/component.lua new file mode 100644 index 0000000..5a35e8f --- /dev/null +++ b/halyde/lib/component.lua @@ -0,0 +1,17 @@ +local componentlib = {} + +function componentlib.get(address) + checkArg(1, address, "string") + assert(#address >= 3, "abbreviated address must be at least 3 characters long") + local components = component.list() + for currentAddress, name in pairs(components) do + if currentAddress:find("^" .. address) then + return(currentAddress) + end + end + return nil, "full address not found" +end + +componentlib.invoke = component.invoke + +return(componentlib) \ No newline at end of file diff --git a/halyde/lib/filesystem.lua b/halyde/lib/filesystem.lua new file mode 100644 index 0000000..b4113d2 --- /dev/null +++ b/halyde/lib/filesystem.lua @@ -0,0 +1,69 @@ +local loadfile = ... -- raw loadfile from boot.lua +local component + +if loadfile then + component = loadfile("/halyde/lib/component.lua")(loadfile) +else + component = require("component") +end + +local filesystem = {} + +function filesystem.processPath(path) -- returns the address and absolute path of a filesystem path as well as sanitizing it + checkArg(1, path, "string") + absPath = path:gsub("/+", "/"):gsub("/$", "") + local address = nil + if absPath:find("^/mnt/.../") then + address = component.get(path:sub(6,8)) + if not address then + address = computer.getBootAddress() + else + absPath = absPath:sub(9) + end + else + address = computer.getBootAddress() + end + if not address then + return nil, "no such device" + end + return address, absPath +end + +function filesystem.exists(path) -- check if path exists + checkArg(1, path, "string") + local address, absPath = filesystem.processPath(path) + if not address then + return false + end + return component.invoke(address, "exists", absPath) +end + +function filesystem.open(path, mode) -- opens a file and returns its handle + checkArg(1, path, "string") + checkArg(2, mode, "string", "nil") + if not mode then + mode = "r" + end + if not (mode == "r" or mode == "w" or mode == "rb" or mode == "wb") then + return nil, "invalid handle type" + end + local address, absPath = filesystem.processPath(path) + local handle = component.invoke(address, "open", absPath, mode) + local properHandle = {} + properHandle.handle = handle + properHandle.address = address + function properHandle.read(self, amount) + checkArg(2, amount, "number") + return component.invoke(self.address, "read", self.handle, amount) + end + function properHandle.write(self, data) + checkArg(2, data, "string") + return component.invoke(self.address, "write", self.handle, data) + end + function properHandle.close(self) + return component.invoke(self.address, "close", self.handle) + end + return properHandle +end + +return(filesystem) \ No newline at end of file diff --git a/halyde/lib/termlib.lua b/halyde/lib/termlib.lua new file mode 100644 index 0000000..f7d7c25 --- /dev/null +++ b/halyde/lib/termlib.lua @@ -0,0 +1,25 @@ +local gpu = component.proxy(component.list("gpu")()) -- replace with component.gpu once implemented +local lineNumber = 1 + +function _G.print(text) + local xRes, yRes = gpu.getResolution() + if not text or not tostring(text) then + return + end + local printText = tostring(text):gsub("\t", " ") + for line in printText:gmatch("([^\n]*)\n?") do + while #line > xRes do + gpu.set(1,lineNumber,line:sub(1,xRes)) + line = line:sub(xRes+1) + lineNumber = lineNumber + 1 + end + gpu.set(1,lineNumber,line) + lineNumber = lineNumber + 1 + end +end + +function _G.clear() + local xRes, yRes = gpu.getResolution() + gpu.fill(1,1,xRes,yRes," ") + lineNumber = 1 +end \ No newline at end of file diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..9b0914b --- /dev/null +++ b/init.lua @@ -0,0 +1,46 @@ +local gpu = component.proxy(component.list("gpu")()) +local resx, resy = gpu.getResolution() + +local function loadfile(file) + checkArg(1, file, "string") + local handle = component.invoke(computer.getBootAddress(), "open", file, "r") + local data = "" + repeat + local tmpdata = component.invoke(computer.getBootAddress(), "read", handle, math.huge or math.maxinteger) + data = data .. (tmpdata or "") + until not tmpdata + component.invoke(computer.getBootAddress(), "close", handle) + return(assert(load(data, "=" .. file))) +end + +local function handleError(errorMessage) + return(errorMessage.."\n \n"..debug.traceback()) +end + +function loadthething() + loadfile("/halyde/core/boot.lua")(loadfile) +end + +while true do + gpu.setBackground(0x000000) + gpu.fill(1, 1, resx, resy, " ") + local result, reason = xpcall(loadthething, handleError) + if not result then + gpu.setBackground(0x000000) + gpu.fill(1, 1, resx, resy, " ") + gpu.setBackground(0x800000) + gpu.setForeground(0xFFFFFF) + gpu.set(2,2,"A critical error has occurred.") + local i = 4 + reason = reason:gsub("\t", " ") + for line in string.gmatch((reason ~= nil and tostring(reason)) or "unknown error", "([^\n]*)\n?") do + gpu.set(2,i,line) + i = i + 1 + end + gpu.set(2,i+1, "Press any key to restart.") + local evname = "" + repeat + evname = computer.pullSignal() + until evname == "key_down" + end +end \ No newline at end of file