added moonscript package
This commit is contained in:
@@ -1,142 +0,0 @@
|
|||||||
-- see: https://github.com/Rochet2/lualzw
|
|
||||||
-- MIT License - Copyright (c) 2016 Rochet2
|
|
||||||
|
|
||||||
local char = string.char
|
|
||||||
local type = type
|
|
||||||
local sub = string.sub
|
|
||||||
local tconcat = table.concat
|
|
||||||
|
|
||||||
local SIGC = 'LZWC'
|
|
||||||
|
|
||||||
local basedictcompress = {}
|
|
||||||
local basedictdecompress = {}
|
|
||||||
for i = 0, 255 do
|
|
||||||
local ic, iic = char(i), char(i, 0)
|
|
||||||
basedictcompress[ic] = iic
|
|
||||||
basedictdecompress[iic] = ic
|
|
||||||
end
|
|
||||||
|
|
||||||
local function dictAddA(str, dict, a, b)
|
|
||||||
if a >= 256 then
|
|
||||||
a, b = 0, b+1
|
|
||||||
if b >= 256 then
|
|
||||||
dict = {}
|
|
||||||
b = 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
dict[str] = char(a,b)
|
|
||||||
a = a+1
|
|
||||||
return dict, a, b
|
|
||||||
end
|
|
||||||
|
|
||||||
local function compress(input)
|
|
||||||
if type(input) ~= "string" then
|
|
||||||
error ("string expected, got "..type(input))
|
|
||||||
end
|
|
||||||
local len = #input
|
|
||||||
if len <= 1 then
|
|
||||||
return input
|
|
||||||
end
|
|
||||||
|
|
||||||
local dict = {}
|
|
||||||
local a, b = 0, 1
|
|
||||||
|
|
||||||
local result = { SIGC }
|
|
||||||
local resultlen = 1
|
|
||||||
local n = 2
|
|
||||||
local word = ""
|
|
||||||
for i = 1, len do
|
|
||||||
local c = sub(input, i, i)
|
|
||||||
local wc = word..c
|
|
||||||
if not (basedictcompress[wc] or dict[wc]) then
|
|
||||||
local write = basedictcompress[word] or dict[word]
|
|
||||||
if not write then
|
|
||||||
error "algorithm error, could not fetch word"
|
|
||||||
end
|
|
||||||
result[n] = write
|
|
||||||
resultlen = resultlen + #write
|
|
||||||
n = n+1
|
|
||||||
if len <= resultlen then
|
|
||||||
return input
|
|
||||||
end
|
|
||||||
dict, a, b = dictAddA(wc, dict, a, b)
|
|
||||||
word = c
|
|
||||||
else
|
|
||||||
word = wc
|
|
||||||
end
|
|
||||||
end
|
|
||||||
result[n] = basedictcompress[word] or dict[word]
|
|
||||||
resultlen = resultlen+#result[n]
|
|
||||||
if len <= resultlen then
|
|
||||||
return input
|
|
||||||
end
|
|
||||||
return tconcat(result)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function dictAddB(str, dict, a, b)
|
|
||||||
if a >= 256 then
|
|
||||||
a, b = 0, b+1
|
|
||||||
if b >= 256 then
|
|
||||||
dict = {}
|
|
||||||
b = 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
dict[char(a,b)] = str
|
|
||||||
a = a+1
|
|
||||||
return dict, a, b
|
|
||||||
end
|
|
||||||
|
|
||||||
local function decompress(input)
|
|
||||||
if type(input) ~= "string" then
|
|
||||||
error( "string expected, got "..type(input))
|
|
||||||
end
|
|
||||||
|
|
||||||
if #input <= 1 then
|
|
||||||
return input
|
|
||||||
end
|
|
||||||
|
|
||||||
local control = sub(input, 1, 4)
|
|
||||||
if control ~= SIGC then
|
|
||||||
return input
|
|
||||||
end
|
|
||||||
input = sub(input, 5)
|
|
||||||
local len = #input
|
|
||||||
|
|
||||||
if len < 2 then
|
|
||||||
error("invalid input - not a compressed string")
|
|
||||||
end
|
|
||||||
|
|
||||||
local dict = {}
|
|
||||||
local a, b = 0, 1
|
|
||||||
|
|
||||||
local result = {}
|
|
||||||
local n = 1
|
|
||||||
local last = sub(input, 1, 2)
|
|
||||||
result[n] = basedictdecompress[last] or dict[last]
|
|
||||||
n = n+1
|
|
||||||
for i = 3, len, 2 do
|
|
||||||
local code = sub(input, i, i+1)
|
|
||||||
local lastStr = basedictdecompress[last] or dict[last]
|
|
||||||
if not lastStr then
|
|
||||||
error( "could not find last from dict. Invalid input?")
|
|
||||||
end
|
|
||||||
local toAdd = basedictdecompress[code] or dict[code]
|
|
||||||
if toAdd then
|
|
||||||
result[n] = toAdd
|
|
||||||
n = n+1
|
|
||||||
dict, a, b = dictAddB(lastStr..sub(toAdd, 1, 1), dict, a, b)
|
|
||||||
else
|
|
||||||
local tmp = lastStr..sub(lastStr, 1, 1)
|
|
||||||
result[n] = tmp
|
|
||||||
n = n+1
|
|
||||||
dict, a, b = dictAddB(tmp, dict, a, b)
|
|
||||||
end
|
|
||||||
last = code
|
|
||||||
end
|
|
||||||
return tconcat(result)
|
|
||||||
end
|
|
||||||
|
|
||||||
return {
|
|
||||||
compress = compress,
|
|
||||||
decompress = decompress,
|
|
||||||
}
|
|
||||||
@@ -1,212 +0,0 @@
|
|||||||
|
|
||||||
-- see: https://github.com/luarocks/luarocks/blob/master/src/luarocks/tools/tar.lua
|
|
||||||
-- A pure-Lua implementation of untar (unpacking .tar archives)
|
|
||||||
local Util = require('opus.util')
|
|
||||||
|
|
||||||
local fs = _G.fs
|
|
||||||
|
|
||||||
local blocksize = 512
|
|
||||||
|
|
||||||
local function get_typeflag(flag)
|
|
||||||
if flag == "0" or flag == "\0" then return "file"
|
|
||||||
elseif flag == "1" then return "link"
|
|
||||||
elseif flag == "2" then return "symlink" -- "reserved" in POSIX, "symlink" in GNU
|
|
||||||
elseif flag == "3" then return "character"
|
|
||||||
elseif flag == "4" then return "block"
|
|
||||||
elseif flag == "5" then return "directory"
|
|
||||||
elseif flag == "6" then return "fifo"
|
|
||||||
elseif flag == "7" then return "contiguous" -- "reserved" in POSIX, "contiguous" in GNU
|
|
||||||
elseif flag == "x" then return "next file"
|
|
||||||
elseif flag == "g" then return "global extended header"
|
|
||||||
elseif flag == "L" then return "long name"
|
|
||||||
elseif flag == "K" then return "long link name"
|
|
||||||
end
|
|
||||||
return "unknown"
|
|
||||||
end
|
|
||||||
|
|
||||||
local function octal_to_number(octal)
|
|
||||||
local exp = 0
|
|
||||||
local number = 0
|
|
||||||
octal = octal:gsub("%s", "")
|
|
||||||
for i = #octal,1,-1 do
|
|
||||||
local digit = tonumber(octal:sub(i,i))
|
|
||||||
if not digit then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
number = number + (digit * 8^exp)
|
|
||||||
exp = exp + 1
|
|
||||||
end
|
|
||||||
return number
|
|
||||||
end
|
|
||||||
|
|
||||||
local function checksum_header(block)
|
|
||||||
local sum = 256
|
|
||||||
for i = 1,148 do
|
|
||||||
local b = block:byte(i) or 0
|
|
||||||
sum = sum + b
|
|
||||||
end
|
|
||||||
for i = 157,500 do
|
|
||||||
local b = block:byte(i) or 0
|
|
||||||
sum = sum + b
|
|
||||||
end
|
|
||||||
return sum
|
|
||||||
end
|
|
||||||
|
|
||||||
local function nullterm(s)
|
|
||||||
return s:match("^[^%z]*")
|
|
||||||
end
|
|
||||||
|
|
||||||
local function read_header_block(block)
|
|
||||||
local header = {}
|
|
||||||
header.name = nullterm(block:sub(1,100))
|
|
||||||
header.mode = nullterm(block:sub(101,108)):gsub(" ", "")
|
|
||||||
header.uid = octal_to_number(nullterm(block:sub(109,116)))
|
|
||||||
header.gid = octal_to_number(nullterm(block:sub(117,124)))
|
|
||||||
header.size = octal_to_number(nullterm(block:sub(125,136)))
|
|
||||||
header.mtime = octal_to_number(nullterm(block:sub(137,148)))
|
|
||||||
header.chksum = octal_to_number(nullterm(block:sub(149,156)))
|
|
||||||
header.typeflag = get_typeflag(block:sub(157,157))
|
|
||||||
header.linkname = nullterm(block:sub(158,257))
|
|
||||||
header.magic = block:sub(258,263)
|
|
||||||
header.version = block:sub(264,265)
|
|
||||||
header.uname = nullterm(block:sub(266,297))
|
|
||||||
header.gname = nullterm(block:sub(298,329))
|
|
||||||
header.devmajor = octal_to_number(nullterm(block:sub(330,337)))
|
|
||||||
header.devminor = octal_to_number(nullterm(block:sub(338,345)))
|
|
||||||
header.prefix = block:sub(346,500)
|
|
||||||
if not checksum_header(block) == header.chksum then
|
|
||||||
return false, "Failed header checksum"
|
|
||||||
end
|
|
||||||
return header
|
|
||||||
end
|
|
||||||
|
|
||||||
local function untar(filename, destdir, verbose)
|
|
||||||
assert(type(filename) == "string")
|
|
||||||
assert(type(destdir) == "string")
|
|
||||||
|
|
||||||
local tar_handle = io.open(filename, "rb")
|
|
||||||
if not tar_handle then return nil, "Error opening file "..filename end
|
|
||||||
|
|
||||||
local long_name, long_link_name
|
|
||||||
local ok, err
|
|
||||||
|
|
||||||
local make_dir = function(a)
|
|
||||||
if not fs.exists(a) then
|
|
||||||
fs.makeDir(a)
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
while true do
|
|
||||||
local block
|
|
||||||
repeat
|
|
||||||
block = tar_handle:read(blocksize)
|
|
||||||
until (not block) or checksum_header(block) > 256
|
|
||||||
if not block then break end
|
|
||||||
if #block < blocksize then
|
|
||||||
ok, err = nil, "Invalid block size -- corrupted file?"
|
|
||||||
break
|
|
||||||
end
|
|
||||||
local header
|
|
||||||
header, err = read_header_block(block)
|
|
||||||
if not header then
|
|
||||||
ok = false
|
|
||||||
break
|
|
||||||
end
|
|
||||||
|
|
||||||
local file_data = tar_handle:read(math.ceil(header.size / blocksize) * blocksize):sub(1,header.size)
|
|
||||||
|
|
||||||
if header.typeflag == "long name" then
|
|
||||||
long_name = nullterm(file_data)
|
|
||||||
elseif header.typeflag == "long link name" then
|
|
||||||
long_link_name = nullterm(file_data)
|
|
||||||
else
|
|
||||||
if long_name then
|
|
||||||
header.name = long_name
|
|
||||||
long_name = nil
|
|
||||||
end
|
|
||||||
if long_link_name then
|
|
||||||
header.name = long_link_name
|
|
||||||
long_link_name = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local pathname = fs.combine(destdir, header.name)
|
|
||||||
|
|
||||||
if header.typeflag == "directory" then
|
|
||||||
ok, err = make_dir(pathname)
|
|
||||||
if not ok then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
elseif header.typeflag == "file" then
|
|
||||||
local dirname = fs.getDir(pathname)
|
|
||||||
if dirname ~= "" then
|
|
||||||
ok, err = make_dir(dirname)
|
|
||||||
if not ok then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local file_handle
|
|
||||||
if verbose then
|
|
||||||
print(pathname)
|
|
||||||
end
|
|
||||||
file_handle, err = io.open(pathname, "wb")
|
|
||||||
if not file_handle then
|
|
||||||
ok = nil
|
|
||||||
break
|
|
||||||
end
|
|
||||||
file_handle:write(file_data)
|
|
||||||
file_handle:close()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
tar_handle:close()
|
|
||||||
return ok, err
|
|
||||||
end
|
|
||||||
|
|
||||||
local function create_header_block(filename, abspath)
|
|
||||||
local block = ('\0'):rep(blocksize)
|
|
||||||
|
|
||||||
local function number_to_octal(n)
|
|
||||||
return ('%o'):format(n)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function ins(pos, istr)
|
|
||||||
block = block:sub(1, pos - 1) .. istr .. block:sub(pos + #istr)
|
|
||||||
end
|
|
||||||
|
|
||||||
ins(1, filename) -- header
|
|
||||||
ins(125, number_to_octal(fs.getSize(abspath)))
|
|
||||||
ins(157, '0') -- typeflag
|
|
||||||
|
|
||||||
ins(149, number_to_octal(checksum_header(block)))
|
|
||||||
|
|
||||||
return block
|
|
||||||
end
|
|
||||||
|
|
||||||
-- the bare minimum for this program to untar
|
|
||||||
local function tar(filename, root, files)
|
|
||||||
assert(type(filename) == "string")
|
|
||||||
assert(type(root) == "string")
|
|
||||||
assert(type(files) == "table")
|
|
||||||
|
|
||||||
local tar_handle = io.open(filename, "wb")
|
|
||||||
if not tar_handle then return nil, "Error opening file "..filename end
|
|
||||||
|
|
||||||
for _, file in pairs(files) do
|
|
||||||
local abs = fs.combine(root, file)
|
|
||||||
local block = create_header_block(file, abs)
|
|
||||||
tar_handle:write(block)
|
|
||||||
local f = Util.readFile(abs, 'rb')
|
|
||||||
tar_handle:write(f)
|
|
||||||
local padding = #f % blocksize
|
|
||||||
if padding > 0 then
|
|
||||||
tar_handle:write(('\0'):rep(blocksize - padding))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
tar_handle:close()
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
return {
|
|
||||||
tar = tar,
|
|
||||||
untar = untar,
|
|
||||||
}
|
|
||||||
@@ -1,14 +1,10 @@
|
|||||||
local LZW = require('compress.lzw')
|
local LZW = require('opus.compress.lzw')
|
||||||
local Tar = require('compress.tar')
|
local Tar = require('opus.compress.tar')
|
||||||
local Util = require('opus.util')
|
local Util = require('opus.util')
|
||||||
|
|
||||||
local fs = _G.fs
|
|
||||||
local shell = _ENV.shell
|
local shell = _ENV.shell
|
||||||
|
|
||||||
local TMP_FILE = '.out.tar'
|
|
||||||
|
|
||||||
local args = { ... }
|
local args = { ... }
|
||||||
local files = { }
|
|
||||||
|
|
||||||
if not args[2] then
|
if not args[2] then
|
||||||
error('Syntax: tar OUTFILE DIR')
|
error('Syntax: tar OUTFILE DIR')
|
||||||
@@ -24,30 +20,10 @@ elseif file:match('(.+)%.lzw$') then
|
|||||||
filetype = 'lzw'
|
filetype = 'lzw'
|
||||||
end
|
end
|
||||||
|
|
||||||
local function recurse(rel)
|
|
||||||
local abs = fs.combine(dir, rel)
|
|
||||||
for _,f in ipairs(fs.list(abs)) do
|
|
||||||
local fullName = fs.combine(abs, f)
|
|
||||||
if fs.native.isDir(fullName) then -- skip virtual dirs
|
|
||||||
recurse(fs.combine(rel, f))
|
|
||||||
else
|
|
||||||
table.insert(files, fs.combine(rel, f))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
recurse('')
|
|
||||||
|
|
||||||
if filetype == 'tar' then
|
if filetype == 'tar' then
|
||||||
Tar.tar(file, dir, files)
|
Tar.tar(file, dir)
|
||||||
|
|
||||||
elseif filetype == 'lzw' then
|
elseif filetype == 'lzw' then
|
||||||
fs.mount(TMP_FILE, 'ramfs', 'file')
|
local c = Tar.tar_string(dir)
|
||||||
Tar.tar(TMP_FILE, dir, files)
|
Util.writeFile(file, LZW.compress(c), 'wb')
|
||||||
|
|
||||||
local c = Util.readFile(TMP_FILE)
|
|
||||||
fs.delete(TMP_FILE)
|
|
||||||
|
|
||||||
c = LZW.compress(c)
|
|
||||||
Util.writeFile(file, c)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
local DEFLATE = require('compress.deflatelua')
|
local DEFLATE = require('compress.deflatelua')
|
||||||
local LZW = require('compress.lzw')
|
local LZW = require('opus.compress.lzw')
|
||||||
local Tar = require('compress.tar')
|
local Tar = require('opus.compress.tar')
|
||||||
local Util = require('opus.util')
|
local Util = require('opus.util')
|
||||||
|
|
||||||
local fs = _G.fs
|
|
||||||
local io = _G.io
|
local io = _G.io
|
||||||
local shell = _ENV.shell
|
local shell = _ENV.shell
|
||||||
|
|
||||||
local TMP_FILE = '.out.tar'
|
|
||||||
|
|
||||||
local args = { ... }
|
local args = { ... }
|
||||||
|
|
||||||
if not args[2] then
|
if not args[2] then
|
||||||
@@ -18,49 +15,40 @@ end
|
|||||||
local inFile = shell.resolve(args[1])
|
local inFile = shell.resolve(args[1])
|
||||||
local outDir = shell.resolve(args[2])
|
local outDir = shell.resolve(args[2])
|
||||||
|
|
||||||
local s, m = pcall(function()
|
if inFile:match('(.+)%.[gG][zZ]$') then
|
||||||
if inFile:match('(.+)%.[gG][zZ]$') then
|
-- uncompress a file created with: tar czf ...
|
||||||
local fh = io.open(inFile, 'rb') or error('Error opening ' .. inFile)
|
local fh = io.open(inFile, 'rb') or error('Error opening ' .. inFile)
|
||||||
|
|
||||||
fs.mount(TMP_FILE, 'ramfs', 'file')
|
local t = { }
|
||||||
local ofh = io.open(TMP_FILE, 'wb')
|
local function writer(b)
|
||||||
|
table.insert(t, b)
|
||||||
|
end
|
||||||
|
|
||||||
DEFLATE.gunzip {input=fh, output=ofh, disable_crc=true}
|
DEFLATE.gunzip {input=fh, output=writer, disable_crc=true}
|
||||||
|
|
||||||
fh:close()
|
fh:close()
|
||||||
ofh:close()
|
|
||||||
|
|
||||||
local s, m = Tar.untar(TMP_FILE, outDir, true)
|
local s, m = Tar.untar_string(string.char(table.unpack(t)), outDir, true)
|
||||||
|
|
||||||
if not s then
|
if not s then
|
||||||
error(m)
|
error(m)
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif inFile:match('(.+)%.lzw$') then
|
elseif inFile:match('(.+)%.tar%.lzw$') then
|
||||||
local c = Util.readFile(inFile)
|
local c = Util.readFile(inFile, 'rb')
|
||||||
if not c then
|
if not c then
|
||||||
error('Unable to open ' .. inFile)
|
error('Unable to open ' .. inFile)
|
||||||
end
|
end
|
||||||
|
|
||||||
fs.mount(TMP_FILE, 'ramfs', 'file')
|
local s, m = Tar.untar_string(LZW.decompress(c), outDir, true)
|
||||||
Util.writeFile(TMP_FILE, LZW.decompress(c))
|
|
||||||
|
|
||||||
local s, m = Tar.untar(TMP_FILE, outDir, true)
|
|
||||||
|
|
||||||
if not s then
|
if not s then
|
||||||
error(m)
|
error(m)
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
local s, m = Tar.untar(inFile, outDir)
|
local s, m = Tar.untar(inFile, outDir, true)
|
||||||
if not s then
|
if not s then
|
||||||
error(m)
|
error(m)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
fs.delete(TMP_FILE)
|
|
||||||
|
|
||||||
if not s then
|
|
||||||
error(m)
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -9,33 +9,12 @@ local dbg = {
|
|||||||
breakpoints = nil,
|
breakpoints = nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
local romFiles = {
|
|
||||||
load = function(self)
|
|
||||||
local function recurse(dir)
|
|
||||||
local files = fs.list(dir)
|
|
||||||
for _,f in ipairs(files) do
|
|
||||||
local fullName = fs.combine(dir, f)
|
|
||||||
if fs.isDir(fullName) then
|
|
||||||
recurse(fullName)
|
|
||||||
else
|
|
||||||
self.files[f] = fullName
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
recurse('rom/apis')
|
|
||||||
end,
|
|
||||||
get = function(self, file)
|
|
||||||
return self.files[file]
|
|
||||||
end,
|
|
||||||
files = { },
|
|
||||||
}
|
|
||||||
romFiles:load()
|
|
||||||
|
|
||||||
local function breakpointHook(info)
|
local function breakpointHook(info)
|
||||||
if dbg.breakpoints then
|
if dbg.breakpoints then
|
||||||
local src = romFiles:get(info.short_src) or info.short_src
|
local src = info.short_src
|
||||||
for _,v in pairs(dbg.breakpoints) do
|
for _,v in pairs(dbg.breakpoints) do
|
||||||
if v.line == info.currentline and v.file == src then
|
if v.line == info.currentline
|
||||||
|
and (v.file == src or v.bfile == src) then
|
||||||
return not v.disabled
|
return not v.disabled
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ local function startClient()
|
|||||||
os.sleep(0) -- not sure why, but we need a sleep before :resume
|
os.sleep(0) -- not sure why, but we need a sleep before :resume
|
||||||
-- directly resuming debugger routine to prevent
|
-- directly resuming debugger routine to prevent
|
||||||
-- serialization of the snapshot
|
-- serialization of the snapshot
|
||||||
dbg.debugger:resume('debuggerX', dbg.debugger.uid, snapshot)
|
dbg.debugger:resume('debuggerX', 'break', snapshot)
|
||||||
local e, cmd, param
|
local e, cmd, param
|
||||||
repeat
|
repeat
|
||||||
e, cmd, param = os.pullEvent('debugger')
|
e, cmd, param = os.pullEvent('debugger')
|
||||||
@@ -65,15 +65,27 @@ local function startClient()
|
|||||||
dbg.debugger = debugger
|
dbg.debugger = debugger
|
||||||
dbg.stopIn(fn)
|
dbg.stopIn(fn)
|
||||||
local s, m = dbg.call(fn, table.unpack(args))
|
local s, m = dbg.call(fn, table.unpack(args))
|
||||||
|
|
||||||
|
dbg.debugger:resume('debuggerX', 'disconnect')
|
||||||
|
|
||||||
if not s then
|
if not s then
|
||||||
error(m, -1)
|
error(m, -1)
|
||||||
end
|
end
|
||||||
|
print('Process ended normally')
|
||||||
|
print('Press enter to exit')
|
||||||
|
while true do
|
||||||
|
local e, code = os.pullEventRaw('key')
|
||||||
|
if e == 'terminate' or e == 'key' and code == _G.keys.enter then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
client = kernel.find(clientId)
|
client = kernel.find(clientId)
|
||||||
end
|
end
|
||||||
|
|
||||||
local romFiles = {
|
local romFiles = {
|
||||||
|
files = { },
|
||||||
load = function(self)
|
load = function(self)
|
||||||
local function recurse(dir)
|
local function recurse(dir)
|
||||||
local files = fs.list(dir)
|
local files = fs.list(dir)
|
||||||
@@ -87,11 +99,14 @@ local romFiles = {
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
recurse('rom/apis')
|
recurse('rom/apis')
|
||||||
|
self.reversed = Util.transpose(self.files)
|
||||||
end,
|
end,
|
||||||
get = function(self, file)
|
get = function(self, file)
|
||||||
return self.files[file]
|
return self.files[file]
|
||||||
end,
|
end,
|
||||||
files = { },
|
lookup = function(self, file)
|
||||||
|
return self.reversed[file]
|
||||||
|
end,
|
||||||
}
|
}
|
||||||
romFiles:load()
|
romFiles:load()
|
||||||
|
|
||||||
@@ -137,7 +152,7 @@ local page = UI.Page {
|
|||||||
disableHeader = true,
|
disableHeader = true,
|
||||||
unfocusedBackgroundSelectedColor = 'black',
|
unfocusedBackgroundSelectedColor = 'black',
|
||||||
columns = {
|
columns = {
|
||||||
{ heading = 'Key', key = 'name' },
|
{ heading = 'localname', key = 'name' },
|
||||||
{ heading = 'Value', key = 'value', textColor = 'yellow' },
|
{ heading = 'Value', key = 'value', textColor = 'yellow' },
|
||||||
},
|
},
|
||||||
autospace = true,
|
autospace = true,
|
||||||
@@ -214,6 +229,13 @@ local page = UI.Page {
|
|||||||
{ heading = 'Name', key = 'short' },
|
{ heading = 'Name', key = 'short' },
|
||||||
{ heading = 'Path', key = 'path', textColor = 'lightGray' },
|
{ heading = 'Path', key = 'path', textColor = 'lightGray' },
|
||||||
},
|
},
|
||||||
|
getDisplayValues = function(_, row)
|
||||||
|
return {
|
||||||
|
line = row.line,
|
||||||
|
short = fs.getName(row.file),
|
||||||
|
path = fs.getDir(row.file),
|
||||||
|
}
|
||||||
|
end,
|
||||||
getRowTextColor = function(self, row, selected)
|
getRowTextColor = function(self, row, selected)
|
||||||
return row.disabled and 'lightGray'
|
return row.disabled and 'lightGray'
|
||||||
or UI.Grid.getRowTextColor(self, row, selected)
|
or UI.Grid.getRowTextColor(self, row, selected)
|
||||||
@@ -438,8 +460,7 @@ local page = UI.Page {
|
|||||||
table.insert(breakpoints, {
|
table.insert(breakpoints, {
|
||||||
file = event.file,
|
file = event.file,
|
||||||
line = event.line,
|
line = event.line,
|
||||||
short = fs.getName(event.file),
|
bfile = romFiles:lookup(event.file),
|
||||||
path = fs.getDir(event.file),
|
|
||||||
})
|
})
|
||||||
|
|
||||||
self:emit({ type = 'update_breakpoints' })
|
self:emit({ type = 'update_breakpoints' })
|
||||||
@@ -487,8 +508,12 @@ local page = UI.Page {
|
|||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
Event.on('debuggerX', function(_, uid, data)
|
Event.on('debuggerX', function(_, cmd, data)
|
||||||
if uid == debugger.uid then
|
if cmd == 'disconnect' then
|
||||||
|
page.statusBar:setStatus('Finished')
|
||||||
|
page:sync()
|
||||||
|
|
||||||
|
elseif cmd == 'break' then
|
||||||
kernel.raise(debugger.uid)
|
kernel.raise(debugger.uid)
|
||||||
|
|
||||||
-- local tab
|
-- local tab
|
||||||
|
|||||||
9
lpeg/.package
Normal file
9
lpeg/.package
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
title = 'LPeg',
|
||||||
|
repository = 'kepler155c/opus-apps/{{OPUS_BRANCH}}/lpeg',
|
||||||
|
description = [[A pure Lua port of LPeg, Roberto Ierusalimschy's Parsing Expression Grammars library.
|
||||||
|
|
||||||
|
This version of LuLPeg emulates LPeg v0.12.
|
||||||
|
see: https://github.com/pygy/LuLPeg/]],
|
||||||
|
license = 'MIT',
|
||||||
|
}
|
||||||
1
lpeg/etc/fstab
Normal file
1
lpeg/etc/fstab
Normal file
@@ -0,0 +1 @@
|
|||||||
|
rom/modules/main/lpeg.lua urlfs https://raw.githubusercontent.com/pygy/LuLPeg/master/lulpeg.lua
|
||||||
11
moonscript/.package
Normal file
11
moonscript/.package
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
title = 'moonscript',
|
||||||
|
repository = 'kepler155c/opus-apps/{{OPUS_BRANCH}}/moonscript',
|
||||||
|
description = [[MoonScript is a programmer friendly language that compiles into Lua. It gives you the power of the fastest scripting language combined with a rich set of features. It runs on Lua 5.1 and above, including alternative runtimes like LuaJIT.
|
||||||
|
|
||||||
|
See https://moonscript.org.]],
|
||||||
|
license = 'MIT',
|
||||||
|
required = {
|
||||||
|
'lpeg',
|
||||||
|
},
|
||||||
|
}
|
||||||
5
moonscript/README.txt
Normal file
5
moonscript/README.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
running the compiler works fine...
|
||||||
|
moonc T.moon <-- OK
|
||||||
|
|
||||||
|
working on getting the moon command to work properly
|
||||||
|
moon T.moon <-- NOPE
|
||||||
97
moonscript/T.lua
Normal file
97
moonscript/T.lua
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
local Event = require('opus.event')
|
||||||
|
local UI = require('opus.ui')
|
||||||
|
local kernel = _G.kernel
|
||||||
|
local multishell = _ENV.multishell
|
||||||
|
local tasks = multishell and multishell.getTabs and multishell.getTabs() or kernel.routines
|
||||||
|
UI:configure('Tasks', ...)
|
||||||
|
local page = UI.Page({
|
||||||
|
menuBar = UI.MenuBar({
|
||||||
|
buttons = {
|
||||||
|
{
|
||||||
|
text = 'Activate',
|
||||||
|
event = 'activate'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text = 'Terminate',
|
||||||
|
event = 'terminate'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text = 'Inspect',
|
||||||
|
event = 'inspect'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
grid = UI.ScrollingGrid({
|
||||||
|
y = 2,
|
||||||
|
columns = {
|
||||||
|
{
|
||||||
|
heading = 'ID',
|
||||||
|
key = 'uid',
|
||||||
|
width = 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
heading = 'Title',
|
||||||
|
key = 'title'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
heading = 'Status',
|
||||||
|
key = 'status'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
heading = 'Time',
|
||||||
|
key = 'timestamp'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
values = tasks,
|
||||||
|
sortColumn = 'uid',
|
||||||
|
autospace = true,
|
||||||
|
getDisplayValues = function(self, row)
|
||||||
|
local elapsed = os.clock() - row.timestamp
|
||||||
|
return {
|
||||||
|
uid = row.uid,
|
||||||
|
title = row.title,
|
||||||
|
status = row.isDead and 'error' or coroutine.status(row.co),
|
||||||
|
timestamp = elapsed < 60 and string.format("%ds", math.floor(elapsed)) or string.format("%sm", math.floor(elapsed / 6) / 10)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
}),
|
||||||
|
accelerators = {
|
||||||
|
['control-q'] = 'quit',
|
||||||
|
[' '] = 'activate',
|
||||||
|
t = 'terminate'
|
||||||
|
},
|
||||||
|
eventHandler = function(self, event)
|
||||||
|
local t = self.grid:getSelected()
|
||||||
|
local _exp_0 = event.type
|
||||||
|
if 'activate' == _exp_0 or 'grid_select' == _exp_0 then
|
||||||
|
if t then
|
||||||
|
return multishell.setFocus(t.uid)
|
||||||
|
end
|
||||||
|
elseif 'terminate' == _exp_0 then
|
||||||
|
if t then
|
||||||
|
return multishell.terminate(t.uid)
|
||||||
|
end
|
||||||
|
elseif 'inspect' == _exp_0 then
|
||||||
|
if t then
|
||||||
|
return multishell.openTab(_ENV, {
|
||||||
|
path = 'sys/apps/Lua.lua',
|
||||||
|
args = {
|
||||||
|
t
|
||||||
|
},
|
||||||
|
focused = true
|
||||||
|
})
|
||||||
|
end
|
||||||
|
elseif 'quit' == _exp_0 then
|
||||||
|
return UI:quit()
|
||||||
|
else
|
||||||
|
return UI.Page.eventHandler(self, event)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
Event.onInterval(1, function()
|
||||||
|
page.grid:update()
|
||||||
|
page.grid:draw()
|
||||||
|
return page:sync()
|
||||||
|
end)
|
||||||
|
UI:setPage(page)
|
||||||
|
return UI:start()
|
||||||
70
moonscript/T.moon
Normal file
70
moonscript/T.moon
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
Event = require('opus.event')
|
||||||
|
UI = require('opus.ui')
|
||||||
|
|
||||||
|
kernel = _G.kernel
|
||||||
|
multishell = _ENV.multishell
|
||||||
|
tasks = multishell and multishell.getTabs and multishell.getTabs() or kernel.routines
|
||||||
|
|
||||||
|
UI\configure 'Tasks', ...
|
||||||
|
|
||||||
|
page = UI.Page {
|
||||||
|
menuBar: UI.MenuBar {
|
||||||
|
buttons: {
|
||||||
|
{ text: 'Activate', event: 'activate' },
|
||||||
|
{ text: 'Terminate', event: 'terminate' },
|
||||||
|
{ text: 'Inspect', event: 'inspect' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
grid: UI.ScrollingGrid {
|
||||||
|
y: 2,
|
||||||
|
columns: {
|
||||||
|
{ heading: 'ID', key: 'uid', width: 3 },
|
||||||
|
{ heading: 'Title', key: 'title' },
|
||||||
|
{ heading: 'Status', key: 'status' },
|
||||||
|
{ heading: 'Time', key: 'timestamp' },
|
||||||
|
},
|
||||||
|
values: tasks,
|
||||||
|
sortColumn: 'uid',
|
||||||
|
autospace: true,
|
||||||
|
getDisplayValues: (row) =>
|
||||||
|
elapsed = os.clock! - row.timestamp
|
||||||
|
{
|
||||||
|
uid: row.uid,
|
||||||
|
title: row.title,
|
||||||
|
status: row.isDead and 'error' or coroutine.status(row.co),
|
||||||
|
timestamp: elapsed < 60 and
|
||||||
|
string.format("%ds", math.floor(elapsed)) or
|
||||||
|
string.format("%sm", math.floor(elapsed/6)/10),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
accelerators: {
|
||||||
|
[ 'control-q' ]: 'quit',
|
||||||
|
[ ' ' ]: 'activate',
|
||||||
|
t: 'terminate',
|
||||||
|
},
|
||||||
|
eventHandler: (event) =>
|
||||||
|
t = self.grid\getSelected!
|
||||||
|
switch event.type
|
||||||
|
when 'activate', 'grid_select'
|
||||||
|
multishell.setFocus t.uid if t
|
||||||
|
when 'terminate'
|
||||||
|
multishell.terminate t.uid if t
|
||||||
|
when 'inspect'
|
||||||
|
multishell.openTab _ENV, {
|
||||||
|
path: 'sys/apps/Lua.lua',
|
||||||
|
args: { t },
|
||||||
|
focused: true,
|
||||||
|
} if t
|
||||||
|
when 'quit'
|
||||||
|
UI\quit!
|
||||||
|
else
|
||||||
|
UI.Page.eventHandler(@, event)
|
||||||
|
}
|
||||||
|
|
||||||
|
Event.onInterval 1, () ->
|
||||||
|
page.grid\update!
|
||||||
|
page.grid\draw!
|
||||||
|
page\sync!
|
||||||
|
|
||||||
|
UI\setPage page
|
||||||
|
UI\start!
|
||||||
1527
moonscript/argparse.lua
Normal file
1527
moonscript/argparse.lua
Normal file
File diff suppressed because it is too large
Load Diff
4
moonscript/etc/fstab
Normal file
4
moonscript/etc/fstab
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
packages/moonscript gitfs leafo/moonscript/master/bin
|
||||||
|
rom/modules/main/moonscript gitfs leafo/moonscript/master/moonscript
|
||||||
|
rom/modules/main/moon gitfs leafo/moonscript/master/moon
|
||||||
|
rom/modules/main/argparse.lua linkfs packages/moonscript/argparse.lua
|
||||||
Reference in New Issue
Block a user