cluna 1.1.0

Tool to convert Lua code into Clue code Made by MarkosTh09
Documentation
-- $Id: testes/goto.lua $
-- See Copyright Notice in file all.lua

collectgarbage()

local function errmsg(code, m)
  local st, msg = load(code)
  assert(not st and string.find(msg, m))
end

-- cannot see label inside block
errmsg([[ goto l1; do ::l1:: end ]], "label 'l1'")
errmsg([[ do ::l1:: end goto l1; ]], "label 'l1'")

-- repeated label
errmsg([[ ::l1:: ::l1:: ]], "label 'l1'")
errmsg([[ ::l1:: do ::l1:: end]], "label 'l1'")


-- undefined label
errmsg([[ goto l1; local aa ::l1:: ::l2:: print(3) ]], "local 'aa'")

-- jumping over variable definition
errmsg([[
do local bb, cc;  end
local aa
 print(3)
]], "local 'aa'")

-- jumping into a block
errmsg([[ do ::l1:: end goto l1 ]], "label 'l1'")
errmsg([[ goto l1 do ::l1:: end ]], "label 'l1'")

-- cannot continue a repeat-until with variables
errmsg([[
  repeat
    if x then  end
    local xuxu = 10

  until xuxu < x
]], "local 'xuxu'")

-- simple gotos
local x
do
  local y = 12

  x = x + 1;
  x = y;
end
assert(x == 13)


-- long labels
do
  local prog = [[
  do
    local a = 1
     a = a + 1
    a = a + 10
     a = a + 2
    a = a + 20
    return a
  end
  ]]
  local label = string.rep("0123456789", 40)
  prog = string.format(prog, label, label, label, label)
  assert(assert(load(prog))() == 31)
end


-- ok to jump over local dec. to end of block
do
  local a = 23
  x = a
  ;
end

while true do
  -- ok to jump over local dec. to end of block
  -- multiple uses of same label
  local x = 45
  ;;;
end
assert(x == 13)

if print then
  -- ok to jump over local dec. to end of block
  error("should not be here")
  -- ok to jump over local dec. to end of block
  local x
  ;;;
else
end

-- to repeat a label in a different function is OK
local function foo()
  local a = {}

  a[#a + 1] = 1;
  a[#a + 1] = 2;

  a[#a + 1] = 3;
  a[#a + 1] = 4;
  a[#a + 1] = 5;
  assert(a[1] == 3 and a[2] == 1 and a[3] == 2 and
    a[4] == 5 and a[5] == 4)
  if not a[6] then a[6] = true; end  -- do it twice
end

foo()


do -- bug in 5.2 -> 5.3.2
  local x

  local y -- cannot join this SETNIL with previous one
  assert(y == nil)
  y = true
  if x == nil then
    x = 1
  else
    x = x + 1
  end
  assert(x == 2 and y == true)
end

-- bug in 5.3
do
  local first = true
  local a = false
  if true then
    a = true

    if first then
      first = false
    end
  end
  assert(a)
end

do -- compiling infinite loops
  -- do not run the infinite loops
end

--------------------------------------------------------------------------------
-- testing closing of upvalues

local debug = require 'debug'

local function foo()
  local t = {}
  do
    local i = 1
    local a, b, c, d
    t[1] = function() return a, b, c, d end

    local b
    do
      local c
      t[#t + 1] = function() return a, b, c, d end -- t[2], t[4], t[6]
      if i > 2 then end
      do
        local d
        t[#t + 1] = function() return a, b, c, d end -- t[3], t[5]
        i = i + 1
        local a
      end
    end
  end
  return t
end

local a = foo()
assert(#a == 6)

-- all functions share same 'a'
for i = 2, 6 do
  assert(debug.upvalueid(a[1], 1) == debug.upvalueid(a[i], 1))
end

-- 'b' and 'c' are shared among some of them
for i = 2, 6 do
  -- only a[1] uses external 'b'/'b'
  assert(debug.upvalueid(a[1], 2) ~= debug.upvalueid(a[i], 2))
  assert(debug.upvalueid(a[1], 3) ~= debug.upvalueid(a[i], 3))
end

for i = 3, 5, 2 do
  -- inner functions share 'b'/'c' with previous ones
  assert(debug.upvalueid(a[i], 2) == debug.upvalueid(a[i - 1], 2))
  assert(debug.upvalueid(a[i], 3) == debug.upvalueid(a[i - 1], 3))
  -- but not with next ones
  assert(debug.upvalueid(a[i], 2) ~= debug.upvalueid(a[i + 1], 2))
  assert(debug.upvalueid(a[i], 3) ~= debug.upvalueid(a[i + 1], 3))
end

-- only external 'd' is shared
for i = 2, 6, 2 do
  assert(debug.upvalueid(a[1], 4) == debug.upvalueid(a[i], 4))
end

-- internal 'd's are all different
for i = 3, 5, 2 do
  for j = 1, 6 do
    assert((debug.upvalueid(a[i], 4) == debug.upvalueid(a[j], 4))
      == (i == j))
  end
end

--------------------------------------------------------------------------------
-- testing if x

local function testG(a)
  if a == 1 then
    error("should never be here!")
  elseif a == 2 then
  elseif a == 3 then
  elseif a == 4 then
    -- go to inside the block
    error("should never be here!")
    a = a + 1  -- must go to 'if' end
  else
    a = a * 2;
    error("should never be here!")

    error("should never be here!")
  end
  do return a end
  do return "2" end
  do return "3" end
  return "1"
end

assert(testG(1) == "1")
assert(testG(2) == "2")
assert(testG(3) == "3")
assert(testG(4) == 5)
assert(testG(5) == 10)

do
  -- if x back goto out of scope of upvalue
  local X




  do
    local a <close> = setmetatable({}, { __close = function() X = true end })
    assert(X == nil)
    if a then end  -- jumping back out of scope of 'a'
  end

  assert(X == true)  -- checks that 'a' was correctly closed
end
--------------------------------------------------------------------------------


print 'OK'