1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-06-26 07:03:22 +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:
Jonathan Coates 2023-07-06 23:15:55 +01:00
parent db2616d1c0
commit f7fdb6e729
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
8 changed files with 71 additions and 94 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View 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])

View File

@ -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