mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-08-24 22:42:18 +00:00
Update to latest CC:T rom
More or less - we're not updating to Lua 5.2/binary-only handles, so have skipped some changes.
This commit is contained in:
parent
e62f2630b5
commit
58d54e2e70
@ -35,6 +35,7 @@ local term = _ENV
|
||||
-- @since 1.31
|
||||
-- @usage
|
||||
-- Redirect to a monitor on the right of the computer.
|
||||
--
|
||||
-- term.redirect(peripheral.wrap("right"))
|
||||
term.redirect = function(target)
|
||||
expect(1, target, "table")
|
||||
|
@ -448,20 +448,25 @@ do
|
||||
end
|
||||
end
|
||||
|
||||
local function serializeJSONImpl(t, tTracking, options)
|
||||
local function serializeJSONImpl(t, tracking, options)
|
||||
local sType = type(t)
|
||||
if t == empty_json_array then return "[]"
|
||||
elseif t == json_null then return "null"
|
||||
|
||||
elseif sType == "table" then
|
||||
if tTracking[t] ~= nil then
|
||||
error("Cannot serialize table with recursive entries", 0)
|
||||
if tracking[t] ~= nil then
|
||||
if tracking[t] == false then
|
||||
error("Cannot serialize table with repeated entries", 0)
|
||||
else
|
||||
error("Cannot serialize table with recursive entries", 0)
|
||||
end
|
||||
end
|
||||
tTracking[t] = true
|
||||
tracking[t] = true
|
||||
|
||||
local result
|
||||
if next(t) == nil then
|
||||
-- Empty tables are simple
|
||||
return "{}"
|
||||
result = "{}"
|
||||
else
|
||||
-- Other tables take more work
|
||||
local sObjectResult = "{"
|
||||
@ -469,14 +474,14 @@ local function serializeJSONImpl(t, tTracking, options)
|
||||
local nObjectSize = 0
|
||||
local nArraySize = 0
|
||||
local largestArrayIndex = 0
|
||||
local bNBTStyle = options and options.nbt_style
|
||||
local bNBTStyle = options.nbt_style
|
||||
for k, v in pairs(t) do
|
||||
if type(k) == "string" then
|
||||
local sEntry
|
||||
if bNBTStyle then
|
||||
sEntry = tostring(k) .. ":" .. serializeJSONImpl(v, tTracking, options)
|
||||
sEntry = tostring(k) .. ":" .. serializeJSONImpl(v, tracking, options)
|
||||
else
|
||||
sEntry = serializeJSONString(k, options) .. ":" .. serializeJSONImpl(v, tTracking, options)
|
||||
sEntry = serializeJSONString(k, options) .. ":" .. serializeJSONImpl(v, tracking, options)
|
||||
end
|
||||
if nObjectSize == 0 then
|
||||
sObjectResult = sObjectResult .. sEntry
|
||||
@ -493,7 +498,7 @@ local function serializeJSONImpl(t, tTracking, options)
|
||||
if t[k] == nil then --if the array is nil at index k the value is "null" as to keep the unused indexes in between used ones.
|
||||
sEntry = "null"
|
||||
else -- if the array index does not point to a nil we serialise it's content.
|
||||
sEntry = serializeJSONImpl(t[k], tTracking, options)
|
||||
sEntry = serializeJSONImpl(t[k], tracking, options)
|
||||
end
|
||||
if nArraySize == 0 then
|
||||
sArrayResult = sArrayResult .. sEntry
|
||||
@ -505,12 +510,19 @@ local function serializeJSONImpl(t, tTracking, options)
|
||||
sObjectResult = sObjectResult .. "}"
|
||||
sArrayResult = sArrayResult .. "]"
|
||||
if nObjectSize > 0 or nArraySize == 0 then
|
||||
return sObjectResult
|
||||
result = sObjectResult
|
||||
else
|
||||
return sArrayResult
|
||||
result = sArrayResult
|
||||
end
|
||||
end
|
||||
|
||||
if options.allow_repetitions then
|
||||
tracking[t] = nil
|
||||
else
|
||||
tracking[t] = false
|
||||
end
|
||||
return result
|
||||
|
||||
elseif sType == "string" then
|
||||
return serializeJSONString(t, options)
|
||||
|
||||
@ -844,10 +856,16 @@ This is largely intended for interacting with various functions from the
|
||||
|
||||
@param[1] t The value to serialise. Like [`textutils.serialise`], this should not
|
||||
contain recursive tables or functions.
|
||||
@tparam[1,opt] { nbt_style? = boolean, unicode_strings? = boolean } options Options for serialisation.
|
||||
- `nbt_style`: Whether to produce NBT-style JSON (non-quoted keys) instead of standard JSON.
|
||||
- `unicode_strings`: Whether to treat strings as containing UTF-8 characters instead of
|
||||
using the default 8-bit character set.
|
||||
@tparam[1,opt] {
|
||||
nbt_style? = boolean,
|
||||
unicode_strings? = boolean,
|
||||
allow_repetitions? = boolean
|
||||
} options Options for serialisation.
|
||||
- `nbt_style`: Whether to produce NBT-style JSON (non-quoted keys) instead of standard JSON.
|
||||
- `unicode_strings`: Whether to treat strings as containing UTF-8 characters instead of
|
||||
using the default 8-bit character set.
|
||||
- `allow_repetitions`: Relax the check for recursive tables, allowing them to appear multiple
|
||||
times (as long as tables do not appear inside themselves).
|
||||
|
||||
@param[2] t The value to serialise. Like [`textutils.serialise`], this should not
|
||||
contain recursive tables or functions.
|
||||
@ -868,6 +886,7 @@ functions and tables which appear multiple times.
|
||||
|
||||
@since 1.7
|
||||
@changed 1.106.0 Added `options` overload and `unicode_strings` option.
|
||||
@changed 1.109.0 Added `allow_repetitions` option.
|
||||
|
||||
@see textutils.json_null Use to serialise a JSON `null` value.
|
||||
@see textutils.empty_json_array Use to serialise a JSON empty array.
|
||||
@ -880,6 +899,9 @@ function serializeJSON(t, options)
|
||||
elseif type(options) == "table" then
|
||||
field(options, "nbt_style", "boolean", "nil")
|
||||
field(options, "unicode_strings", "boolean", "nil")
|
||||
field(options, "allow_repetitions", "boolean", "nil")
|
||||
else
|
||||
options = {}
|
||||
end
|
||||
|
||||
local tTracking = {}
|
||||
|
@ -0,0 +1,37 @@
|
||||
-- SPDX-FileCopyrightText: 2024 The CC: Tweaked Developers
|
||||
--
|
||||
-- SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
--[[- Utilities for working with events.
|
||||
|
||||
> [!DANGER]
|
||||
> This is an internal module and SHOULD NOT be used in your own code. It may
|
||||
> be removed or changed at any time.
|
||||
|
||||
@local
|
||||
]]
|
||||
|
||||
--[[-
|
||||
Attempt to discard a [`event!char`] event that may follow a [`event!key`] event.
|
||||
|
||||
This attempts to flush the event queue via a timer, stopping early if we observe
|
||||
another key or char event.
|
||||
|
||||
We flush the event queue by waiting a single tick. It is technically possible
|
||||
the key and char events will be delivered in different ticks, but it should be
|
||||
very rare, and not worth adding extra delay for.
|
||||
]]
|
||||
local function discard_char()
|
||||
local timer = os.startTimer(0)
|
||||
while true do
|
||||
local event, id = os.pullEvent()
|
||||
if event == "timer" and id == timer then break
|
||||
elseif event == "char" or event == "key" or event == "key_up" then
|
||||
os.cancelTimer(timer)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return { discard_char = discard_char }
|
@ -58,6 +58,7 @@ local token_names = setmetatable({
|
||||
[tokens.DO] = code("do"),
|
||||
[tokens.DOT] = code("."),
|
||||
[tokens.DOTS] = code("..."),
|
||||
[tokens.DOUBLE_COLON] = code("::"),
|
||||
[tokens.ELSE] = code("else"),
|
||||
[tokens.ELSEIF] = code("elseif"),
|
||||
[tokens.END] = code("end"),
|
||||
@ -67,6 +68,7 @@ local token_names = setmetatable({
|
||||
[tokens.FOR] = code("for"),
|
||||
[tokens.FUNCTION] = code("function"),
|
||||
[tokens.GE] = code(">="),
|
||||
[tokens.GOTO] = code("goto"),
|
||||
[tokens.GT] = code(">"),
|
||||
[tokens.IF] = code("if"),
|
||||
[tokens.IN] = code("in"),
|
||||
@ -451,32 +453,53 @@ function errors.local_function_dot(local_start, local_end, dot_start, dot_end)
|
||||
}
|
||||
end
|
||||
|
||||
--[[- A statement of the form `x.y z`
|
||||
--[[- A statement of the form `x.y`
|
||||
|
||||
@tparam number token The token id.
|
||||
@tparam number pos The position right after this name.
|
||||
@return The resulting parse error.
|
||||
]]
|
||||
function errors.standalone_name(pos)
|
||||
expect(1, pos, "number")
|
||||
function errors.standalone_name(token, pos)
|
||||
expect(1, token, "number")
|
||||
expect(2, pos, "number")
|
||||
|
||||
return {
|
||||
"Unexpected symbol after name.",
|
||||
"Unexpected " .. token_names[token] .. " after name.",
|
||||
annotate(pos),
|
||||
"Did you mean to assign this or call it as a function?",
|
||||
}
|
||||
end
|
||||
|
||||
--[[- A statement of the form `x.y, z`
|
||||
|
||||
@tparam number token The token id.
|
||||
@tparam number pos The position right after this name.
|
||||
@return The resulting parse error.
|
||||
]]
|
||||
function errors.standalone_names(token, pos)
|
||||
expect(1, token, "number")
|
||||
expect(2, pos, "number")
|
||||
|
||||
return {
|
||||
"Unexpected " .. token_names[token] .. " after name.",
|
||||
annotate(pos),
|
||||
"Did you mean to assign this?",
|
||||
}
|
||||
end
|
||||
|
||||
--[[- A statement of the form `x.y`. This is similar to [`standalone_name`], but
|
||||
when the next token is on another line.
|
||||
|
||||
@tparam number token The token id.
|
||||
@tparam number pos The position right after this name.
|
||||
@return The resulting parse error.
|
||||
]]
|
||||
function errors.standalone_name_call(pos)
|
||||
expect(1, pos, "number")
|
||||
function errors.standalone_name_call(token, pos)
|
||||
expect(1, token, "number")
|
||||
expect(2, pos, "number")
|
||||
|
||||
return {
|
||||
"Unexpected symbol after variable.",
|
||||
"Unexpected " .. token_names[token] .. " after name.",
|
||||
annotate(pos + 1, "Expected something before the end of the line."),
|
||||
"Tip: Use " .. code("()") .. " to call with no arguments.",
|
||||
}
|
||||
@ -535,6 +558,28 @@ function errors.unexpected_end(start_pos, end_pos)
|
||||
}
|
||||
end
|
||||
|
||||
--[[- A label statement was opened but not closed.
|
||||
|
||||
@tparam number open_start The start position of the opening label.
|
||||
@tparam number open_end The end position of the opening label.
|
||||
@tparam number tok_start The start position of the current token.
|
||||
@return The resulting parse error.
|
||||
]]
|
||||
function errors.unclosed_label(open_start, open_end, token, start_pos, end_pos)
|
||||
expect(1, open_start, "number")
|
||||
expect(2, open_end, "number")
|
||||
expect(3, token, "number")
|
||||
expect(4, start_pos, "number")
|
||||
expect(5, end_pos, "number")
|
||||
|
||||
return {
|
||||
"Unexpected " .. token_names[token] .. ".",
|
||||
annotate(open_start, open_end, "Label was started here."),
|
||||
annotate(start_pos, end_pos, "Tip: Try adding " .. code("::") .. " here."),
|
||||
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Generic parsing errors
|
||||
--------------------------------------------------------------------------------
|
||||
|
@ -32,12 +32,12 @@ local tokens = require "cc.internal.syntax.parser".tokens
|
||||
local sub, find = string.sub, string.find
|
||||
|
||||
local keywords = {
|
||||
["and"] = tokens.AND, ["break"] = tokens.BREAK, ["do"] = tokens.DO, ["else"] = tokens.ELSE,
|
||||
["elseif"] = tokens.ELSEIF, ["end"] = tokens.END, ["false"] = tokens.FALSE, ["for"] = tokens.FOR,
|
||||
["function"] = tokens.FUNCTION, ["if"] = tokens.IF, ["in"] = tokens.IN, ["local"] = tokens.LOCAL,
|
||||
["nil"] = tokens.NIL, ["not"] = tokens.NOT, ["or"] = tokens.OR, ["repeat"] = tokens.REPEAT,
|
||||
["return"] = tokens.RETURN, ["then"] = tokens.THEN, ["true"] = tokens.TRUE, ["until"] = tokens.UNTIL,
|
||||
["while"] = tokens.WHILE,
|
||||
["and"] = tokens.AND, ["break"] = tokens.BREAK, ["do"] = tokens.DO, ["else"] = tokens.ELSE,
|
||||
["elseif"] = tokens.ELSEIF, ["end"] = tokens.END, ["false"] = tokens.FALSE, ["for"] = tokens.FOR,
|
||||
["function"] = tokens.FUNCTION, ["goto"] = tokens.GOTO, ["if"] = tokens.IF, ["in"] = tokens.IN,
|
||||
["local"] = tokens.LOCAL, ["nil"] = tokens.NIL, ["not"] = tokens.NOT, ["or"] = tokens.OR,
|
||||
["repeat"] = tokens.REPEAT, ["return"] = tokens.RETURN, ["then"] = tokens.THEN, ["true"] = tokens.TRUE,
|
||||
["until"] = tokens.UNTIL, ["while"] = tokens.WHILE,
|
||||
}
|
||||
|
||||
--- Lex a newline character
|
||||
@ -292,12 +292,15 @@ local function lex_token(context, str, pos)
|
||||
local next_pos = pos + 1
|
||||
if sub(str, next_pos, next_pos) == "=" then return tokens.LE, next_pos end
|
||||
return tokens.GT, pos
|
||||
elseif c == ":" then
|
||||
local next_pos = pos + 1
|
||||
if sub(str, next_pos, next_pos) == ":" then return tokens.DOUBLE_COLON, next_pos end
|
||||
return tokens.COLON, pos
|
||||
elseif c == "~" and sub(str, pos + 1, pos + 1) == "=" then return tokens.NE, pos + 1
|
||||
|
||||
-- Single character tokens
|
||||
elseif c == "," then return tokens.COMMA, pos
|
||||
elseif c == ";" then return tokens.SEMICOLON, pos
|
||||
elseif c == ":" then return tokens.COLON, pos
|
||||
elseif c == "(" then return tokens.OPAREN, pos
|
||||
elseif c == ")" then return tokens.CPAREN, pos
|
||||
elseif c == "]" then return tokens.CSQUARE, pos
|
||||
|
File diff suppressed because one or more lines are too long
@ -124,13 +124,22 @@ local function make_package(env, dir)
|
||||
local package = {}
|
||||
package.loaded = {
|
||||
_G = _G,
|
||||
bit32 = bit32,
|
||||
coroutine = coroutine,
|
||||
math = math,
|
||||
package = package,
|
||||
string = string,
|
||||
table = table,
|
||||
}
|
||||
|
||||
-- Copy everything from the global package table to this instance.
|
||||
--
|
||||
-- This table is an internal implementation detail - it is NOT intended to
|
||||
-- be extended by user code.
|
||||
local registry = debug.getregistry()
|
||||
if registry and type(registry._LOADED) == "table" then
|
||||
for k, v in next, registry._LOADED do
|
||||
if type(k) == "string" then
|
||||
package.loaded[k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
package.path = "?;?.lua;?/init.lua;/rom/modules/main/?;/rom/modules/main/?.lua;/rom/modules/main/?/init.lua"
|
||||
if turtle then
|
||||
package.path = package.path .. ";/rom/modules/turtle/?;/rom/modules/turtle/?.lua;/rom/modules/turtle/?/init.lua"
|
||||
|
@ -88,6 +88,7 @@ for i = 1, #wrapped do
|
||||
term.write(wrapped[i])
|
||||
end
|
||||
os.pullEvent('key')
|
||||
require "cc.internal.event".discard_char()
|
||||
]]
|
||||
|
||||
-- Menus
|
||||
|
@ -300,7 +300,7 @@ local menu_choices = {
|
||||
return false
|
||||
end,
|
||||
Exit = function()
|
||||
sleep(0) -- Super janky, but consumes stray "char" events from pressing Ctrl then E separately.
|
||||
require "cc.internal.event".discard_char() -- Consume stray "char" events from pressing Ctrl then E separately.
|
||||
return true
|
||||
end,
|
||||
}
|
||||
|
@ -257,7 +257,7 @@ while true do
|
||||
offset = print_height - content_height
|
||||
draw()
|
||||
elseif param == keys.q then
|
||||
sleep(0) -- Super janky, but consumes stray "char" events.
|
||||
require "cc.internal.event".discard_char()
|
||||
break
|
||||
end
|
||||
elseif event == "mouse_scroll" then
|
||||
|
Loading…
x
Reference in New Issue
Block a user