Repository navigation
Conversation
… %s, gsub n
Differential testing against real Lua exposed four output-layer
divergences (semantics verified against Lua 5.4.6 sources:
lobject.c::tostringbuff and lstrlib.c str_format/str_gsub):
- float tostring used %.17g (interp/JIT concat) and std::format/
std::to_string elsewhere, and never appended the Lua '.0' suffix:
tostring(1.0) -> "1", so tonumber(tostring(1.0)) silently became an
integer. Add FormatLuaFloat (%.14g + '.0' when the result contains
only sign/digits, matching Lua's strspn check) and route every Lua
value->string path through it: Var::ToString (tostring/print/natives),
interp BinConcat, table.concat, log, and FlVarToStr in the JIT C
runtime header (C89-compatible for TCC). Serialization formats
(json/xml/csv/ini) are intentionally left unchanged.
- print quoted its string arguments (ToString defaults to has_quote=true);
call ToString(false, false) so print(x) equals print(tostring(x)).
- string.format("%s", x) rejected booleans and formatted floats with
std::to_string (fixed 6 decimals, 2.5 -> "2.500000"). %s is defined as
luaL_tolstring: string/number/boolean/nil are valid and formatted via
tostring; only tables without __tostring still raise. Replace the
incorrect bool-must-error regression with test_format_s_types.lua.
- gsub(s, p, r, n) treated any negative n as unlimited. Lua defaults the
missing/nil argument to srcl+1 and loops while n < max_s, so an
explicit negative or zero performs zero replacements. Use srcl+1 as
the default, honor explicit nil, and drop the negative escape hatch.
Also fix a backend inconsistency surfaced by the new assertions: the
interp compiled -0.0 as +0.0. ClassifyConstNumberExp normalizes 0.0 to
an integer zero for table keys, but in value context rebuilding the
double dropped the sign. Add ConstNumberExpToDouble, which restores
+-0.0 by the parity of nested unary minuses, shared by all three value
construction sites (CGen and both interp codegen paths); table-key
normalization is unaffected. 1/-0.0 is now -inf on all backends.
Tests: extend test_basic_tostring_cases with exact assertions
(1.0/-0.0/0.1/1e20/inf/nan, concat, math.type round-trip, table.concat),
add test_gsub_negative_n, update the var.ToString assertion
(12345.0 -> "12345.0"); all three JIT backends, 1491 tests pass.
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #26 +/- ##
==========================================
+ Coverage 88.04% 88.07% +0.03%
==========================================
Files 123 124 +1
Lines 25216 25234 +18
==========================================
+ Hits 22201 22225 +24
+ Misses 3015 3009 -6 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
与真实 Lua 5.4 的差分测试发现 4 个输出层语义差异。语义均对照 Lua 5.4.6 官方源码核实(
lobject.c::tostringbuff、lstrlib.c的str_format/str_gsub)。修改内容
%.17g/std::format/std::to_string,且从不补 Lua 的.0后缀——tostring(1.0)得到"1",导致tonumber(tostring(1.0))静默变成 integer。新增统一的
FormatLuaFloat(%.14g,结果只含符号和数字时补.0,等价 Lua 的 strspn 判定),覆盖全部 Lua 值→字符串路径:Var::ToString(tostring/print/native)、interpBinConcat、table.concat、log,以及 JIT C 运行时头里的FlVarToStr(TCC 按 C89 兼容写法)。json/xml/csv/ini 等序列化格式刻意不改。ToString(false, false),使print(x)与print(tostring(x))一致。string.format("%s", x)对齐luaL_tolstring:bool/nil/number 均合法并走 tostring(此前 bool 报错、float 固定 6 位小数2.5→"2.500000");仅 table(无__tostring)仍报错。gsub(s,p,r,n)负数 n:此前任何负数都被当作不限次数。Lua 缺省/nil 时默认srcl+1,循环条件n < max_s,因此显式负数或 0 表示 0 次替换。连带修复
新断言暴露出 interp 后端把
-0.0编成+0.0(JIT 为-0.0)。根因:ClassifyConstNumberExp为表键把0.0归一化成 int 0,值语境重建 double 时丢了负号。新增ConstNumberExpToDouble,按嵌套一元负号层数奇偶还原 ±0.0,三处值构造点(CGen + interp 两处)共用;表键归一化不受影响。修复后三后端1/-0.0均为-inf。测试
test_basic_tostring_cases:精确断言1.0/-0.0/0.1/1e20/inf/nan、字符串拼接、math.type往返、table.concattest_format_s_types、test_gsub_negative_n(CallAll覆盖 TCC/GCC/interp 三后端)test_format_s_bad_arg(它错误地期望 bool 必须报错)var.ToString断言(12345.0 → "12345.0")备注
assignment of read-only locationwarning(可变参 native 调用嵌套)在 master 上原本就存在,不在本 PR 范围