I don't think anything ought to change, but I thought this was interesting. Pico-8 allows this:
x = 1 if (x == 1) do print('a') end if (x == 2) do print('b') end |
Notice that this is not "if-then-end" but "if-do-end". This appears to be supported accidentally due to the "if (...) ..." shortcut, described in the manual as:
IF THEN END statements on a single line can be expressed without the THEN & END IF (NOT B) I=1 J=2 -- is equivalent to: IF (NOT B) THEN I=1 J=2 END -- note that the condition must be surrounded by brackets. |
The intent is for "if (cond) exp..." to parse expressions to the end of the line. However, if the last expression is a do-end block, the block is allowed to span multiple lines. Of course, this requires that the condition be in parentheses.
I found 7 carts posted to the BBS that use "if-do-end" across multiple lines. Pico-8 does what's intended, so it's hard to call it a mistake.
Unrelated: "if (cond) block else block" is undocumented but supported. "if (cond) block elseif (code) block else block" is not supported. The else's block is optional (though pointless to omit): "if (cond) block else" I found 13 carts using the else form of short-if.
Hi! I’m digging up this old post because I think it’s actually a mistake. It’s not only “if-do-end” that is allowed, but also “for”, “while”, etc. and unfortunately most of them do not behave properly.
The interpreter allows this, but the inner block is only executed once and the loop variable is unavailable inside the do/end:
if (true) for i=1,10 do print("Hello") end |
This is also allowed but the interpreter goes into an infinite loop and the inner block is never executed:
x = 0 if (true) while x < 10 do print("Hello") x = x + 1 end |
I believe that what is happening is some kind of naïve text replacement which adds “then” and “end” inside the code.
So the above snippets are replaced with:
if (true) then for i=1,10 do end print("Hello") end |
And:
x = 0 if (true) then while x < 10 do end print("Hello") x = x + 1 end |
Which explains both behaviours: there is an “end” keyword that prematurely ends the loop.
Which just goes to show, monkey proof your code guys. I've been told I'm a terrible programmer cause I'm always running and checking to see how everything looks every 2-minutes or so.
But at the same token this method really cuts down on difficult-to-find errors later, so I think it is a benefit.
That’s exactly a situation where “monkey-proofing” causes wrong assumptions to be made. The conclusion here was “if the last expression is a do-end block, the block is allowed to span multiple lines”, which as it happens is not true: the do-end block is actually closed prematurely as in this example:
x = 0 if (true) do local x = 1 print(x) -- prints 0 end x = 0 if (true) do local x = 1 print(x) -- prints 1 end |
Writing code so your program runs better (I.E. Monkeyproofing or implementing Poka Yoke) does not sound negative to me, Sam. :)
Oh, then I’m not sure I understood your answer, sorry. Did you mean that it was PICO-8 that needed more monkeyproofing, rather than our code?
Well spotted samhocevar, I'm glad you took a closer look.
My interest was in adding the Pico-8 extra features to picotool's Lua parser, and I did so prior to understanding that the extra features were added as a preprocessor step. My implementation adds them directly to the language grammar. I saw "if (cond) do" in a bunch of carts and assumed this was just unusual syntax that slipped in and started getting used.
For what it's worth, "if (cond) do\n...end" does work as expected fitting your explanation that transforms the line: "if (cond) then do end\n...end" Your counterexample with more statements after the "do" on the first line is illustrative of the error.
I agree this should be fixed with a breaking change prior to 1.0b.
I took a grammar approach for my tools, too, which means I cannot properly emulate this “feature” :-)
If it might be of interest to you, I made a unit test cartridge for the language extensions. For now it doesn’t run in PICO-8 because of several issues which I believe were all reported.
[Please log in to post a comment]