Log In  

This is a bug in 0.2.1b, and possibly earlier, causing crashes in BBS carts like Pieces of Cake. After the new add() functionality was added, complex or token-optimized code causes a hard crash with this error:

Note that having a space between these statements, as in "add(...) end", does not solve the parsing problem, but putting a newline between them sometimes does (no idea why). It's also possible that nested parentheses inside the add() call are messing up a regex parser, since this also consistently solves the crash:

local f=fn(sub(str,i,i),i)

As per @Felice, the bug is from an implied nil return from a function, which is apparently different than an explicit "return nil". add(t,nil) works, as should this (since it gets converted to a true nil through assignment):

function fn() end
local f=fn()

This fails:

P#79749 2020-07-22 05:10 ( Edited 2020-07-24 00:34)

It’s a runtime error, so it’s likely not related to the parser. My guess is that it’s a bug in the new C implementation of add().

P#79754 2020-07-22 08:01

My thought was that since the manual states add(t,v) is equivalent to t[#t+1] = v, it might be a macro replacement internally. The runtime error would then be because it's extracting the wrong values for t and v.

Also, I swear it fixed the runtime error once when I only adjusted whitespace around all of the add statements, though I can't reproduce that. That kind of weirdness outside of the function itself makes me think it's a parser bug.

P#79755 2020-07-22 08:10 ( Edited 2020-07-22 08:14)

It’s a runtime error :-) The 0.2.1 changelog states that add() is no longer implemented in Lua; it is only conceptually equivalent to t[#t+1]=v but internally it has always done more (such as handle type error) and since 0.2.1 does even more (it can now use a third argument).

P#79757 2020-07-22 10:10

Just because it states 'runtime error' doesn't guarantee that the issue happens there, only that it compiles something that eventually crashes on run. I'd like to hear your explanation of how outside whitespace and pulling function calls out of the passed arguments would affect the add function itself, regardless of where it's implemented. It could be double-executing fn() calls or extracting the wrong t v values (that just happen to still compile). Due to the solutions I've found for the crash, it's much more likely that something is going wrong pre-runtime.

P#79772 2020-07-22 21:03

@zep et al

It's failing because fn(...) is returning nil in this case (or maybe the special-case empty value for functions that don't explicitly return anything, which gets coerced to nil on assignment).

I think the original lua-mode add() allowed you to add nil. I imagine it behaved as a no-op. Probably the C-mode version ought to do the same.

P#79788 2020-07-23 01:12 ( Edited 2020-07-23 01:20)

Ah, yup, the empty value is the problem.

Works fine if the function returns nil:

But fails if the function doesn't return anything:

The C-mode code just needs to handle the special empty value as if it were nil.

@zep, you probably want to check any other C-ified functions for similar issues.

P#79789 2020-07-23 01:21 ( Edited 2020-07-23 06:12)

@shy because we know what exact transformations the PICO-8 parser operates on a given chunk of code (to replace != with ~=, for instance), and add() is not affected by these. The fact that it suddenly worked when you changed whitespace but never worked again can be better explained by some randomness in the code that prevented the runtime error, or by user error.

P#79807 2020-07-23 13:10

Thanks @Felice, I updated the top post and title to be more specific, so @zep can see what really went wrong here. More info here, I had no idea that lua treated "return nil" and "return" as different. Apparently it takes advantage of the fact that assignments with a mismatched # of arguments on LHS and RHS assign nil in the rest, so it doesn't actually return anything or push a value to the stack, even when a value is expected. That's quite a bizarre edge case.

@samhocevar: The whitespace fix probably was user error, I likely pulled the function call out just so it was visible in pico8's code editor, and then forgot when I tried to reproduce. However, the bug here was more about what got passed to add than about the add function's implementation itself, so I'd still say it was important to make that distinction.

P#79824 2020-07-24 00:25 ( Edited 2020-07-24 00:31)

Thanks everyone -- fixed for 0.2.1c, and also in the current BBS player (0.2.1c dev)

This was indeed caused by re-implementing add() in C, and was supposed to match the existing behaviour. Calling add() with no second parameter now does nothing, and returns nothing -- same as earlier versions.

P#80037 2020-07-28 17:03

[Please log in to post a comment]