mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-09-28 15:08:47 +00:00
Backport a couple of ROM commits
- Improve REPL's handling of expressions (655d5aeca8
) - Some tiny optimisations to the window API (4accda6b8e
) - Be lazy in reporting errors in the lexer (54ab98473f
) - Update lua.lua require logic. (88f0c44152
)
This commit is contained in:
parent
db2616d1c0
commit
f7fdb6e729
@ -127,11 +127,7 @@ function create(parent, nX, nY, nWidth, nHeight, bStartVisible)
|
||||
local sEmptyTextColor = tEmptyColorLines[nTextColor]
|
||||
local sEmptyBackgroundColor = tEmptyColorLines[nBackgroundColor]
|
||||
for y = 1, nHeight do
|
||||
tLines[y] = {
|
||||
text = sEmptyText,
|
||||
textColor = sEmptyTextColor,
|
||||
backgroundColor = sEmptyBackgroundColor,
|
||||
}
|
||||
tLines[y] = { sEmptyText, sEmptyTextColor, sEmptyBackgroundColor }
|
||||
end
|
||||
|
||||
for i = 0, 15 do
|
||||
@ -161,7 +157,7 @@ function create(parent, nX, nY, nWidth, nHeight, bStartVisible)
|
||||
local function redrawLine(n)
|
||||
local tLine = tLines[n]
|
||||
parent.setCursorPos(nX, nY + n - 1)
|
||||
parent.blit(tLine.text, tLine.textColor, tLine.backgroundColor)
|
||||
parent.blit(tLine[1], tLine[2], tLine[3])
|
||||
end
|
||||
|
||||
local function redraw()
|
||||
@ -184,9 +180,9 @@ function create(parent, nX, nY, nWidth, nHeight, bStartVisible)
|
||||
-- Modify line
|
||||
local tLine = tLines[nCursorY]
|
||||
if nStart == 1 and nEnd == nWidth then
|
||||
tLine.text = sText
|
||||
tLine.textColor = sTextColor
|
||||
tLine.backgroundColor = sBackgroundColor
|
||||
tLine[1] = sText
|
||||
tLine[2] = sTextColor
|
||||
tLine[3] = sBackgroundColor
|
||||
else
|
||||
local sClippedText, sClippedTextColor, sClippedBackgroundColor
|
||||
if nStart < 1 then
|
||||
@ -206,9 +202,9 @@ function create(parent, nX, nY, nWidth, nHeight, bStartVisible)
|
||||
sClippedBackgroundColor = sBackgroundColor
|
||||
end
|
||||
|
||||
local sOldText = tLine.text
|
||||
local sOldTextColor = tLine.textColor
|
||||
local sOldBackgroundColor = tLine.backgroundColor
|
||||
local sOldText = tLine[1]
|
||||
local sOldTextColor = tLine[2]
|
||||
local sOldBackgroundColor = tLine[3]
|
||||
local sNewText, sNewTextColor, sNewBackgroundColor
|
||||
if nStart > 1 then
|
||||
local nOldEnd = nStart - 1
|
||||
@ -227,9 +223,9 @@ function create(parent, nX, nY, nWidth, nHeight, bStartVisible)
|
||||
sNewBackgroundColor = sNewBackgroundColor .. string_sub(sOldBackgroundColor, nOldStart, nWidth)
|
||||
end
|
||||
|
||||
tLine.text = sNewText
|
||||
tLine.textColor = sNewTextColor
|
||||
tLine.backgroundColor = sNewBackgroundColor
|
||||
tLine[1] = sNewText
|
||||
tLine[2] = sNewTextColor
|
||||
tLine[3] = sNewBackgroundColor
|
||||
end
|
||||
|
||||
-- Redraw line
|
||||
@ -276,11 +272,10 @@ function create(parent, nX, nY, nWidth, nHeight, bStartVisible)
|
||||
local sEmptyTextColor = tEmptyColorLines[nTextColor]
|
||||
local sEmptyBackgroundColor = tEmptyColorLines[nBackgroundColor]
|
||||
for y = 1, nHeight do
|
||||
tLines[y] = {
|
||||
text = sEmptyText,
|
||||
textColor = sEmptyTextColor,
|
||||
backgroundColor = sEmptyBackgroundColor,
|
||||
}
|
||||
local line = tLines[y]
|
||||
line[1] = sEmptyText
|
||||
line[2] = sEmptyTextColor
|
||||
line[3] = sEmptyBackgroundColor
|
||||
end
|
||||
if bVisible then
|
||||
redraw()
|
||||
@ -291,14 +286,10 @@ function create(parent, nX, nY, nWidth, nHeight, bStartVisible)
|
||||
|
||||
function window.clearLine()
|
||||
if nCursorY >= 1 and nCursorY <= nHeight then
|
||||
local sEmptyText = sEmptySpaceLine
|
||||
local sEmptyTextColor = tEmptyColorLines[nTextColor]
|
||||
local sEmptyBackgroundColor = tEmptyColorLines[nBackgroundColor]
|
||||
tLines[nCursorY] = {
|
||||
text = sEmptyText,
|
||||
textColor = sEmptyTextColor,
|
||||
backgroundColor = sEmptyBackgroundColor,
|
||||
}
|
||||
local line = tLines[nCursorY]
|
||||
line[1] = sEmptySpaceLine
|
||||
line[2] = tEmptyColorLines[nTextColor]
|
||||
line[3] = tEmptyColorLines[nBackgroundColor]
|
||||
if bVisible then
|
||||
redrawLine(nCursorY)
|
||||
updateCursorColor()
|
||||
@ -427,11 +418,7 @@ function create(parent, nX, nY, nWidth, nHeight, bStartVisible)
|
||||
if y >= 1 and y <= nHeight then
|
||||
tNewLines[newY] = tLines[y]
|
||||
else
|
||||
tNewLines[newY] = {
|
||||
text = sEmptyText,
|
||||
textColor = sEmptyTextColor,
|
||||
backgroundColor = sEmptyBackgroundColor,
|
||||
}
|
||||
tNewLines[newY] = { sEmptyText, sEmptyTextColor, sEmptyBackgroundColor }
|
||||
end
|
||||
end
|
||||
tLines = tNewLines
|
||||
@ -474,7 +461,8 @@ function create(parent, nX, nY, nWidth, nHeight, bStartVisible)
|
||||
error("Line is out of range.", 2)
|
||||
end
|
||||
|
||||
return tLines[y].text, tLines[y].textColor, tLines[y].backgroundColor
|
||||
local line = tLines[y]
|
||||
return line[1], line[2], line[3]
|
||||
end
|
||||
|
||||
-- Other functions
|
||||
@ -570,26 +558,22 @@ function create(parent, nX, nY, nWidth, nHeight, bStartVisible)
|
||||
local sEmptyBackgroundColor = tEmptyColorLines[nBackgroundColor]
|
||||
for y = 1, new_height do
|
||||
if y > nHeight then
|
||||
tNewLines[y] = {
|
||||
text = sEmptyText,
|
||||
textColor = sEmptyTextColor,
|
||||
backgroundColor = sEmptyBackgroundColor,
|
||||
}
|
||||
tNewLines[y] = { sEmptyText, sEmptyTextColor, sEmptyBackgroundColor }
|
||||
else
|
||||
local tOldLine = tLines[y]
|
||||
if new_width == nWidth then
|
||||
tNewLines[y] = tOldLine
|
||||
elseif new_width < nWidth then
|
||||
tNewLines[y] = {
|
||||
text = string_sub(tOldLine.text, 1, new_width),
|
||||
textColor = string_sub(tOldLine.textColor, 1, new_width),
|
||||
backgroundColor = string_sub(tOldLine.backgroundColor, 1, new_width),
|
||||
string_sub(tOldLine[1], 1, new_width),
|
||||
string_sub(tOldLine[2], 1, new_width),
|
||||
string_sub(tOldLine[3], 1, new_width),
|
||||
}
|
||||
else
|
||||
tNewLines[y] = {
|
||||
text = tOldLine.text .. string_sub(sEmptyText, nWidth + 1, new_width),
|
||||
textColor = tOldLine.textColor .. string_sub(sEmptyTextColor, nWidth + 1, new_width),
|
||||
backgroundColor = tOldLine.backgroundColor .. string_sub(sEmptyBackgroundColor, nWidth + 1, new_width),
|
||||
tOldLine[1] .. string_sub(sEmptyText, nWidth + 1, new_width),
|
||||
tOldLine[2] .. string_sub(sEmptyTextColor, nWidth + 1, new_width),
|
||||
tOldLine[3] .. string_sub(sEmptyBackgroundColor, nWidth + 1, new_width),
|
||||
}
|
||||
end
|
||||
end
|
||||
|
@ -17,6 +17,8 @@ local error_printer = require "cc.internal.error_printer"
|
||||
local error_sentinel = {}
|
||||
|
||||
local function make_context(input)
|
||||
expect(1, input, "string")
|
||||
|
||||
local context = {}
|
||||
|
||||
local lines = { 1 }
|
||||
@ -69,8 +71,9 @@ local function parse(input, start_symbol)
|
||||
expect(2, start_symbol, "number")
|
||||
|
||||
local context = make_context(input)
|
||||
function context.report(msg)
|
||||
expect(1, msg, "table")
|
||||
function context.report(msg, ...)
|
||||
expect(1, msg, "table", "function")
|
||||
if type(msg) == "function" then msg = msg(...) end
|
||||
error_printer(context, msg)
|
||||
error(error_sentinel)
|
||||
end
|
||||
@ -106,8 +109,9 @@ local function parse_repl(input)
|
||||
local context = make_context(input)
|
||||
|
||||
local last_error = nil
|
||||
function context.report(msg)
|
||||
expect(1, msg, "table")
|
||||
function context.report(msg, ...)
|
||||
expect(1, msg, "table", "function")
|
||||
if type(msg) == "function" then msg = msg(...) end
|
||||
last_error = msg
|
||||
error(error_sentinel)
|
||||
end
|
||||
|
@ -92,7 +92,7 @@ local function lex_number(context, str, start)
|
||||
local contents = sub(str, start, pos - 1)
|
||||
if not tonumber(contents) then
|
||||
-- TODO: Separate error for "2..3"?
|
||||
context.report(errors.malformed_number(start, pos - 1))
|
||||
context.report(errors.malformed_number, start, pos - 1)
|
||||
end
|
||||
|
||||
return tokens.NUMBER, pos - 1
|
||||
@ -114,14 +114,14 @@ local function lex_string(context, str, start_pos, quote)
|
||||
return tokens.STRING, pos
|
||||
elseif c == "\n" or c == "\r" or c == "" then
|
||||
-- We don't call newline here, as that's done for the next token.
|
||||
context.report(errors.unfinished_string(start_pos, pos, quote))
|
||||
context.report(errors.unfinished_string, start_pos, pos, quote)
|
||||
return tokens.STRING, pos - 1
|
||||
elseif c == "\\" then
|
||||
c = sub(str, pos + 1, pos + 1)
|
||||
if c == "\n" or c == "\r" then
|
||||
pos = newline(context, str, pos + 1, c)
|
||||
elseif c == "" then
|
||||
context.report(errors.unfinished_string_escape(start_pos, pos, quote))
|
||||
context.report(errors.unfinished_string_escape, start_pos, pos, quote)
|
||||
return tokens.STRING, pos
|
||||
elseif c == "z" then
|
||||
pos = pos + 2
|
||||
@ -129,7 +129,7 @@ local function lex_string(context, str, start_pos, quote)
|
||||
local next_pos, _, c = find(str, "([%S\r\n])", pos)
|
||||
|
||||
if not next_pos then
|
||||
context.report(errors.unfinished_string(start_pos, #str, quote))
|
||||
context.report(errors.unfinished_string, start_pos, #str, quote)
|
||||
return tokens.STRING, #str
|
||||
end
|
||||
|
||||
@ -192,7 +192,7 @@ local function lex_long_str(context, str, start, len)
|
||||
elseif c == "[" then
|
||||
local ok, boundary_pos = lex_long_str_boundary(str, pos + 1, "[")
|
||||
if ok and boundary_pos - pos == len and len == 1 then
|
||||
context.report(errors.nested_long_str(pos, boundary_pos))
|
||||
context.report(errors.nested_long_str, pos, boundary_pos)
|
||||
end
|
||||
|
||||
pos = boundary_pos
|
||||
@ -234,12 +234,12 @@ local function lex_token(context, str, pos)
|
||||
local end_pos = lex_long_str(context, str, boundary_pos + 1, boundary_pos - pos)
|
||||
if end_pos then return tokens.STRING, end_pos end
|
||||
|
||||
context.report(errors.unfinished_long_string(pos, boundary_pos, boundary_pos - pos))
|
||||
context.report(errors.unfinished_long_string, pos, boundary_pos, boundary_pos - pos)
|
||||
return tokens.ERROR, #str
|
||||
elseif pos + 1 == boundary_pos then -- Just a "["
|
||||
return tokens.OSQUARE, pos
|
||||
else -- Malformed long string, for instance "[="
|
||||
context.report(errors.malformed_long_string(pos, boundary_pos, boundary_pos - pos))
|
||||
context.report(errors.malformed_long_string, pos, boundary_pos, boundary_pos - pos)
|
||||
return tokens.ERROR, boundary_pos
|
||||
end
|
||||
|
||||
@ -256,7 +256,7 @@ local function lex_token(context, str, pos)
|
||||
local end_pos = lex_long_str(context, str, boundary_pos + 1, boundary_pos - comment_pos)
|
||||
if end_pos then return tokens.COMMENT, end_pos end
|
||||
|
||||
context.report(errors.unfinished_long_comment(pos, boundary_pos, boundary_pos - comment_pos))
|
||||
context.report(errors.unfinished_long_comment, pos, boundary_pos, boundary_pos - comment_pos)
|
||||
return tokens.ERROR, #str
|
||||
end
|
||||
end
|
||||
@ -313,18 +313,18 @@ local function lex_token(context, str, pos)
|
||||
if end_pos - pos <= 3 then
|
||||
local contents = sub(str, pos, end_pos)
|
||||
if contents == "&&" then
|
||||
context.report(errors.wrong_and(pos, end_pos))
|
||||
context.report(errors.wrong_and, pos, end_pos)
|
||||
return tokens.AND, end_pos
|
||||
elseif contents == "||" then
|
||||
context.report(errors.wrong_or(pos, end_pos))
|
||||
context.report(errors.wrong_or, pos, end_pos)
|
||||
return tokens.OR, end_pos
|
||||
elseif contents == "!=" or contents == "<>" then
|
||||
context.report(errors.wrong_ne(pos, end_pos))
|
||||
context.report(errors.wrong_ne, pos, end_pos)
|
||||
return tokens.NE, end_pos
|
||||
end
|
||||
end
|
||||
|
||||
context.report(errors.unexpected_character(pos))
|
||||
context.report(errors.unexpected_character, pos)
|
||||
return tokens.ERROR, end_pos
|
||||
end
|
||||
end
|
||||
|
@ -240,7 +240,7 @@ local function handle_error(context, stack, stack_n, token, token_start, token_e
|
||||
end
|
||||
end
|
||||
|
||||
context.report(errors.unexpected_token(token, token_start, token_end))
|
||||
context.report(errors.unexpected_token, token, token_start, token_end)
|
||||
return false
|
||||
end
|
||||
|
||||
|
@ -107,7 +107,9 @@ local function set_status(text, ok)
|
||||
status_text = text
|
||||
end
|
||||
|
||||
if not bReadOnly and fs.getFreeSpace(sPath) < 1024 then
|
||||
if bReadOnly then
|
||||
set_status("File is read only", false)
|
||||
elseif fs.getFreeSpace(sPath) < 1024 then
|
||||
set_status("Disk is low on space", false)
|
||||
else
|
||||
local message
|
||||
|
@ -27,7 +27,7 @@ local function pcm_decoder(chunk)
|
||||
end
|
||||
|
||||
local function report_invalid_format(format)
|
||||
printError(("The speaker cannot play %s files."):format(format))
|
||||
printError(("speaker cannot play %s files."):format(format))
|
||||
local pp = require "cc.pretty"
|
||||
pp.print("Run '" .. pp.text("help speaker", colours.lightGrey) .. "' for information on supported formats.")
|
||||
end
|
||||
@ -103,6 +103,7 @@ elseif cmd == "play" then
|
||||
elseif start == "OggS" then return report_invalid_format("Ogg")
|
||||
elseif start == "fLaC" then return report_invalid_format("FLAC")
|
||||
elseif start:sub(1, 3) == "ID3" then return report_invalid_format("MP3")
|
||||
elseif start == "<!DO" --[[<!DOCTYPE]] then return report_invalid_format("HTML")
|
||||
end
|
||||
|
||||
print("Playing " .. file)
|
||||
|
@ -21,21 +21,13 @@ local tEnv = {
|
||||
}
|
||||
setmetatable(tEnv, { __index = _ENV })
|
||||
|
||||
-- Replace our package.path, so that it loads from the current directory, rather
|
||||
-- than from /rom/programs. This makes it a little more friendly to use and
|
||||
-- closer to what you'd expect.
|
||||
-- Replace our require with new instance that loads from the current directory
|
||||
-- rather than from /rom/programs. This makes it more friendly to use and closer
|
||||
-- to what you'd expect.
|
||||
do
|
||||
local make_package = require "cc.require".make
|
||||
local dir = shell.dir()
|
||||
if dir:sub(1, 1) ~= "/" then dir = "/" .. dir end
|
||||
if dir:sub(-1) ~= "/" then dir = dir .. "/" end
|
||||
|
||||
local strip_path = "?;?.lua;?/init.lua;"
|
||||
local path = package.path
|
||||
if path:sub(1, #strip_path) == strip_path then
|
||||
path = path:sub(#strip_path + 1)
|
||||
end
|
||||
|
||||
package.path = dir .. "?;" .. dir .. "?.lua;" .. dir .. "?/init.lua;" .. path
|
||||
_ENV.require, _ENV.package = make_package(_ENV, dir)
|
||||
end
|
||||
|
||||
if term.isColour() then
|
||||
@ -78,18 +70,13 @@ while running do
|
||||
|
||||
local name, offset = "=lua[" .. chunk_idx .. "]", 0
|
||||
|
||||
local force_print = 0
|
||||
local func, err = load(input, name, "t", tEnv)
|
||||
|
||||
local expr_func = load("return _echo(" .. input .. ");", name, "t", tEnv)
|
||||
if not func then
|
||||
if expr_func then
|
||||
func = expr_func
|
||||
offset = 13
|
||||
force_print = 1
|
||||
end
|
||||
elseif expr_func then
|
||||
func = expr_func
|
||||
if load("return " .. input) then
|
||||
-- We wrap the expression with a call to _echo(...), which prevents tail
|
||||
-- calls (and thus confusing errors). Note we check this is a valid
|
||||
-- expression separately, to avoid accepting inputs like `)--` (which are
|
||||
-- parsed as `_echo()--)`.
|
||||
func = load("return _echo(" .. input .. "\n)", name, "t", tEnv)
|
||||
offset = 13
|
||||
end
|
||||
|
||||
@ -99,9 +86,8 @@ while running do
|
||||
|
||||
local results = table.pack(exception.try(func))
|
||||
if results[1] then
|
||||
local n = 1
|
||||
while n < results.n or n <= force_print do
|
||||
local value = results[n + 1]
|
||||
for i = 2, results.n do
|
||||
local value = results[i]
|
||||
local ok, serialised = pcall(pretty.pretty, value, {
|
||||
function_args = settings.get("lua.function_args"),
|
||||
function_source = settings.get("lua.function_source"),
|
||||
@ -111,7 +97,6 @@ while running do
|
||||
else
|
||||
print(tostring(value))
|
||||
end
|
||||
n = n + 1
|
||||
end
|
||||
else
|
||||
printError(results[2])
|
||||
|
@ -45,8 +45,9 @@ local function capture_parser(input, print_tokens, start)
|
||||
end
|
||||
|
||||
local context = make_context(input)
|
||||
function context.report(message)
|
||||
expect(3, message, "table")
|
||||
function context.report(message, ...)
|
||||
expect(3, message, "table", "function")
|
||||
if type(message) == "function" then message = message(...) end
|
||||
|
||||
for _, msg in ipairs(message) do
|
||||
if type(msg) == "table" and msg.tag == "annotate" then
|
||||
|
Loading…
Reference in New Issue
Block a user