Files
HyperionOS/Src/Hyperion-bash/bin/lua
2026-02-16 20:37:13 -05:00

149 lines
5.4 KiB
Plaintext

syscall.devctl(1,"sfgc",7)
print("HyperionOS Lua prompt.")
print("Call exit() to exit.")
local commandHistory = {}
local luaEnv=setmetatable({
["exit"] = setmetatable({}, {
__tostring = function() return "Call exit() to exit." end,
__call = function() syscall.exit() end,
}),
["_echo"] = function(...)
return ...
end,
},{__index=_ENV})
local function getUserInput()
syscall.devctl(1,"sfgc",1)
printInline("lua> ")
local curOffsetStr = syscall.devctl(1, "gpos")
local curOffsetX = tonumber(curOffsetStr:sub(1, curOffsetStr:find(";")-1))
local curOffsetY = tonumber(curOffsetStr:sub(curOffsetStr:find(";")+1))
local input = ""
local blinkState = false
local cursorPos = 1
local history = 0
while true do
local key=syscall.read(0)
if key then
if key == "\19" then --TODO: REPLACE WITH LEFT ARROW
if cursorPos > 1 then
cursorPos = cursorPos - 1
end
elseif key == "\20" then --TODO: REPLACE WITH RIGHT ARROW
if cursorPos <= #input then
cursorPos = cursorPos + 1
end
elseif key == "\17" then --TODO: REPLACE WITH UP ARROW
if history < #commandHistory then
syscall.devctl(1,"spos",curOffsetX,curOffsetY)
printInline((" "):rep(#input + 1))
history = history + 1
input = commandHistory[#commandHistory - history + 1]
cursorPos = #input + 1
end
elseif key == "\18" then --TODO: REPLACE WITH DOWN ARROW
if history > 1 then
syscall.devctl(1,"spos",curOffsetX,curOffsetY)
printInline((" "):rep(#input + 1))
history = history - 1
input = commandHistory[#commandHistory - history + 1]
cursorPos = #input + 1
elseif history == 1 then
syscall.devctl(1,"spos",curOffsetX,curOffsetY)
printInline((" "):rep(#input + 1))
history = 0
input = ""
cursorPos = 1
end
elseif key == "\b" then
if cursorPos > 1 then
syscall.devctl(1,"spos",curOffsetX,curOffsetY)
printInline((" "):rep(#input + 1))
input = string.sub(input, 1, cursorPos-2)..string.sub(input, cursorPos)
cursorPos = cursorPos - 1
end
elseif key == "\n" then
syscall.devctl(1,"spos",curOffsetX,curOffsetY)
print(input.." ")
return input
else
input = string.sub(input, 1, cursorPos-1)..key..string.sub(input, cursorPos)
cursorPos = cursorPos + 1
end
local screenSizeStr = syscall.devctl(1, "size")
local sizeX = tonumber(screenSizeStr:sub(1, screenSizeStr:find(";")-1))
local sizeY = tonumber(screenSizeStr:sub(screenSizeStr:find(";")+1))
local totalChars = sizeX * sizeY
local eocCharNum = ((curOffsetY - 1) * sizeX) + curOffsetX + #input
if eocCharNum >= totalChars then
syscall.devctl(1,"spos",sizeX,sizeY)
printInline(" ")
curOffsetY = curOffsetY - 1
end
end
syscall.devctl(1,"spos",curOffsetX,curOffsetY)
printInline(string.sub(input, 1, cursorPos-1))
if blinkState then
syscall.devctl(1,"sfgc",16)
syscall.devctl(1,"sbgc",1)
end
if cursorPos > #input then
printInline(" ")
else
printInline(string.sub(input, cursorPos, cursorPos))
end
syscall.devctl(1,"sfgc",1)
syscall.devctl(1,"sbgc",16)
printInline(string.sub(input, cursorPos+1))
if cursorPos <= #input then
printInline(" ")
end
local curBlink = ((math.floor(syscall.getUptime() / 500) % 2) == 0)
if curBlink ~= blinkState then
blinkState = curBlink
end
end
end
local function runCode(code)
local func, err = load(code, "@lua", "t", luaEnv)
local isReturn = false
if load("return "..code) then
func, err = load("return _echo("..code.."\n)", "@lua", "t", luaEnv)
isReturn = true
end
if not func then
local errSL = string.sub(err, string.find(err, ":") + 1)
syscall.devctl(1,"sfgc",2)
printInline("@lua: Load error on line ")
print(string.sub(errSL, 1, string.find(errSL, ":") - 1))
syscall.devctl(1,"sfgc",1)
print(string.sub(errSL, string.find(errSL, ":") + 1))
return
end
local success, msg = xpcall(func, debug.traceback)
if not success then
local errSL = string.sub(msg, string.find(msg, ":") + 1)
syscall.devctl(1,"sfgc",2)
printInline("@lua: Runtime error on line ")
print(string.sub(errSL, 1, string.find(errSL, ":") - 1))
syscall.devctl(1,"sfgc",1)
print(string.sub(errSL, string.find(errSL, ":") + 1))
elseif isReturn then
print(tostring(msg))
end
end
while true do
local code = getUserInput()
if code ~= "" then
if code ~= commandHistory[#commandHistory] then
table.insert(commandHistory, code)
end
runCode(code)
end
end