Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

annotation allowed in generic for statement #701

Closed
fperrad opened this issue Sep 23, 2023 · 1 comment
Closed

annotation allowed in generic for statement #701

fperrad opened this issue Sep 23, 2023 · 1 comment
Labels
bug Something isn't working

Comments

@fperrad
Copy link
Contributor

fperrad commented Sep 23, 2023

The following code runs with tl:

for k <const>, v <const> in pairs(table as {string:any}) do
    print(k, v)
end

It looks like a bug (as not expected by docs/grammar.md).

Now, the reference manual for Lua 5.3 gives some equivalent code of for statement (in section https://www.lua.org/manual/5.3/manual.html#3.3.5)

  -- for v = e1, e2, e3 do block end

  do
    local var, limit, step = tonumber(e1), tonumber(e2), tonumber(e3)
    if not (var and limit and step) then error() end
    var = var - step
    while true do
      var = var + step
      if (step >= 0 and var > limit) or (step < 0 and var < limit) then
        break
      end
      local v = var
      block
    end
  end
  -- for var_1, ···, var_n in explist do block end

  do
    local f, s, var = explist
    while true do
      local var_1, ···, var_n = f(s, var)
      if var_1 == nil then break end
      var = var_1
      block
    end
  end

These pseudo codes were removed of the reference manual for Lua 5.4.
The reference manual 5.4 (which introduces the <const> annotation) says:

You should not change the value of the control variable during the loop.

But, you could do it in any version of Lua:

$ cat fornum.lua 
for i = 1, 2 do
     i = 9
     print(i)
end
$ lua5.1 fornum.lua 
9
9
$ lua5.2 fornum.lua 
9
9
$ lua5.3 fornum.lua 
9
9
$ lua5.4 fornum.lua 
9
9
$ tl run fornum.lua 
9
9

As it is a bad/insane practice, Teal must prevent it by handling the control variable as a <const> one.

  -- for v = e1, e2, e3 do block end
  -- v is implicitly <const>

  do
    local var, limit, step = tonumber(e1), tonumber(e2), tonumber(e3)
    if not (var and limit and step) then error() end
    var = var - step
    while true do
      var = var + step
      if (step >= 0 and var > limit) or (step < 0 and var < limit) then
        break
      end
      local v <const> = var
      block
    end
  end
  -- for var_1, ···, var_n in explist do block end
  -- var_1 is implicitly <const>

  do
    local f, s, var = explist
    while true do
      local var_1 <const>, ···, var_n = f(s, var)
      if var_1 == nil then break end
      var = var_1
      block
    end
  end
@hishamhm
Copy link
Member

I added the parser fix, but didn't force <const> on the variables.

@hishamhm hishamhm added the bug Something isn't working label Oct 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants