vararg.lua 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. -- $Id: testes/vararg.lua $
  2. -- See Copyright Notice in file lua.h
  3. print('testing vararg')
  4. local function f (a, ...t)
  5. local x = {n = select('#', ...), ...}
  6. assert(x.n == t.n)
  7. for i = 1, x.n do
  8. assert(a[i] == x[i] and x[i] == t[i])
  9. end
  10. return x.n
  11. end
  12. local function c12 (...)
  13. assert(arg == _G.arg) -- no local 'arg'
  14. local x = {...}; x.n = #x
  15. local res = (x.n==2 and x[1] == 1 and x[2] == 2)
  16. if res then res = 55 end
  17. return res, 2
  18. end
  19. local function vararg (... t) return t end
  20. local call = function (f, args) return f(table.unpack(args, 1, args.n)) end
  21. assert(f() == 0)
  22. assert(f({1,2,3}, 1, 2, 3) == 3)
  23. assert(f({"alo", nil, 45, f, nil}, "alo", nil, 45, f, nil) == 5)
  24. assert(vararg().n == 0)
  25. assert(vararg(nil, nil).n == 2)
  26. assert(c12(1,2)==55)
  27. local a,b = assert(call(c12, {1,2}))
  28. assert(a == 55 and b == 2)
  29. a = call(c12, {1,2;n=2})
  30. assert(a == 55 and b == 2)
  31. a = call(c12, {1,2;n=1})
  32. assert(not a)
  33. assert(c12(1,2,3) == false)
  34. local a = vararg(call(next, {_G,nil;n=2}))
  35. local b,c = next(_G)
  36. assert(a[1] == b and a[2] == c and a.n == 2)
  37. a = vararg(call(call, {c12, {1,2}}))
  38. assert(a.n == 2 and a[1] == 55 and a[2] == 2)
  39. a = call(print, {'+'})
  40. assert(a == nil)
  41. local t = {1, 10}
  42. function t:f (...) local arg = {...}; return self[...]+#arg end
  43. assert(t:f(1,4) == 3 and t:f(2) == 11)
  44. print('+')
  45. local lim = 20
  46. local i, a = 1, {}
  47. while i <= lim do a[i] = i+0.3; i=i+1 end
  48. function f(a, b, c, d, ...)
  49. local more = {...}
  50. assert(a == 1.3 and more[1] == 5.3 and
  51. more[lim-4] == lim+0.3 and not more[lim-3])
  52. end
  53. local function g (a,b,c)
  54. assert(a == 1.3 and b == 2.3 and c == 3.3)
  55. end
  56. call(f, a)
  57. call(g, a)
  58. a = {}
  59. i = 1
  60. while i <= lim do a[i] = i; i=i+1 end
  61. assert(call(math.max, a) == lim)
  62. print("+")
  63. -- new-style varargs
  64. local function oneless (a, ...) return ... end
  65. function f (n, a, ...)
  66. local b
  67. assert(arg == _G.arg) -- no local 'arg'
  68. if n == 0 then
  69. local b, c, d = ...
  70. return a, b, c, d, oneless(oneless(oneless(...)))
  71. else
  72. n, b, a = n-1, ..., a
  73. assert(b == ...)
  74. return f(n, a, ...)
  75. end
  76. end
  77. a,b,c,d,e = assert(f(10,5,4,3,2,1))
  78. assert(a==5 and b==4 and c==3 and d==2 and e==1)
  79. a,b,c,d,e = f(4)
  80. assert(a==nil and b==nil and c==nil and d==nil and e==nil)
  81. -- varargs for main chunks
  82. local f = assert(load[[ return {...} ]])
  83. local x = f(2,3)
  84. assert(x[1] == 2 and x[2] == 3 and x[3] == undef)
  85. f = load[[
  86. local x = {...}
  87. for i=1,select('#', ...) do assert(x[i] == select(i, ...)) end
  88. assert(x[select('#', ...)+1] == undef)
  89. return true
  90. ]]
  91. assert(f("a", "b", nil, {}, assert))
  92. assert(f())
  93. a = {select(3, table.unpack{10,20,30,40})}
  94. assert(#a == 2 and a[1] == 30 and a[2] == 40)
  95. a = {select(1)}
  96. assert(next(a) == nil)
  97. a = {select(-1, 3, 5, 7)}
  98. assert(a[1] == 7 and a[2] == undef)
  99. a = {select(-2, 3, 5, 7)}
  100. assert(a[1] == 5 and a[2] == 7 and a[3] == undef)
  101. pcall(select, 10000)
  102. pcall(select, -10000)
  103. -- bug in 5.2.2
  104. function f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
  105. p11, p12, p13, p14, p15, p16, p17, p18, p19, p20,
  106. p21, p22, p23, p24, p25, p26, p27, p28, p29, p30,
  107. p31, p32, p33, p34, p35, p36, p37, p38, p39, p40,
  108. p41, p42, p43, p44, p45, p46, p48, p49, p50, ...)
  109. local a1,a2,a3,a4,a5,a6,a7
  110. local a8,a9,a10,a11,a12,a13,a14
  111. end
  112. -- assertion fail here
  113. f()
  114. -- missing arguments in tail call
  115. do
  116. local function f(a,b,c) return c, b end
  117. local function g() return f(1,2) end
  118. local a, b = g()
  119. assert(a == nil and b == 2)
  120. end
  121. do -- vararg parameter used in nested functions
  122. local function foo (...tab1)
  123. return function (...tab2)
  124. return {tab1, tab2}
  125. end
  126. end
  127. local f = foo(10, 20, 30)
  128. local t = f("a", "b")
  129. assert(t[1].n == 3 and t[1][1] == 10)
  130. assert(t[2].n == 2 and t[2][1] == "a")
  131. end
  132. do -- vararg parameter is read-only
  133. local st, msg = load("return function (... t) t = 10 end")
  134. assert(string.find(msg, "const variable 't'"))
  135. local st, msg = load[[
  136. local function foo (...extra)
  137. return function (...) extra = nil end
  138. end
  139. ]]
  140. assert(string.find(msg, "const variable 'extra'"))
  141. end
  142. do -- _ENV as vararg parameter
  143. local st, msg = load[[
  144. local function aux (... _ENV)
  145. global <const> a
  146. a = 10
  147. end ]]
  148. assert(string.find(msg, "const variable 'a'"))
  149. local function aux (..._ENV)
  150. global a; a = 10
  151. return a
  152. end
  153. assert(aux() == 10)
  154. local function aux (... _ENV)
  155. global a = 10
  156. return a
  157. end
  158. assert(aux() == 10)
  159. end
  160. do -- access to vararg parameter
  161. local function notab (keys, t, ...v)
  162. for _, k in pairs(keys) do
  163. assert(t[k] == v[k])
  164. end
  165. assert(t.n == v.n)
  166. end
  167. local t = table.pack(10, 20, 30)
  168. local keys = {-1, 0, 1, t.n, t.n + 1, 1.0, 1.1, "n", print, "k", "1"}
  169. notab(keys, t, 10, 20, 30) -- ensure stack space
  170. local m = collectgarbage"count"
  171. notab(keys, t, 10, 20, 30)
  172. -- 'notab' does not create any table/object
  173. assert(m == collectgarbage"count")
  174. -- writing to the vararg table
  175. local function foo (...t)
  176. t[1] = t[1] + 10
  177. return t[1]
  178. end
  179. assert(foo(10, 30) == 20)
  180. end
  181. print('OK')