Lua parsing error
mustime opened this issue · 4 comments
Compiling the following code into bytecode:
local t = {}
function t:GetNumFromStr(strData, Substr: string)
local iSubLen = #Substr
local iCount = 0
local temp1 = strData
for i = 1, #strData, 1 do
local temp2 = string.sub(temp1, i, i + iSubLen - 1)
if temp2 == Substr then
i = i + iSubLen
iCount = iCount + 1
end
end
return iCount
end
and will end up with an error:
test.lua:11: Invalid assignment: integer expected near 'iCount'
However, if I change line: 4 to local iSubLen: integer = #Substr
, it will get passed.
So I wonder doesn't #
operation make iSubLen
an integer already? Why : integer
is needed.
hi
the # operator is not guaranteed to return an integer value as you can have meta method to override the behavior.
Although I suppose if operand is a string, unlikely to have a metamethod on it. Maybe in this case we could assert its an integer
Although I suppose if operand is a string, unlikely to have a metamethod on it. Maybe in this case we could assert its an integer
The #
operator is guaranteed to return integers for ravi-arrays and strings. There is already a case for that when parsing the length operator
Lines 1315 to 1319 in a6eeb86
but
Substr: string
allows Substr
to be a string or nil and nil can have a metamethod for the length operator.
Also, there is a bug in lcode.c:
--- a/src/lcode.c
+++ b/src/lcode.c
@@ -1391,7 +1391,7 @@ static void codebinexpval (FuncState *fs, OpCode op,
} \
e1->u.info = luaK_codeABC(fs, OP_##op, 0, rk1, rk2); \
if ((e1->ravi_type_map & (~(RAVI_TM_FLOAT | RAVI_TM_INTEGER))) == 0 && \
- (e1->ravi_type_map & (~(RAVI_TM_FLOAT | RAVI_TM_INTEGER))) == 0) { \
+ (e2->ravi_type_map & (~(RAVI_TM_FLOAT | RAVI_TM_INTEGER))) == 0) { \
if (e1->ravi_type_map & e2->ravi_type_map & RAVI_TM_INTEGER) { \
e1->ravi_type_map = RAVI_TM_FLOAT | ii; \
} \
@mustime I do not know what you do with i = i + iSubLen
as
for i = 1, 10 do
print(i)
i = i + 2
end
might not give the result you expected.
@mustime I do not know what you do with
i = i + iSubLen
asfor i = 1, 10 do print(i) i = i + 2 endmight not give the result you expected.
Well, the logic I list above had been stripped down and somehow pointless. Just try to explain the case. And it seems only happened within the for-statement.
To make this simpler, try the following code:
function foo(a, b)
local x = #b
for i = 1, #a, 1 do
i = i + x
end
end
And will get test.lua: 5: Invalid assignment: integer expected near 'end'