tl
tl copied to clipboard
Cannot use semicolon after return statement
This is not a major bug, but rather a non-intuitive situation.
local function test()
return;
end -- return must be the last statement of its block
Some folks coming from the C world complained about this.
Looks like Lua actually allows this (return must be the last statement, but a single ; after it is allowed), so I think we should change our parser accordingly.
(cc @Frityet)
]lua5.3
Lua 5.3.6 Copyright (C) 1994-2020 Lua.org, PUC-Rio
> function f() ;; end
> function f() return; end
> function f() return;; end
stdin:1: 'end' expected near ';'
>
]lua5.1
Lua 5.1.5 Copyright (C) 1994-2012 Lua.org, PUC-Rio
> function f() ;; end
stdin:1: unexpected symbol near ';'
> function f() return; end
> function f() return;; end
stdin:1: 'end' expected near ';'
>
Lua 5.4 is the same as 5.3. Teal should have the same behavior as Lua 5.3/5.4 (and elide the empty ; command in the first test case when generating code with --gen-target=5.1).
EDIT: the Teal code generator does drop unnecessary semicolons in the output, so function() ;; end does generate Lua 5.1 compatible code.
Also, Teal versions up to and including 0.24.1 do not report errors.
Git bisect points to the commit 2d73d3fc1cae8519985736228ffd56d5eb152a87 (and the parent issue #495).
Personally, I don't depend on this issue, as I can just fix the script itself (and it will look better btw). So if fixing the bug requires a lot of effort, you are free to close this as a wontfix (and maybe describe this somewhere in the docs).
Yeah, I think what's most important about this is that we handle inputs and outputs consistently for different Lua targets.
Lua actually allows this (
returnmust be the last statement, but a single;after it is allowed)
LOL, and this is why I have a VIM register semi-permanently housing a copy of
if true then return end
...for use in forcing early returns during debugging.
For information and maybe some clarity on Lua 5.3 vs 5.1, from The evolution of Lua, continued:
We … took the opportunity to clarify the role of the semicolon as an optional statement separator, not terminator. For this, Lua 5.2 introduced the empty statement, which allows the programmer to separate statements with semicolons, start a block with a semicolon, or write multiple semicolons in sequence. The empty statement also helps to resolve ambiguity in statements starting with parentheses. As an example, consider the following fragment:
-- this is not an assignment followed by a function call! a = b (foo or goo)(a)As the syntax in Lua is free format, that code is equivalent to this fragment:
a = b(foo or goo)(a)We can fix this issue with an extra semicolon (an empty statement):
a = b ;(foo or goo)(a)As the unusual feature in this example is the statement starting with a parentheses, it is customary in Lua to place the semicolon there.
If I understand correctly, the first paragraph explains why return;; is not allowed: there is an implicit empty statement between the semicolons (and return must be the last statement).
Thanks for sharing @bjornbm !
As the unusual feature in this example is the statement starting with a parentheses
In Teal this is not as unusual, because of as casts, so we added explicit support for disambiguating the above via a newline, without the need for starting the line with an ; (IIRC, there was already some situation in the past where Lua broke the free format syntax with an explicit check for a newline, so there was some precedent.)
For this reason, in Teal that first example is an assignment followed by a function call, just like any reader would expect.
...for use in forcing early returns during debugging.
Honestly, I never understood why Lua enforces this rule about return. Maybe it's due to being an interpreted language without compile-time warnings?
Looks like Lua actually allows this (
returnmust be the last statement, but a single;after it is allowed), so I think we should change our parser accordingly.(cc @Frityet)
thx!!
Lua actually allows this (
returnmust be the last statement, but a single;after it is allowed)LOL, and this is why I have a VIM register semi-permanently housing a copy of
if true then return end
...for use in forcing early returns during debugging.
you can shorten this to
do return end