Backport several ROM/Lua commits

- Fix GPS returning nan on duplicate positions.
 - Distinguish between all parsers passing and failing.
 - Improve several comma related parse errors.
 - Ignore metatables in textutils.serialize.
 - Detect common audio containers in "speaker".

Co-authored-by: Wojbie <Wojbie@gmail.com>
This commit is contained in:
Jonathan Coates 2023-05-03 23:24:49 +01:00
parent 0fce3212a3
commit 2a9f35de5e
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
6 changed files with 113 additions and 25 deletions

View File

@ -153,12 +153,22 @@ function locate(_nTimeout, _bDebug)
if tFix.nDistance == 0 then
pos1, pos2 = tFix.vPosition, nil
else
table.insert(tFixes, tFix)
-- Insert our new position in our table, with a maximum of three items. If this is close to a
-- previous position, replace that instead of inserting.
local insIndex = math.min(3, #tFixes + 1)
for i, older in pairs(tFixes) do
if (older.vPosition - tFix.vPosition):length() < 1 then
insIndex = i
break
end
end
tFixes[insIndex] = tFix
if #tFixes >= 3 then
if not pos1 then
pos1, pos2 = trilaterate(tFixes[1], tFixes[2], tFixes[#tFixes])
pos1, pos2 = trilaterate(tFixes[1], tFixes[2], tFixes[3])
else
pos1, pos2 = narrow(pos1, pos2, tFixes[#tFixes])
pos1, pos2 = narrow(pos1, pos2, tFixes[3])
end
end
end

View File

@ -74,8 +74,7 @@ function undefine(name)
details[name] = nil
end
local function set_value(name, value)
local new = reserialize(value)
local function set_value(name, new)
local old = values[name]
if old == nil then
local opt = details[name]
@ -103,7 +102,7 @@ function set(name, value)
local opt = details[name]
if opt and opt.type then expect(2, value, opt.type) end
set_value(name, value)
set_value(name, reserialize(value))
end
--- Get the value of a setting.
@ -214,7 +213,9 @@ function load(sPath)
if type(k) == "string" and (ty_v == "string" or ty_v == "number" or ty_v == "boolean" or ty_v == "table") then
local opt = details[k]
if not opt or not opt.type or ty_v == opt.type then
set_value(k, v)
-- This may fail if the table is recursive (or otherwise cannot be serialized).
local ok, v = pcall(reserialize, v)
if ok then set_value(k, v) end
end
end
end

View File

@ -292,6 +292,13 @@ local g_tLuaKeywords = {
["while"] = true,
}
--- A version of the ipairs iterator which ignores metamethods
local function inext(tbl, i)
i = (i or 0) + 1
local v = rawget(tbl, i)
if v == nil then return nil else return i, v end
end
local serialize_infinity = math.huge
local function serialize_impl(t, tracking, indent, opts)
local sType = type(t)
@ -318,11 +325,11 @@ local function serialize_impl(t, tracking, indent, opts)
result = open
local seen_keys = {}
for k, v in ipairs(t) do
for k, v in inext, t do
seen_keys[k] = true
result = result .. sub_indent .. serialize_impl(v, tracking, sub_indent, opts) .. comma
end
for k, v in pairs(t) do
for k, v in next, t do
if not seen_keys[k] then
local sEntry
if type(k) == "string" and not g_tLuaKeywords[k] and string.match(k, "^[%a_][%a%d_]*$") then

View File

@ -364,6 +364,48 @@ function errors.table_key_equals(start_pos, end_pos)
}
end
--[[- There is a trailing comma in this list of function arguments.
@tparam number token The token id.
@tparam number token_start The start position of the token.
@tparam number token_end The end position of the token.
@tparam number prev The start position of the previous entry.
@treturn table The resulting parse error.
]]
function errors.missing_table_comma(token, token_start, token_end, prev)
expect(1, token, "number")
expect(2, token_start, "number")
expect(3, token_end, "number")
expect(4, prev, "number")
return {
"Unexpected " .. token_names[token] .. " in table.",
annotate(token_start, token_end),
annotate(prev + 1, prev + 1, "Are you missing a comma here?"),
}
end
--[[- There is a trailing comma in this list of function arguments.
@tparam number comma_start The start position of the `,` token.
@tparam number comma_end The end position of the `,` token.
@tparam number paren_start The start position of the `)` token.
@tparam number paren_end The end position of the `)` token.
@treturn table The resulting parse error.
]]
function errors.trailing_call_comma(comma_start, comma_end, paren_start, paren_end)
expect(1, comma_start, "number")
expect(2, comma_end, "number")
expect(3, paren_start, "number")
expect(4, paren_end, "number")
return {
"Unexpected " .. code(")") .. " in function call.",
annotate(paren_start, paren_end),
annotate(comma_start, comma_end, "Tip: Try removing this " .. code(",") .. "."),
}
end
--------------------------------------------------------------------------------
-- Statement parsing errors
--------------------------------------------------------------------------------

File diff suppressed because one or more lines are too long

View File

@ -26,6 +26,12 @@ local function pcm_decoder(chunk)
return buffer
end
local function report_invalid_format(format)
printError(("The 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
local cmd = ...
if cmd == "stop" then
@ -93,6 +99,10 @@ elseif cmd == "play" then
handle.read(4)
start = nil
-- Detect several other common audio files.
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")
end
print("Playing " .. file)