on master help sign in
wip
commit9b0ba75640e741a9d82452e9e04cc4933b72dd8b authoriko <mail@iko.soy> dateSat 27 Jul 2024, 17:18 (2 years ago) parent2ba97e9
37 files changed+15460−4
zod/luau/lib/lua/parser.hoon+1−1 zod/luau/lib/lua/printer.hoon+2 zod/luau/res/lua/cycled/all.lua+214 zod/luau/res/lua/cycled/api.lua+1296 zod/luau/res/lua/cycled/attrib.lua+430 zod/luau/res/lua/cycled/big.lua+69 zod/luau/res/lua/cycled/bitwise.lua+307 zod/luau/res/lua/cycled/bwcoercion.lua+59 zod/luau/res/lua/cycled/calls.lua+483 zod/luau/res/lua/cycled/closure.lua+309 zod/luau/res/lua/cycled/code.lua+576 zod/luau/res/lua/cycled/constructs.lua+466 zod/luau/res/lua/cycled/coroutine.lua+1171 zod/luau/res/lua/cycled/cstack.lua+152 zod/luau/res/lua/cycled/db.lua+1009 zod/luau/res/lua/cycled/errors.lua+610 zod/luau/res/lua/cycled/events.lua+602 zod/luau/res/lua/cycled/files.lua+886 zod/luau/res/lua/cycled/foo.lua+75 zod/luau/res/lua/cycled/gc.lua+762 zod/luau/res/lua/cycled/gengc.lua+98 zod/luau/res/lua/cycled/goto.lua+262 zod/luau/res/lua/cycled/heavy.lua+132 zod/luau/res/lua/cycled/literals.lua+311 zod/luau/res/lua/cycled/locals.lua+987 zod/luau/res/lua/cycled/main.lua+447 zod/luau/res/lua/cycled/math.lua+831 zod/luau/res/lua/cycled/nextvar.lua+1024 zod/luau/res/lua/cycled/pm.lua+406 zod/luau/res/lua/cycled/sort.lua+301 zod/luau/res/lua/cycled/strings.lua+434 zod/luau/res/lua/cycled/tpack.lua+245 zod/luau/res/lua/cycled/tracegc.lua+24 zod/luau/res/lua/cycled/utf8.lua+195 zod/luau/res/lua/cycled/vararg.lua+137 zod/luau/res/lua/cycled/verybig.lua+120 zod/luau/ted/test-lua.hoon+27−3
zod/luau/lib/lua/parser.hoon+1−1
@@ -709,7 +709,7 @@ apex
709709++ parse-name
710710 =>
711711 |%
712− ++ name-char ;~(pose name-fst-char dit:ab)
712+ ++ name-char ;~(pose name-fst-char (shim '0' '9'))
713713 ++ name-fst-char ;~(pose alf:ab (just '_'))
714714 --
715715 %+ cook |= =tape (crip tape)
zod/luau/lib/lua/printer.hoon+2
@@ -55,6 +55,7 @@ print
5555 ==
5656:: string
5757::
58+:: NOTE: does not handle escaping chars
5859++ print-string
5960 |= =string
6061 %- zing
@@ -240,6 +241,7 @@ print
240241 :~
241242 "local "
242243 (print-attnamelist attnamelist.local-asmnt)
244+ " = "
243245 ?~ rhs.local-asmnt "" (print-explist u.rhs.local-asmnt)
244246 ==
245247:: attnamelist
zod/luau/res/lua/cycled/all.luanew file+214
@@ -0,0 +1,214 @@
1+local version = "Lua 5.4"
2+if _VERSION ~= version then
3+io.stderr:write("This test suite is for ",version,", not for ",_VERSION,"
4+Exiting tests")
5+return
6+end
7+_G.ARG=arg
8+_soft=rawget(_G,"_soft") or false
9+_port=rawget(_G,"_port") or false
10+_nomsg=rawget(_G,"_nomsg") or false
11+local usertests = rawget(_G,"_U")
12+if usertests then
13+_soft=true
14+_port=true
15+_nomsg=true
16+end
17+debug=nil
18+if usertests then
19+T=nil
20+else
21+T=rawget(_G,"T")
22+end
23+print("
24+ Starting Tests")
25+local random_x,random_y = math.randomseed()
26+print(string.format("random seeds: %d, %d",random_x,random_y))
27+print("current path:
28+****" .. package.path .. "****
29+")
30+local initclock = os.clock()
31+local lastclock = initclock
32+local walltime = os.time()
33+local collectgarbage = collectgarbage
34+local msgs = {}
35+function Message(m)
36+if not _nomsg then
37+print(m)
38+msgs[# msgs + 1]=string.sub(m,3,- 3)
39+end
40+end
41+assert(os.setlocale("C"))
42+local T,print,format,write,assert,type,unpack,floor = T,print,string.format,io.write,assert,type,table.unpack,math.floor
43+local function F
44+(m)
45+local function round
46+(m)
47+m=m + 0.04999
48+return format("%.1f",m)
49+end
50+if m < 1e3 then
51+return m
52+else
53+m=m / 1e3
54+if m < 1e3 then
55+return round(m) .. "K"
56+else
57+return round(m / 1e3) .. "M"
58+end
59+end
60+end
61+local Cstacklevel =
62+local showmem =
63+if not T then
64+local max = 0
65+showmem=()
66+local m = collectgarbage("count") * 1024
67+max=(m > max) and m or max
68+print(format(" ---- total memory: %s, max memory: %s ----
69+",F(m),F(max)))
70+end
71+Cstacklevel=()
72+return 0
73+end
74+else
75+showmem=()
76+T.checkmemory()
77+local total,numblocks,maxmem = T.totalmem()
78+local count = collectgarbage("count")
79+print(format("
80+ ---- total memory: %s (%.0fK), max use: %s, blocks: %d
81+",F(total),count,F(maxmem),numblocks))
82+print(format(" (strings: %d, tables: %d, functions: %d, " .. "
83+ udata: %d, threads: %d)",T.totalmem("string"),T.totalmem("table"),T.totalmem("function"),T.totalmem("userdata"),T.totalmem("thread")))
84+end
85+Cstacklevel=()
86+local _,_,ncalls = T.stacklevel()
87+return ncalls
88+end
89+end
90+local Cstack = Cstacklevel()
91+local function report
92+(n)
93+print("
94+***** FILE '" .. n .. "'*****")
95+end
96+local olddofile = dofile
97+local dofile = (n,strip)
98+showmem()
99+local c = os.clock()
100+print(string.format("time: %g (+%g)",c - initclock,c - lastclock))
101+lastclock=c
102+report(n)
103+local f = assert(loadfile(n))
104+local b = string.dump(f,strip)
105+f=assert(load(b))
106+return f()
107+end
108+dofile("main.lua")
109+require("tracegc").start()
110+report("gc.lua")
111+local f = assert(loadfile("gc.lua"))
112+f()
113+dofile("db.lua")
114+assert(dofile("calls.lua") == deep and deep)
115+_G.deep=nil
116+olddofile("strings.lua")
117+olddofile("literals.lua")
118+dofile("tpack.lua")
119+assert(dofile("attrib.lua") == 27)
120+dofile("gengc.lua")
121+assert(dofile("locals.lua") == 5)
122+dofile("constructs.lua")
123+dofile("code.lua",true)
124+if not _G._soft then
125+report("big.lua")
126+local f = coroutine.wrap(assert(loadfile("big.lua")))
127+assert(f() == "b")
128+assert(f() == "a")
129+end
130+dofile("cstack.lua")
131+dofile("nextvar.lua")
132+dofile("pm.lua")
133+dofile("utf8.lua")
134+dofile("api.lua")
135+assert(dofile("events.lua") == 12)
136+dofile("vararg.lua")
137+dofile("closure.lua")
138+dofile("coroutine.lua")
139+dofile("goto.lua",true)
140+dofile("errors.lua")
141+dofile("math.lua")
142+dofile("sort.lua",true)
143+dofile("bitwise.lua")
144+assert(dofile("verybig.lua",true) == 10)
145+;
146+collectgarbage()
147+dofile("files.lua")
148+if # msgs > 0 then
149+local m = table.concat(msgs,"
150+ ")
151+warn("#tests not performed:
152+ ",m,"
153+")
154+end
155+print("(there should be two warnings now)")
156+warn("@on")
157+warn("#This is ","an expected"," warning")
158+warn("@off")
159+warn("******** THIS WARNING SHOULD NOT APPEAR **********")
160+warn("******** THIS WARNING ALSO SHOULD NOT APPEAR **********")
161+warn("@on")
162+warn("#This is"," another one")
163+assert(debug == nil)
164+local debug = require("debug")
165+print(string.format("%d-bit integers, %d-bit floats",string.packsize("j") * 8,string.packsize("n") * 8))
166+debug.sethook((a)
167+assert(type(a) == "string")
168+end,"cr")
169+_G.showmem=showmem
170+assert(Cstack == Cstacklevel(),"should be at the same C-stack level it was when started the tests")
171+local _G,showmem,print,format,clock,time,difftime,assert,open,warn = _G,showmem,print,string.format,os.clock,os.time,os.difftime,assert,io.open,warn
172+local fname = T and "time-debug.txt" or "time.txt"
173+local lasttime =
174+if not usertests then
175+local f = io.open(fname)
176+if f then
177+lasttime=assert(tonumber(f:read("a")))
178+f:close()
179+;
180+else
181+lasttime=nil
182+end
183+end
184+print("cleaning all!!!!")
185+for n in pairs(_G)
186+do
187+if not ({["___Glob"] = 1,["tostring"] = 1})[n] then
188+_G[n]=undef
189+end
190+end
191+collectgarbage()
192+collectgarbage()
193+collectgarbage()
194+collectgarbage()
195+collectgarbage()
196+collectgarbage()
197+;
198+showmem()
199+local clocktime = clock() - initclock
200+walltime=difftime(time(),walltime)
201+print(format("
202+
203+total time: %.2fs (wall time: %gs)
204+",clocktime,walltime))
205+if not usertests then
206+lasttime=lasttime or clocktime
207+local diff = (clocktime - lasttime) / lasttime
208+local tolerance = 0.05
209+if (diff >= tolerance or diff <= - tolerance) then
210+warn(format("#time difference from previous test: %+.1f%%",diff * 100))
211+end
212+assert(open(fname,"w")):write(clocktime):close()
213+end
214+print("final OK !!!")
zod/luau/res/lua/cycled/api.luanew file+1296
@@ -0,0 +1,1296 @@
1+if T == nil then
2+(Message or print)("
3+ >>> testC not active: skipping API tests <<<
4+")
5+return
6+end
7+local debug = require("debug")
8+local pack = table.pack
9+local MEMERRMSG = "not enough memory"
10+local function tcheck
11+(t1,t2)
12+assert(t1.n == (t2.n or # t2) + 1)
13+for i = 2, t1.n
14+do
15+assert(t1[i] == t2[i - 1])
16+end
17+end
18+local function checkerr
19+(msg,f, ...)
20+local stat,err = pcall(f,...)
21+assert(not stat and string.find(err,msg))
22+end
23+print("testing C API")
24+local a = T.testC("pushvalue R; return 1")
25+assert(a == debug.getregistry())
26+assert(T.testC("settop 10; absindex -1; return 1") == 10)
27+assert(T.testC("settop 5; absindex -5; return 1") == 1)
28+assert(T.testC("settop 10; absindex 1; return 1") == 1)
29+assert(T.testC("settop 10; absindex R; return 1") < - 10)
30+a=T.d2s(12458954321123)
31+assert(a == string.pack("d",12458954321123))
32+assert(T.s2d(a) == 12458954321123)
33+local a,b,c = T.testC("pushnum 1; pushnum 2; pushnum 3; return 2")
34+assert(a == 2 and b == 3 and not c)
35+local f = T.makeCfunc("pushnum 1; pushnum 2; pushnum 3; return 2")
36+a,b,c=f()
37+assert(a == 2 and b == 3 and not c)
38+a,b,c=T.testC("pushbool 1; pushbool 2; pushbool 0; return 3")
39+assert(a == b and a == true and c == false)
40+a,b,c=T.testC("pushbool 0; pushbool 10; pushnil;
41+ tobool -3; tobool -3; tobool -3; return 3")
42+assert(a == false and b == true and c == false)
43+a,b,c=T.testC("gettop; return 2",10,20,30,40)
44+assert(a == 40 and b == 5 and not c)
45+local t = pack(T.testC("settop 5; return *",2,3))
46+tcheck(t,{["n"] = 4,2,3})
47+t=pack(T.testC("settop 0; settop 15; return 10",3,1,23))
48+assert(t.n == 10 and t[1] == nil and t[10] == nil)
49+t=pack(T.testC("remove -2; return *",2,3,4))
50+tcheck(t,{["n"] = 2,2,4})
51+t=pack(T.testC("insert -1; return *",2,3))
52+tcheck(t,{["n"] = 2,2,3})
53+t=pack(T.testC("insert 3; return *",2,3,4,5))
54+tcheck(t,{["n"] = 4,2,5,3,4})
55+t=pack(T.testC("replace 2; return *",2,3,4,5))
56+tcheck(t,{["n"] = 3,5,3,4})
57+t=pack(T.testC("replace -2; return *",2,3,4,5))
58+tcheck(t,{["n"] = 3,2,3,5})
59+t=pack(T.testC("remove 3; return *",2,3,4,5))
60+tcheck(t,{["n"] = 3,2,4,5})
61+t=pack(T.testC("copy 3 4; return *",2,3,4,5))
62+tcheck(t,{["n"] = 4,2,3,3,5})
63+t=pack(T.testC("copy -3 -1; return *",2,3,4,5))
64+tcheck(t,{["n"] = 4,2,3,4,3})
65+local t = {10,20,30,40,50,60}
66+for i = - 6, 6
67+do
68+local s = string.format("rotate 2 %d; return 7",i)
69+local t1 = pack(T.testC(s,10,20,30,40,50,60))
70+tcheck(t1,t)
71+table.insert(t,1,table.remove(t))
72+end
73+t=pack(T.testC("rotate -2 1; return *",10,20,30,40))
74+tcheck(t,{10,20,40,30})
75+t=pack(T.testC("rotate -2 -1; return *",10,20,30,40))
76+tcheck(t,{10,20,40,30})
77+t=pack(T.testC("rotate -1 0; return *",10,20,30,40))
78+tcheck(t,{10,20,30,40})
79+t=pack(T.testC("rotate -1 1; return *",10,20,30,40))
80+tcheck(t,{10,20,30,40})
81+t=pack(T.testC("rotate 5 -1; return *",10,20,30,40))
82+tcheck(t,{10,20,30,40})
83+T.testC(" warningC "#This shold be a"
84+ warningC " single "
85+ warning "warning"
86+ warningC "#This should be "
87+ warning "another one"
88+")
89+local f = T.makeCfunc(" getglobal error
90+ pushstring bola
91+ pcall 1 1 1 # call 'error' with given handler
92+ pushstatus
93+ return 2 # return error message and status
94+ ")
95+local msg,st = f(string.upper)
96+assert(st == "ERRRUN" and msg == "BOLA")
97+local msg,st = f(string.len)
98+assert(st == "ERRRUN" and msg == 4)
99+t=pack(T.testC("insert 3; pushvalue 3; remove 3; pushvalue 2; remove 2;
100+ insert 2; pushvalue 1; remove 1; insert 1;
101+ insert -2; pushvalue -2; remove -3; return *",2,3,4,5,10,40,90))
102+tcheck(t,{["n"] = 7,2,3,4,5,10,40,90})
103+t=pack(T.testC("concat 5; return *","alo",2,3,"joao",12))
104+tcheck(t,{["n"] = 1,"alo23joao12"})
105+t=pack(T.testC("call 2,-1; return *",(a,b)
106+return 1,2,3,4,a,b
107+end,"alo","joao"))
108+tcheck(t,{["n"] = 6,1,2,3,4,"alo","joao"})
109+local a = {}
110+for i = 1, 1e3
111+do
112+a[i]=true
113+end
114+;
115+a[999]=10
116+local b = T.testC("pcall 1 -1 0; pop 1; tostring -1; return 1",table.unpack,a)
117+assert(b == "10")
118+_G.AA=14
119+;
120+_G.BB="a31"
121+local a = {T.testC(" getglobal AA;
122+ getglobal BB;
123+ getglobal BB;
124+ setglobal AA;
125+ return *
126+")}
127+assert(a[2] == 14 and a[3] == "a31" and a[4] == nil and _G.AA == "a31")
128+_G.AA,_G.BB=nil
129+assert(T.testC("pushnum 10; pushnum 20; arith /; return 1") == 0.5)
130+assert(T.testC("pushnum 10; pushnum 20; arith -; return 1") == - 10)
131+assert(T.testC("pushnum 10; pushnum -20; arith *; return 1") == - 200)
132+assert(T.testC("pushnum 10; pushnum 3; arith ^; return 1") == 1e3)
133+assert(T.testC("pushnum 10; pushstring 20; arith /; return 1") == 0.5)
134+assert(T.testC("pushstring 10; pushnum 20; arith -; return 1") == - 10)
135+assert(T.testC("pushstring 10; pushstring -20; arith *; return 1") == - 200)
136+assert(T.testC("pushstring 10; pushstring 3; arith ^; return 1") == 1e3)
137+assert(T.testC("arith /; return 1",2,0) == 10 / 0)
138+a=T.testC("pushnum 10; pushint 3; arith \; return 1")
139+assert(a == 3 and math.type(a) == "float")
140+a=T.testC("pushint 10; pushint 3; arith \; return 1")
141+assert(a == 3 and math.type(a) == "integer")
142+a=assert(T.testC("pushint 10; pushint 3; arith +; return 1"))
143+assert(a == 13 and math.type(a) == "integer")
144+a=assert(T.testC("pushnum 10; pushint 3; arith +; return 1"))
145+assert(a == 13 and math.type(a) == "float")
146+a,b,c=T.testC("pushnum 1;
147+ pushstring 10; arith _;
148+ pushstring 5; return 3")
149+assert(a == 1 and b == - 10 and c == "5")
150+local mt = {["__add"] = (a,b)
151+return setmetatable({a[1] + b[1]},mt)
152+end,["__mod"] = (a,b)
153+return setmetatable({a[1] % b[1]},mt)
154+end,["__unm"] = (a)
155+return setmetatable({a[1] * 2},mt)
156+end}
157+a,b,c=setmetatable({4},mt),setmetatable({8},mt),setmetatable({- 3},mt)
158+local x,y,z = T.testC("arith +; return 2",10,a,b)
159+assert(x == 10 and y[1] == 12 and z == nil)
160+assert(T.testC("arith %; return 1",a,c)[1] == 4 % - 3)
161+assert(T.testC("arith _; arith +; arith %; return 1",b,a,c)[1] == 8 % (4 + (- 3) * 2))
162+checkerr("divide by zero",T.testC,"arith \",10,0)
163+checkerr("%%0",T.testC,"arith %",10,0)
164+assert(T.testC("compare LT 2 5, return 1",3,2,2,4,2,2))
165+assert(T.testC("compare LE 2 5, return 1",3,2,2,4,2,2))
166+assert(not T.testC("compare LT 3 4, return 1",3,2,2,4,2,2))
167+assert(T.testC("compare LE 3 4, return 1",3,2,2,4,2,2))
168+assert(T.testC("compare LT 5 2, return 1",4,2,2,3,2,2))
169+assert(not T.testC("compare LT 2 -3, return 1","4","2","2","3","2","2"))
170+assert(not T.testC("compare LT -3 2, return 1","3","2","2","4","2","2"))
171+assert(not T.testC("compare LT 1 4, return 1"))
172+assert(not T.testC("compare LE 9 1, return 1"))
173+assert(not T.testC("compare EQ 9 9, return 1"))
174+local b = {["__lt"] = (a,b)
175+return a[1] < b[1]
176+end}
177+local a1,a3,a4 = setmetatable({1},b),setmetatable({3},b),setmetatable({4},b)
178+assert(T.testC("compare LT 2 5, return 1",a3,2,2,a4,2,2))
179+assert(T.testC("compare LE 2 5, return 1",a3,2,2,a4,2,2))
180+assert(T.testC("compare LT 5 -6, return 1",a4,2,2,a3,2,2))
181+a,b=T.testC("compare LT 5 -6, return 2",a1,2,2,a3,2,20)
182+assert(a == 20 and b == false)
183+a,b=T.testC("compare LE 5 -6, return 2",a1,2,2,a3,2,20)
184+assert(a == 20 and b == false)
185+a,b=T.testC("compare LE 5 -6, return 2",a1,2,2,a1,2,20)
186+assert(a == 20 and b == true)
187+local mt = {["__lt"] = (a,b)
188+return a[1] < b[1]
189+end,["__le"] = (a,b)
190+return a[1] <= b[1]
191+end,["__eq"] = (a,b)
192+return a[1] == b[1]
193+end}
194+local function O
195+(x)
196+return setmetatable({x},mt)
197+end
198+local a,b = T.testC("compare LT 2 3; pushint 10; return 2",O(1),O(2))
199+assert(a == true and b == 10)
200+local a,b = T.testC("compare LE 2 3; pushint 10; return 2",O(3),O(2))
201+assert(a == false and b == 10)
202+local a,b = T.testC("compare EQ 2 3; pushint 10; return 2",O(3),O(3))
203+assert(a == true and b == 10)
204+local t = setmetatable({["x"] = 20},{["__len"] = (t)
205+return t.x
206+end})
207+a,b,c=T.testC(" len 2;
208+ Llen 2;
209+ objsize 2;
210+ return 3
211+",t)
212+assert(a == 20 and b == 20 and c == 0)
213+t.x="234"
214+;
215+t[1]=20
216+a,b,c=T.testC(" len 2;
217+ Llen 2;
218+ objsize 2;
219+ return 3
220+",t)
221+assert(a == "234" and b == 234 and c == 1)
222+t.x=print
223+;
224+t[1]=20
225+a,c=T.testC(" len 2;
226+ objsize 2;
227+ return 2
228+",t)
229+assert(a == print and c == 1)
230+a=setmetatable({["x"] = "u"},{["__concat"] = (a,b)
231+return a.x .. "." .. b.x
232+end})
233+x,y=T.testC(" pushnum 5
234+ pushvalue 2;
235+ pushvalue 2;
236+ concat 2;
237+ pushvalue -2;
238+ return 2;
239+",a,a)
240+assert(x == a .. a and y == 5)
241+assert(T.testC("concat 0; return 1") == "")
242+assert(T.testC("concat 1; return 1","xuxu") == "xuxu")
243+local function B
244+(x)
245+return x and 1 or 0
246+end
247+local function count
248+(x,n)
249+n=n or 2
250+local prog = " isnumber %d;
251+ isstring %d;
252+ isfunction %d;
253+ iscfunction %d;
254+ istable %d;
255+ isuserdata %d;
256+ isnil %d;
257+ isnull %d;
258+ return 8
259+ "
260+prog=string.format(prog,n,n,n,n,n,n,n,n)
261+local a,b,c,d,e,f,g,h = T.testC(prog,x)
262+return B(a) + B(b) + B(c) + B(d) + B(e) + B(f) + B(g) + (100 * B(h))
263+end
264+assert(count(3) == 2)
265+assert(count("alo") == 1)
266+assert(count("32") == 2)
267+assert(count({}) == 1)
268+assert(count(print) == 2)
269+assert(count(()
270+
271+end) == 1)
272+assert(count(nil) == 1)
273+assert(count(io.stdin) == 1)
274+assert(count(nil,15) == 100)
275+local function to
276+(s,x,n)
277+n=n or 2
278+return T.testC(string.format("%s %d; return 1",s,n),x)
279+end
280+local null = T.pushuserdata(0)
281+local hfunc = string.gmatch("","")
282+assert(debug.getupvalue(hfunc,1))
283+assert(to("tostring",{}) == nil)
284+assert(to("tostring","alo") == "alo")
285+assert(to("tostring",12) == "12")
286+assert(to("tostring",12,3) == nil)
287+assert(to("objsize",{}) == 0)
288+assert(to("objsize",{1,2,3}) == 3)
289+assert(to("objsize","aloa") == 6)
290+assert(to("objsize",T.newuserdata(0)) == 0)
291+assert(to("objsize",T.newuserdata(101)) == 101)
292+assert(to("objsize",124) == 0)
293+assert(to("objsize",true) == 0)
294+assert(to("tonumber",{}) == 0)
295+assert(to("tonumber","12") == 12)
296+assert(to("tonumber","s2") == 0)
297+assert(to("tonumber",1,20) == 0)
298+assert(to("topointer",10) == null)
299+assert(to("topointer",true) == null)
300+assert(to("topointer",nil) == null)
301+assert(to("topointer","abc") ~= null)
302+assert(to("topointer",string.rep("x",10)) == to("topointer",string.rep("x",10)))
303+local s1 = string.rep("x",300)
304+local s2 = string.rep("x",300)
305+assert(to("topointer",s1) ~= to("topointer",s2))
306+assert(to("topointer",T.pushuserdata(20)) ~= null)
307+assert(to("topointer",io.read) ~= null)
308+assert(to("topointer",hfunc) ~= null)
309+assert(to("topointer",()
310+
311+end) ~= null)
312+assert(to("topointer",io.stdin) ~= null)
313+assert(to("func2num",20) == 0)
314+assert(to("func2num",T.pushuserdata(10)) == 0)
315+assert(to("func2num",io.read) ~= 0)
316+assert(to("func2num",hfunc) ~= 0)
317+a=to("tocfunction",math.deg)
318+assert(a(3) == math.deg(3) and a == math.deg)
319+print("testing panic function")
320+assert(T.checkpanic("pushstring hi; error") == "hi")
321+assert(T.checkpanic("pushstring hi; error;","checkstack 5 XX
322+ pushstring ' alo'
323+ pushstring ' mundo'
324+ concat 3") == "hi alo mundo")
325+assert(T.checkpanic("loadstring 4") == "bad argument #4 (string expected, got no value)")
326+T.totalmem(T.totalmem() + 1e4)
327+assert(T.checkpanic("newuserdata 20000") == MEMERRMSG)
328+T.totalmem(0)
329+if not _soft then
330+local msg = T.checkpanic(" pushstring "function f() f() end"
331+ loadstring -1; call 0 0
332+ getglobal f; call 0 0
333+ ")
334+assert(string.find(msg,"stack overflow"))
335+end
336+assert(T.checkpanic(" pushstring "return {__close = function () Y = 'ho'; end}"
337+ newtable
338+ loadstring -2
339+ call 0 1
340+ setmetatable -2
341+ toclose -1
342+ pushstring "hi"
343+ error
344+ "," getglobal Y
345+ concat 2 # concat original error with global Y
346+ ") == "hiho")
347+if not _soft then
348+print("testing stack overflow")
349+collectgarbage("stop")
350+checkerr("XXXX",T.testC,"checkstack 1000023 XXXX")
351+checkerr("^stack overflow$",T.testC,"checkstack 1000023 ''")
352+local s = string.rep("pushnil;checkstack 1 XX;",1e6)
353+checkerr("overflow",T.testC,s)
354+collectgarbage("restart")
355+print("+")
356+end
357+local lim = _soft and 500 or 1.2e4
358+local prog = {"checkstack " .. (lim * 2 + 100) .. "msg","newtable"}
359+for i = 1, lim
360+do
361+prog[# prog + 1]="pushnum " .. i
362+prog[# prog + 1]="pushnum " .. i * 10
363+end
364+prog[# prog + 1]="rawgeti R 2"
365+prog[# prog + 1]="insert " .. - (2 * lim + 2)
366+for i = 1, lim
367+do
368+prog[# prog + 1]="settable " .. - (2 * (lim - i + 1) + 1)
369+end
370+prog[# prog + 1]="return 2"
371+prog=table.concat(prog,";")
372+local g,t = T.testC(prog)
373+assert(g == _G)
374+for i = 1, lim
375+do
376+assert(t[i] == i * 10)
377+;
378+t[i]=undef
379+end
380+assert(next(t) == nil)
381+prog,g,t=nil
382+a=T.testC(" loadstring 2; pcall 0 1 0;
383+ pushvalue 3; insert -2; pcall 1 1 0;
384+ pcall 0 0 0;
385+ return 1
386+","XX=150",(a)
387+assert(a == nil)
388+;
389+return 3
390+end)
391+assert(type(a) == "string" and XX == 150)
392+_G.XX=nil
393+local function check3
394+(p, ...)
395+local arg = {...}
396+assert(# arg == 3)
397+assert(string.find(arg[3],p))
398+end
399+check3(":1:",T.testC("loadstring 2; return *","x="))
400+check3("%.",T.testC("loadfile 2; return *","."))
401+check3("xxxx",T.testC("loadfile 2; return *","xxxx"))
402+local function checkerrnopro
403+(code,msg)
404+local th = coroutine.create(()
405+
406+end)
407+local stt,err = pcall(T.testC,th,code)
408+assert(not stt and string.find(err,msg))
409+end
410+if not _soft then
411+collectgarbage("stop")
412+checkerrnopro("pushnum 3; call 0 0","attempt to call")
413+print("testing stack overflow in unprotected thread")
414+function F()
415+F()
416+end
417+checkerrnopro("getglobal 'F'; call 0 0;","stack overflow")
418+F=nil
419+collectgarbage("restart")
420+end
421+print("+")
422+local a = {}
423+local a1 = T.testC("rawsetp 2 1; return 1",a,20)
424+assert(a == a1)
425+assert(a[T.pushuserdata(1)] == 20)
426+local a1,res = T.testC("rawgetp -1 1; return 2",a)
427+assert(a == a1 and res == 20)
428+local a = {}
429+a[a]=10
430+local prog = "gettable -1; return *"
431+local res = {T.testC(prog,a)}
432+assert(# res == 2 and res[1] == prog and res[2] == 10)
433+local prog = "settable -2; return *"
434+local res = {T.testC(prog,a,20)}
435+assert(a[a] == 20)
436+assert(# res == 1 and res[1] == prog)
437+a[a]=10
438+local prog = "rawget -1; return *"
439+local res = {T.testC(prog,a)}
440+assert(# res == 2 and res[1] == prog and res[2] == 10)
441+local prog = "rawset -2; return *"
442+local res = {T.testC(prog,a,20)}
443+assert(a[a] == 20)
444+assert(# res == 1 and res[1] == prog)
445+local prog = "rawset -1; return *"
446+local res = {T.testC(prog,30,a)}
447+assert(a[30] == a)
448+assert(# res == 1 and res[1] == prog)
449+local prog = "settable -1; return *"
450+local res = {T.testC(prog,40,a)}
451+assert(a[40] == a)
452+assert(# res == 1 and res[1] == prog)
453+local prog = "rawseti -1 100; return *"
454+local res = {T.testC(prog,a)}
455+assert(a[100] == a)
456+assert(# res == 1 and res[1] == prog)
457+local prog = "seti -1 200; return *"
458+local res = {T.testC(prog,a)}
459+assert(a[200] == a)
460+assert(# res == 1 and res[1] == prog)
461+a={["x"] = 0,["y"] = 12}
462+x,y=T.testC("gettable 2; pushvalue 4; gettable 2; return 2",a,3,"y",4,"x")
463+assert(x == 0 and y == 12)
464+T.testC("settable -5",a,3,4,"x",15)
465+assert(a.x == 15)
466+a[a]=print
467+x=T.testC("gettable 2; return 1",a)
468+assert(x == print)
469+T.testC("settable 2",a,"x")
470+assert(a[a] == "x")
471+b=setmetatable({["p"] = a},{})
472+getmetatable(b).__index=(t,i)
473+return t.p[i]
474+end
475+local k,x = T.testC("gettable 3, return 2",4,b,20,35,"x")
476+assert(x == 15 and k == 35)
477+k=T.testC("getfield 2 y, return 1",b)
478+assert(k == 12)
479+getmetatable(b).__index=(t,i)
480+return a[i]
481+end
482+getmetatable(b).__newindex=(t,i,v)
483+a[i]=v
484+end
485+y=T.testC("insert 2; gettable -5; return 1",2,3,4,"y",b)
486+assert(y == 12)
487+k=T.testC("settable -5, return 1",b,3,4,"x",16)
488+assert(a.x == 16 and k == 4)
489+a[b]="xuxu"
490+y=T.testC("gettable 2, return 1",b)
491+assert(y == "xuxu")
492+T.testC("settable 2",b,19)
493+assert(a[b] == 19)
494+local t = {["_012345678901234567890123456789012345678901234567890123456789"] = 32}
495+local a = T.testC(" getfield 2 _012345678901234567890123456789012345678901234567890123456789
496+ return 1
497+ ",t)
498+assert(a == 32)
499+local a = T.testC(" pushnum 33
500+ setglobal _012345678901234567890123456789012345678901234567890123456789
501+ ")
502+assert(_012345678901234567890123456789012345678901234567890123456789 == 33)
503+_012345678901234567890123456789012345678901234567890123456789=nil
504+a={}
505+t=pack(T.testC("next; return *",a,nil))
506+tcheck(t,{["n"] = 1,a})
507+a={["a"] = 3}
508+t=pack(T.testC("next; return *",a,nil))
509+tcheck(t,{["n"] = 3,a,"a",3})
510+t=pack(T.testC("next; pop 1; next; return *",a,nil))
511+tcheck(t,{["n"] = 1,a})
512+local A = T.testC(" pushnum 10; pushnum 20; pushcclosure 2; return 1")
513+t,b,c=A("pushvalue U0; pushvalue U1; pushvalue U2; return 3")
514+assert(b == 10 and c == 20 and type(t) == "table")
515+a,b=A("tostring U3; tonumber U4; return 2")
516+assert(a == nil and b == 0)
517+A("pushnum 100; pushnum 200; replace U2; replace U1")
518+b,c=A("pushvalue U1; pushvalue U2; return 2")
519+assert(b == 100 and c == 200)
520+A("replace U2; replace U1",{["x"] = 1},{["x"] = 2})
521+b,c=A("pushvalue U1; pushvalue U2; return 2")
522+assert(b.x == 1 and c.x == 2)
523+T.checkmemory()
524+assert(T.testC("isnull U1; return 1") == true)
525+assert(T.testC("isnull U100; return 1") == true)
526+assert(T.testC("pushvalue U1; return 1") == nil)
527+local f = T.testC(" pushnum 10; pushnum 20; pushcclosure 2; return 1")
528+assert(T.upvalue(f,1) == 10 and T.upvalue(f,2) == 20 and T.upvalue(f,3) == nil)
529+T.upvalue(f,2,"xuxu")
530+assert(T.upvalue(f,2) == "xuxu")
531+local A = "checkstack 300 msg;" .. string.rep("pushnum 10;",255) .. "pushcclosure 255; return 1"
532+A=T.testC(A)
533+for i = 1, 255
534+do
535+assert(A(("pushvalue U%d; return 1"):format(i)) == 10)
536+end
537+assert(A("isnull U256; return 1"))
538+assert(not A("isnil U256; return 1"))
539+checkerr("got number",debug.setuservalue,3,{})
540+checkerr("got nil",debug.setuservalue,nil,{})
541+checkerr("got light userdata",debug.setuservalue,T.pushuserdata(1),{})
542+local b = T.newuserdata(0,10)
543+for i = 1, 10
544+do
545+local v,p = debug.getuservalue(b,i)
546+assert(v == nil and p)
547+end
548+local v,p = debug.getuservalue(b,- 2)
549+assert(v == nil and not p)
550+local v,p = debug.getuservalue(b,11)
551+assert(v == nil and not p)
552+local t = {true,false,4.56,print,{},b,"XYZ"}
553+for k,v in ipairs(t)
554+do
555+debug.setuservalue(b,v,k)
556+end
557+for k,v in ipairs(t)
558+do
559+local v1,p = debug.getuservalue(b,k)
560+assert(v1 == v and p)
561+end
562+assert(not debug.getuservalue(4))
563+debug.setuservalue(b,()
564+return 10
565+end,10)
566+collectgarbage()
567+assert(debug.getuservalue(b,10)() == 10)
568+debug.setuservalue(b,134)
569+collectgarbage()
570+assert(debug.getuservalue(b) == 134)
571+local oldmode = collectgarbage("incremental")
572+T.gcstate("atomic")
573+assert(T.gccolor(b) == "black")
574+debug.setuservalue(b,{["x"] = 100})
575+T.gcstate("pause")
576+assert(debug.getuservalue(b).x == 100)
577+collectgarbage(oldmode)
578+for i = 1, 1e3
579+do
580+local bb = T.newuserdata(0,1)
581+debug.setuservalue(bb,b)
582+b=bb
583+end
584+collectgarbage()
585+for i = 1, 1e3
586+do
587+b=debug.getuservalue(b)
588+end
589+assert(debug.getuservalue(b).x == 100)
590+b=nil
591+local i = T.ref({})
592+T.unref(i)
593+assert(T.ref({}) == i)
594+local Arr = {}
595+local Lim = 100
596+for i = 1, Lim
597+do
598+Arr[i]=T.ref({})
599+end
600+assert(T.ref(nil) == - 1 and T.getref(- 1) == nil)
601+T.unref(- 1)
602+;
603+T.unref(- 1)
604+for i = 1, Lim
605+do
606+T.unref(Arr[i])
607+end
608+local function printlocks
609+()
610+local f = T.makeCfunc("gettable R; return 1")
611+local n = f("n")
612+print("n",n)
613+for i = 0, n
614+do
615+print(i,f(i))
616+end
617+end
618+for i = 1, Lim
619+do
620+Arr[i]=T.ref({})
621+end
622+for i = 1, Lim, 2
623+do
624+T.unref(Arr[i])
625+end
626+assert(type(T.getref(Arr[2])) == "table")
627+assert(T.getref(- 1) == nil)
628+a=T.ref({})
629+collectgarbage()
630+assert(type(T.getref(a)) == "table")
631+local tt = {}
632+local cl = {["n"] = 0}
633+A=nil
634+;
635+B=nil
636+local F =
637+F=(x)
638+local udval = T.udataval(x)
639+table.insert(cl,udval)
640+local d = T.newuserdata(100)
641+d=nil
642+assert(debug.getmetatable(x).__gc == F)
643+assert(load("table.insert({}, {})"))()
644+assert(not collectgarbage())
645+local dummy = {}
646+if A ~= nil then
647+assert(type(A) == "userdata")
648+assert(T.udataval(A) == B)
649+debug.getmetatable(A)
650+end
651+A=x
652+B=udval
653+return 1,2,3
654+end
655+tt.__gc=F
656+collectgarbage()
657+;
658+collectgarbage()
659+;
660+local x = collectgarbage("count")
661+;
662+local a = T.newuserdata(5001)
663+assert(T.testC("objsize 2; return 1",a) == 5001)
664+assert(collectgarbage("count") >= x + 4)
665+a=nil
666+collectgarbage()
667+;
668+assert(collectgarbage("count") <= x + 1)
669+x=collectgarbage("count")
670+collectgarbage("stop")
671+for i = 1, 1e3
672+do
673+T.newuserdata(0)
674+end
675+assert(collectgarbage("count") > x + 10)
676+collectgarbage()
677+assert(collectgarbage("count") <= x + 1)
678+collectgarbage()
679+x=collectgarbage("count")
680+collectgarbage("stop")
681+a={["__gc"] = ()
682+
683+end}
684+for i = 1, 1e3
685+do
686+debug.setmetatable(T.newuserdata(0),a)
687+end
688+assert(collectgarbage("count") >= x + 10)
689+collectgarbage()
690+assert(collectgarbage("count") >= x + 10)
691+collectgarbage()
692+assert(collectgarbage("count") <= x + 1)
693+collectgarbage("restart")
694+collectgarbage("stop")
695+a=T.newuserdata(0)
696+;
697+debug.setmetatable(a,tt)
698+;
699+local na = T.udataval(a)
700+b=T.newuserdata(0)
701+;
702+debug.setmetatable(b,tt)
703+;
704+local nb = T.udataval(b)
705+c=T.newuserdata(0)
706+;
707+debug.setmetatable(c,tt)
708+;
709+local nc = T.udataval(c)
710+x=T.newuserdata(4)
711+y=T.newuserdata(0)
712+checkerr("FILE%* expected, got userdata",io.input,a)
713+checkerr("FILE%* expected, got userdata",io.input,x)
714+assert(debug.getmetatable(x) == nil and debug.getmetatable(y) == nil)
715+local d = T.ref(a)
716+;
717+local e = T.ref(b)
718+;
719+local f = T.ref(c)
720+;
721+t={T.getref(d),T.getref(e),T.getref(f)}
722+assert(t[1] == a and t[2] == b and t[3] == c)
723+t=nil
724+;
725+a=nil
726+;
727+c=nil
728+;
729+T.unref(e)
730+;
731+T.unref(f)
732+collectgarbage()
733+assert(# cl == 1 and cl[1] == nc)
734+x=T.getref(d)
735+assert(type(x) == "userdata" and debug.getmetatable(x) == tt)
736+x=nil
737+tt.b=b
738+tt=nil
739+A=nil
740+b=nil
741+T.unref(d)
742+;
743+local n5 = T.newuserdata(0)
744+debug.setmetatable(n5,{["__gc"] = F})
745+n5=T.udataval(n5)
746+collectgarbage()
747+assert(# cl == 4)
748+assert(cl[2] == n5 and cl[3] == nb and cl[4] == na)
749+collectgarbage("restart")
750+a,na={},{}
751+for i = 30, 1, - 1
752+do
753+a[i]=T.newuserdata(0)
754+debug.setmetatable(a[i],{["__gc"] = F})
755+na[i]=T.udataval(a[i])
756+end
757+cl={}
758+a=nil
759+;
760+collectgarbage()
761+assert(# cl == 30)
762+for i = 1, 30
763+do
764+assert(cl[i] == na[i])
765+end
766+na=nil
767+for i = 2, Lim, 2
768+do
769+T.unref(Arr[i])
770+end
771+x=T.newuserdata(41)
772+;
773+debug.setmetatable(x,{["__gc"] = F})
774+assert(T.testC("objsize 2; return 1",x) == 41)
775+cl={}
776+a={[x] = 1}
777+x=T.udataval(x)
778+collectgarbage()
779+assert(# cl == 0)
780+for n in pairs(a)
781+do
782+a[n]=undef
783+end
784+collectgarbage()
785+assert(# cl == 1 and cl[1] == x)
786+assert(T.testC("compare EQ 2 4; return 1",print,1,print,20))
787+assert(T.testC("compare EQ 3 2; return 1","alo","alo"))
788+assert(T.testC("compare EQ 2 3; return 1",nil,nil))
789+assert(not T.testC("compare EQ 2 3; return 1",{},{}))
790+assert(not T.testC("compare EQ 2 3; return 1"))
791+assert(not T.testC("compare EQ 2 3; return 1",3))
792+local map = {}
793+local t = {["__eq"] = (a,b)
794+return map[a] == map[b]
795+end}
796+local function f
797+(x)
798+local u = T.newuserdata(0)
799+debug.setmetatable(u,t)
800+map[u]=x
801+return u
802+end
803+assert(f(10) == f(10))
804+assert(f(10) ~= f(11))
805+assert(T.testC("compare EQ 2 3; return 1",f(10),f(10)))
806+assert(not T.testC("compare EQ 2 3; return 1",f(10),f(20)))
807+t.__eq=nil
808+assert(f(10) ~= f(10))
809+print("+")
810+_G.TT={}
811+T.sethook(" # set a line hook after 3 count hooks
812+ sethook 4 0 '
813+ getglobal TT;
814+ pushvalue -3; append -2
815+ pushvalue -2; append -2
816+ '","c",3)
817+local a = 1
818+a=1
819+a=1
820+a=1
821+a=1
822+debug.sethook()
823+local t = _G.TT
824+assert(t[1] == "line")
825+local line = t[2]
826+assert(t[3] == "line" and t[4] == line + 1)
827+assert(t[5] == "line" and t[6] == line + 2)
828+assert(t[7] == nil)
829+_G.TT=nil
830+warn("@off")
831+collectgarbage("stop")
832+local a = {}
833+for i = 1, 20
834+do
835+a[i]=T.newuserdata(i)
836+end
837+for i = 1, 20, 2
838+do
839+debug.setmetatable(a[i],{["__gc"] = (x)
840+error("@expected error in gc")
841+end})
842+end
843+for i = 2, 20, 2
844+do
845+debug.setmetatable(a[i],{["__gc"] = (x)
846+load("A=A+1")()
847+end})
848+end
849+a=nil
850+_G.A=0
851+collectgarbage()
852+assert(A == 10)
853+collectgarbage("restart")
854+warn("@on")
855+_G.A=nil
856+local a = {}
857+;
858+local lim = 30
859+for i = 0, lim
860+do
861+a[i]=T.pushuserdata(i)
862+end
863+for i = 0, lim
864+do
865+assert(T.udataval(a[i]) == i)
866+end
867+for i = 0, lim
868+do
869+assert(T.pushuserdata(i) == a[i])
870+end
871+for i = 0, lim
872+do
873+a[a[i]]=i
874+end
875+for i = 0, lim
876+do
877+a[T.pushuserdata(i)]=i
878+end
879+assert(type(tostring(a[1])) == "string")
880+T.closestate(T.newstate())
881+;
882+L1=T.newstate()
883+assert(L1)
884+assert(T.doremote(L1,"X='a'; return 'a'") == "a")
885+assert(# pack(T.doremote(L1,"function f () return 'alo', 3 end; f()")) == 0)
886+a,b=T.doremote(L1,"return f()")
887+assert(a == "alo" and b == "3")
888+T.doremote(L1,"_ERRORMESSAGE = nil")
889+a,b,c=T.doremote(L1,"return sin(1)")
890+assert(a == nil and c == 2)
891+a,b,c=T.doremote(L1,"return a+")
892+assert(a == nil and c == 3 and type(b) == "string")
893+T.loadlib(L1)
894+a,b,c=T.doremote(L1," string = require'string'
895+ a = require'_G'; assert(a == _G and require("_G") == a)
896+ io = require'io'; assert(type(io.read) == "function")
897+ assert(require("io") == io)
898+ a = require'table'; assert(type(a.insert) == "function")
899+ a = require'debug'; assert(type(a.getlocal) == "function")
900+ a = require'math'; assert(type(a.sin) == "function")
901+ return string.sub('okinama', 1, 2)
902+")
903+assert(a == "ok")
904+T.closestate(L1)
905+;
906+L1=T.newstate()
907+T.loadlib(L1)
908+T.doremote(L1,"a = {}")
909+T.testC(L1,"getglobal "a"; pushstring "x"; pushint 1;
910+ settable -3")
911+assert(T.doremote(L1,"return a.x") == "1")
912+T.closestate(L1)
913+L1=nil
914+print("+")
915+print("testing to-be-closed variables")
916+local openresource = {}
917+local function newresource
918+()
919+local x = setmetatable({10},{["__close"] = (y)
920+assert(openresource[# openresource] == y)
921+openresource[# openresource]=nil
922+y[1]=y[1] + 1
923+end})
924+openresource[# openresource + 1]=x
925+return x
926+end
927+local a,b = T.testC(" call 0 1 # create resource
928+ pushnil
929+ toclose -2 # mark call result to be closed
930+ toclose -1 # mark nil to be closed (will be ignored)
931+ return 2
932+ ",newresource)
933+assert(a[1] == 11 and b == nil)
934+assert(# openresource == 0)
935+local a = {T.testC(" call 0 1 # create resource
936+ toclose 2 # mark it to be closed
937+ return 2
938+ ",newresource)}
939+assert(type(a[1]) == "string" and a[2][1] == 11)
940+assert(# openresource == 0)
941+local a,b = pcall(T.makeCfunc(" call 0 1 # create resource
942+ toclose -1 # mark it to be closed
943+ error # resource is the error object
944+ "),newresource)
945+assert(a == false and b[1] == 11)
946+assert(# openresource == 0)
947+local a,b = pcall(T.makeCfunc(" newtable # create non-closable object
948+ toclose -1 # mark it to be closed (should raise an error)
949+ abort # will not be executed
950+ "))
951+assert(a == false and string.find(b,"non%-closable value"))
952+local function check
953+(n)
954+assert(# openresource == n)
955+end
956+_ENV.xxx=true
957+local a = T.testC(" pushvalue 2 # stack: S, NR, CH, NR
958+ call 0 1 # create resource; stack: S, NR, CH, R
959+ toclose -1 # mark it to be closed
960+ pushvalue 2 # stack: S, NR, CH, R, NR
961+ call 0 1 # create another resource; stack: S, NR, CH, R, R
962+ toclose -1 # mark it to be closed
963+ pushvalue 3 # stack: S, NR, CH, R, R, CH
964+ pushint 2 # there should be two open resources
965+ call 1 0 # stack: S, NR, CH, R, R
966+ closeslot -1 # close second resource
967+ pushvalue 3 # stack: S, NR, CH, R, R, CH
968+ pushint 1 # there should be one open resource
969+ call 1 0 # stack: S, NR, CH, R, R
970+ closeslot 4
971+ setglobal "xxx" # previous op. erased the slot
972+ pop 1 # pop other resource from the stack
973+ pushint *
974+ return 1 # return stack size
975+ ",newresource,check)
976+assert(a == 3 and _ENV.xxx == nil)
977+local a = T.testC(" pushvalue 2 # stack: S, NR, CH, NR
978+ call 0 1 # create resource; stack: S, NR, CH, R
979+ toclose -1 # mark it to be closed
980+ pushvalue 2 # stack: S, NR, CH, R, NR
981+ call 0 1 # create another resource; stack: S, NR, CH, R, R
982+ toclose -1 # mark it to be closed
983+ pushvalue 3 # stack: S, NR, CH, R, R, CH
984+ pushint 2 # there should be two open resources
985+ call 1 0 # stack: S, NR, CH, R, R
986+ pop 1 # pop second resource
987+ pushvalue 3 # stack: S, NR, CH, R, CH
988+ pushint 1 # there should be one open resource
989+ call 1 0 # stack: S, NR, CH, R
990+ pop 1 # pop other resource from the stack
991+ pushvalue 3 # stack: S, NR, CH, CH
992+ pushint 0 # there should be no open resources
993+ call 1 0 # stack: S, NR, CH
994+ pushint *
995+ return 1 # return stack size
996+ ",newresource,check)
997+assert(a == 3)
998+local a,b = pcall(T.makeCfunc(" pushint 32
999+ toclose -1
1000+ "))
1001+assert(not a and string.find(b,"(C temporary)"))
1002+print("memory-allocation errors")
1003+checkerr("block too big",T.newuserdata,math.maxinteger)
1004+collectgarbage()
1005+local f = load("local a={}; for i=1,100000 do a[i]=i end")
1006+T.alloccount(10)
1007+checkerr(MEMERRMSG,f)
1008+T.alloccount()
1009+local function testbytes
1010+(s,f)
1011+collectgarbage()
1012+local M = T.totalmem()
1013+local oldM = M
1014+local a,b = nil
1015+while true do
1016+collectgarbage()
1017+;
1018+collectgarbage()
1019+T.totalmem(M)
1020+a,b=T.testC("pcall 0 1 0; pushstatus; return 2",f)
1021+T.totalmem(0)
1022+if a and b == "OK" then
1023+break
1024+end
1025+if b ~= "OK" and b ~= MEMERRMSG then
1026+error(a,0)
1027+end
1028+M=M + 7
1029+print(string.format("minimum memory for %s: %d bytes",s,M - oldM))
1030+return a
1031+end
1032+local function testalloc
1033+(s,f)
1034+collectgarbage()
1035+local M = 0
1036+local a,b = nil
1037+while true do
1038+collectgarbage()
1039+;
1040+collectgarbage()
1041+T.alloccount(M)
1042+a,b=T.testC("pcall 0 1 0; pushstatus; return 2",f)
1043+T.alloccount()
1044+if a and b == "OK" then
1045+break
1046+end
1047+if b ~= "OK" and b ~= MEMERRMSG then
1048+error(a,0)
1049+end
1050+M=M + 1
1051+print(string.format("minimum allocations for %s: %d allocations",s,M))
1052+return a
1053+end
1054+local function testamem
1055+(s,f)
1056+testalloc(s,f)
1057+return testbytes(s,f)
1058+end
1059+b=testamem("doing nothing",()
1060+return 10
1061+end)
1062+assert(b == 10)
1063+testamem("state creation",()
1064+local st = T.newstate()
1065+if st then
1066+T.closestate(st)
1067+end
1068+return st
1069+end)
1070+testamem("empty-table creation",()
1071+return {}
1072+end)
1073+testamem("string creation",()
1074+return "XXX" .. "YYY"
1075+end)
1076+testamem("coroutine creation",()
1077+return coroutine.create(print)
1078+end)
1079+testamem("to-be-closed variables",()
1080+local flag =
1081+local x <close> = setmetatable({},{["__close"] = ()
1082+flag=true
1083+end})
1084+flag=false
1085+local x = {}
1086+return flag
1087+end)
1088+local mt = T.testC("rawgeti R 1; return 1")
1089+assert(type(mt) == "thread" and coroutine.running() == mt)
1090+local function expand
1091+(n,s)
1092+if n == 0 then
1093+return ""
1094+end
1095+local e = string.rep("=",n)
1096+return string.format("T.doonnewstack([%s[ %s;
1097+ collectgarbage(); %s]%s])
1098+",e,s,expand(n - 1,s),e)
1099+end
1100+G=0
1101+;
1102+collectgarbage()
1103+;
1104+a=collectgarbage("count")
1105+load(expand(20,"G=G+1"))()
1106+assert(G == 20)
1107+;
1108+collectgarbage()
1109+;
1110+G=nil
1111+testamem("running code on new thread",()
1112+return T.doonnewstack("local x=1") == 0
1113+end)
1114+testamem("loadstring",()
1115+return load("x=1")
1116+end)
1117+local testprog = "local function foo () return end
1118+local t = {"x"}
1119+AA = "aaa"
1120+for i = 1, #t do AA = AA .. t[i] end
1121+return true
1122+"
1123+_G.AA=nil
1124+local t = os.tmpname()
1125+local f = assert(io.open(t,"w"))
1126+f:write(testprog)
1127+f:close()
1128+testamem("dofile",()
1129+local a = loadfile(t)
1130+return a and a()
1131+end)
1132+assert(os.remove(t))
1133+assert(_G.AA == "aaax")
1134+testamem("gsub",()
1135+local a,b = string.gsub("alo alo","(a)",(x)
1136+return x .. "b"
1137+end)
1138+return (a == "ablo ablo")
1139+end)
1140+testamem("dump/undump",()
1141+local a = load(testprog)
1142+local b = a and string.dump(a)
1143+a=b and load(b)
1144+return a and a()
1145+end)
1146+_G.AA=nil
1147+local t = os.tmpname()
1148+testamem("file creation",()
1149+local f = assert(io.open(t,"w"))
1150+assert(not io.open("nomenaoexistente"))
1151+io.close(f)
1152+;
1153+return not loadfile("nomenaoexistente")
1154+end)
1155+assert(os.remove(t))
1156+testamem("table creation",()
1157+local a,lim = {},10
1158+for i = 1, lim
1159+do
1160+a[i]=i
1161+;
1162+a[i .. "a"]={}
1163+end
1164+return (type(a[lim .. "a"]) == "table" and a[lim] == lim)
1165+end)
1166+testamem("constructors",()
1167+local a = {10,20,30,40,50,["a"] = 1,["b"] = 2,["c"] = 3,["d"] = 4,["e"] = 5}
1168+return (type(a) == "table" and a.e == 5)
1169+end)
1170+local a = 1
1171+local close = nil
1172+testamem("closure creation",()
1173+function close(b)
1174+return (x)
1175+return b + x
1176+end
1177+end
1178+return (close(2)(4) == 6)
1179+end)
1180+testamem("using coroutines",()
1181+local a = coroutine.wrap(()
1182+coroutine.yield(string.rep("a",10))
1183+return {}
1184+end)
1185+assert(string.len(a()) == 10)
1186+return a()
1187+end)
1188+local lim = 100
1189+local a = {}
1190+;
1191+for i = 1, lim
1192+do
1193+a[i]="01234567890123456789"
1194+end
1195+testamem("auxiliary buffer",()
1196+return (# table.concat(a,",") == 20 * lim + lim - 1)
1197+end)
1198+testamem("growing stack",()
1199+local function foo
1200+(n)
1201+if n == 0 then
1202+return 1
1203+else
1204+return 1 + foo(n - 1)
1205+end
1206+end
1207+return foo(100)
1208+end)
1209+local res = T.testC("rawcheckstack 500000; return 1")
1210+assert(res == false)
1211+local L = T.newstate()
1212+T.alloccount(0)
1213+res=T.testC(L,"rawcheckstack 5000; return 1")
1214+T.alloccount()
1215+T.closestate(L)
1216+assert(res == false)
1217+local L = T.newstate()
1218+T.alloccount(0)
1219+T.closestate(L)
1220+T.alloccount()
1221+local L = T.newstate()
1222+T.loadlib(L)
1223+local res = (T.doremote(L," _ENV = require"_G"
1224+ local T = require"T"
1225+ local a = {}
1226+ for i = 1, 1000 do a[i] = 'i' .. i end -- grow string table
1227+ local stsize, stuse = T.querystr()
1228+ assert(stuse > 1000)
1229+ local function foo (n)
1230+ if n > 0 then foo(n - 1) end
1231+ end
1232+ foo(180) -- grow stack
1233+ local _, stksize = T.stacklevel()
1234+ assert(stksize > 180)
1235+ a = nil
1236+ T.alloccount(0)
1237+ collectgarbage()
1238+ T.alloccount()
1239+ -- stack and string table could not be reallocated,
1240+ -- so they kept their sizes (without errors)
1241+ assert(select(2, T.stacklevel()) == stksize)
1242+ assert(T.querystr() == stsize)
1243+ return 'ok'
1244+ "))
1245+assert(res == "ok")
1246+T.closestate(L)
1247+print("+")
1248+local function gsub
1249+(a,b,c)
1250+a,b=T.testC("gsub 2 3 4; gettop; return 2",a,b,c)
1251+assert(b == 5)
1252+return a
1253+end
1254+assert(gsub("alo.alo.uhuh.",".","//") == "alo//alo//uhuh//")
1255+assert(gsub("alo.alo.uhuh.","alo","//") == "//.//.uhuh.")
1256+assert(gsub("","alo","//") == "")
1257+assert(gsub("...",".","/.") == "/././.")
1258+assert(gsub("...","...","") == "")
1259+local mt_xuxu,res,top = T.testC("newmetatable xuxu; gettop; return 3")
1260+assert(type(mt_xuxu) == "table" and res and top == 3)
1261+local d,res,top = T.testC("newmetatable xuxu; gettop; return 3")
1262+assert(mt_xuxu == d and not res and top == 3)
1263+d,res,top=T.testC("newmetatable xuxu1; gettop; return 3")
1264+assert(mt_xuxu ~= d and res and top == 3)
1265+x=T.newuserdata(0)
1266+;
1267+y=T.newuserdata(0)
1268+;
1269+T.testC("pushstring xuxu; gettable R; setmetatable 2",x)
1270+assert(getmetatable(x) == mt_xuxu)
1271+local res1,res2,top = T.testC("testudata -1 xuxu
1272+ testudata 2 xuxu
1273+ gettop
1274+ return 3",x)
1275+assert(res1 and res2 and top == 4)
1276+res1,res2,top=T.testC("testudata -1 xuxu1
1277+ testudata 2 xuxu1
1278+ gettop
1279+ return 3",x)
1280+assert(not res1 and not res2 and top == 4)
1281+res1,res2,top=T.testC("testudata -1 xuxu2
1282+ testudata 2 xuxu2
1283+ gettop
1284+ return 3",x)
1285+assert(not res1 and not res2 and top == 4)
1286+res1,res2,top=T.testC("testudata -1 xuxu
1287+ testudata 2 xuxu
1288+ gettop
1289+ return 3",y)
1290+assert(not res1 and not res2 and top == 4)
1291+local r = debug.getregistry()
1292+assert(r.xuxu == mt_xuxu and r.xuxu1 == d)
1293+r.xuxu=nil
1294+;
1295+r.xuxu1=nil
1296+print("OK")
zod/luau/res/lua/cycled/attrib.luanew file+430
@@ -0,0 +1,430 @@
1+print("testing require")
2+assert(require("string") == string)
3+assert(require("math") == math)
4+assert(require("table") == table)
5+assert(require("io") == io)
6+assert(require("os") == os)
7+assert(require("coroutine") == coroutine)
8+assert(type(package.path) == "string")
9+assert(type(package.cpath) == "string")
10+assert(type(package.loaded) == "table")
11+assert(type(package.preload) == "table")
12+assert(type(package.config) == "string")
13+print("package config: " .. string.gsub(package.config,"
14+","|"))
15+local max = _soft and 100 or 2e3
16+local t = {}
17+for i = 1, max
18+do
19+t[i]=string.rep("?",i % 10 + 1)
20+end
21+t[# t + 1]=";"
22+local path = table.concat(t,";")
23+local s,err = package.searchpath("xuxu",path)
24+assert(not s and string.find(err,string.rep("xuxu",10)) and # string.gsub(err,"[^
25+]","") >= max)
26+local path = string.rep("?",max)
27+local s,err = package.searchpath("xuxu",path)
28+assert(not s and string.find(err,string.rep("xuxu",max)))
29+local oldpath = package.path
30+package.path={}
31+local s,err = pcall(require,"no-such-file")
32+assert(not s and string.find(err,"package.path"))
33+package.path=oldpath
34+print("testing 'require' message")
35+local oldpath = package.path
36+local oldcpath = package.cpath
37+package.path="?.lua;?/?"
38+package.cpath="?.so;?/init"
39+local st,msg = pcall(require,"XXX")
40+local expected = "module 'XXX' not found:
41+ no field package.preload['XXX']
42+ no file 'XXX.lua'
43+ no file 'XXX/XXX'
44+ no file 'XXX.so'
45+ no file 'XXX/init'"
46+assert(msg == expected)
47+package.path=oldpath
48+package.cpath=oldcpath
49+print("+")
50+if not _port then
51+local dirsep = string.match(package.config,"^([^
52+]+)
53+")
54+local DIR = "libs" .. dirsep
55+local function D
56+(x)
57+local x = string.gsub(x,"/",dirsep)
58+return DIR .. x
59+end
60+local function DC
61+(x)
62+local ext = (dirsep == "\") and ".dll" or ".so"
63+return D(x .. ext)
64+end
65+local function createfiles
66+(files,preextras,posextras)
67+for n,c in pairs(files)
68+do
69+io.output(D(n))
70+io.write(string.format(preextras,n))
71+io.write(c)
72+io.write(string.format(posextras,n))
73+io.close(io.output())
74+end
75+end
76+local function removefiles
77+(files)
78+for n in pairs(files)
79+do
80+os.remove(D(n))
81+end
82+end
83+local files = {["names.lua"] = "do return {...} end
84+",["err.lua"] = "B = 15; a = a + 1;",["synerr.lua"] = "B =",["A.lua"] = "",["B.lua"] = "assert(...=='B');require 'A'",["A.lc"] = "",["A"] = "",["L"] = "",["XXxX"] = "",["C.lua"] = "package.loaded[...] = 25; require'C'"}
85+AA=nil
86+local extras = "NAME = '%s'
87+REQUIRED = ...
88+return AA"
89+createfiles(files,"",extras)
90+assert(package.searchpath("C.lua",D("?"),"","") == D("C.lua"))
91+assert(package.searchpath("C.lua",D("?"),".",".") == D("C.lua"))
92+assert(package.searchpath("--x-",D("?"),"-","X") == D("XXxX"))
93+assert(package.searchpath("---xX",D("?"),"---","XX") == D("XXxX"))
94+assert(package.searchpath(D("C.lua"),"?",dirsep) == D("C.lua"))
95+assert(package.searchpath(".\C.lua",D("?"),"\") == D("./C.lua"))
96+local oldpath = package.path
97+package.path=string.gsub("D/?.lua;D/?.lc;D/?;D/??x?;D/L","D/",DIR)
98+local try = (p,n,r,ext)
99+NAME=nil
100+local rr,x = require(p)
101+assert(NAME == n)
102+assert(REQUIRED == p)
103+assert(rr == r)
104+assert(ext == x)
105+end
106+local a = require("names")
107+assert(a[1] == "names" and a[2] == D("names.lua"))
108+local st,msg = pcall(require,"err")
109+assert(not st and string.find(msg,"arithmetic") and B == 15)
110+st,msg=pcall(require,"synerr")
111+assert(not st and string.find(msg,"error loading module"))
112+assert(package.searchpath("C",package.path) == D("C.lua"))
113+assert(require("C") == 25)
114+assert(require("C") == 25)
115+AA=nil
116+try("B","B.lua",true,"libs/B.lua")
117+assert(package.loaded.B)
118+assert(require("B") == true)
119+assert(package.loaded.A)
120+assert(require("C") == 25)
121+package.loaded.A=nil
122+try("B",nil,true,nil)
123+try("A","A.lua",true,"libs/A.lua")
124+package.loaded.A=nil
125+os.remove(D("A.lua"))
126+AA={}
127+try("A","A.lc",AA,"libs/A.lc")
128+assert(package.searchpath("A",package.path) == D("A.lc"))
129+assert(require("A") == AA)
130+AA=false
131+try("K","L",false,"libs/L")
132+try("K","L",false,"libs/L")
133+assert(rawget(_G,"_REQUIREDNAME") == nil)
134+AA="x"
135+try("X","XXxX",AA,"libs/XXxX")
136+removefiles(files)
137+NAME,REQUIRED,AA,B=nil
138+local _G = _G
139+package.path=string.gsub("D/?.lua;D/?/init.lua","D/",DIR)
140+files={["P1/init.lua"] = "AA = 10",["P1/xuxu.lua"] = "AA = 20"}
141+createfiles(files,"_ENV = {}
142+","
143+return _ENV
144+")
145+AA=0
146+local m,ext = assert(require("P1"))
147+assert(ext == "libs/P1/init.lua")
148+assert(AA == 0 and m.AA == 10)
149+assert(require("P1") == m)
150+assert(require("P1") == m)
151+assert(package.searchpath("P1.xuxu",package.path) == D("P1/xuxu.lua"))
152+m.xuxu,ext=assert(require("P1.xuxu"))
153+assert(AA == 0 and m.xuxu.AA == 20)
154+assert(ext == "libs/P1/xuxu.lua")
155+assert(require("P1.xuxu") == m.xuxu)
156+assert(require("P1.xuxu") == m.xuxu)
157+assert(require("P1") == m and m.AA == 10)
158+removefiles(files)
159+AA=nil
160+package.path=""
161+assert(not pcall(require,"file_does_not_exist"))
162+package.path="???"
163+assert(not pcall(require,"file_does_not_exist1"))
164+package.path=oldpath
165+local fname = "file_does_not_exist2"
166+local m,err = pcall(require,fname)
167+for t in string.gmatch(package.path .. ";" .. package.cpath,"[^;]+")
168+do
169+t=string.gsub(t,"?",fname)
170+assert(string.find(err,t,1,true))
171+end
172+local searchers = package.searchers
173+package.searchers=3
174+local st,msg = pcall(require,"a")
175+assert(not st and string.find(msg,"must be a table"))
176+package.searchers=searchers
177+local function import
178+(...)
179+local f = {...}
180+return (m)
181+for i = 1, # f
182+do
183+m[f[i]]=_G[f[i]]
184+end
185+end
186+end
187+assert(not pcall(module,"XUXU"))
188+local p = ""
189+local st,err,when = package.loadlib(DC("lib1"),"*")
190+if not st then
191+local f,err,when = package.loadlib("donotexist",p .. "xuxu")
192+assert(not f and type(err) == "string" and when == "absent")
193+;
194+(Message or print)("
195+ >>> cannot load dynamic library <<<
196+")
197+print(err,when)
198+else
199+local f = assert(package.loadlib(DC("lib1"),p .. "onefunction"))
200+local a,b = f(15,25)
201+assert(a == 25 and b == 15)
202+f=assert(package.loadlib(DC("lib1"),p .. "anotherfunc"))
203+assert(f(10,20) == "10%20
204+")
205+local f,err,when = package.loadlib(DC("lib1"),p .. "xuxu")
206+assert(not f and type(err) == "string" and when == "init")
207+f,err,when=package.loadlib("donotexist",p .. "xuxu")
208+assert(not f and type(err) == "string" and when == "open")
209+f=assert(package.loadlib(DC("lib11"),p .. "luaopen_lib11"))
210+assert(f() == "exported")
211+package.cpath=DC("?")
212+local lib2,ext = require("lib2-v2")
213+assert(string.find(ext,"libs/lib2-v2",1,true))
214+assert(_ENV.x == "lib2-v2" and _ENV.y == DC("lib2-v2"))
215+assert(lib2.id("x") == true)
216+local fs,ext = require("lib1.sub")
217+assert(_ENV.x == "lib1.sub" and _ENV.y == DC("lib1"))
218+assert(string.find(ext,"libs/lib1",1,true))
219+assert(fs.id(45) == 45)
220+_ENV.x,_ENV.y=nil
221+end
222+_ENV=_G
223+local p = package
224+package={}
225+p.preload.pl=(...)
226+local _ENV = {...}
227+function xuxu(x)
228+return x + 20
229+end
230+return _ENV
231+end
232+local pl,ext = require("pl")
233+assert(require("pl") == pl)
234+assert(pl.xuxu(10) == 30)
235+assert(pl[1] == "pl" and pl[2] == ":preload:" and ext == ":preload:")
236+package=p
237+assert(type(package.path) == "string")
238+print("+")
239+end
240+print("testing assignments, logical operators, and constructors")
241+local res,res2 = 27
242+local a,b = 1,2 + 3
243+assert(a == 1 and b == 5)
244+a={}
245+local function f
246+()
247+return 10,11,12
248+end
249+a.x,b,a[1]=1,2,f()
250+assert(a.x == 1 and b == 2 and a[1] == 10)
251+a[f()],b,a[f() + 3]=f(),a,"x"
252+assert(a[10] == 10 and b == a and a[13] == "x")
253+local f = (n)
254+local x = {}
255+;
256+for i = 1, n
257+do
258+x[i]=i
259+end
260+;
261+return table.unpack(x)
262+end
263+;
264+local a,b,c =
265+a,b=0,f(1)
266+assert(a == 0 and b == 1)
267+a,b=0,f(1)
268+assert(a == 0 and b == 1)
269+a,b,c=0,5,f(4)
270+assert(a == 0 and b == 5 and c == 1)
271+a,b,c=0,5,f(0)
272+assert(a == 0 and b == 5 and c == nil)
273+local a,b,c,d = 1 and nil,1 or nil,(1 and (nil or 1)),6
274+assert(not a and b and c and d == 6)
275+d=20
276+a,b,c,d=f()
277+assert(a == 10 and b == 11 and c == 12 and d == nil)
278+a,b=f(),1,2,3,f()
279+assert(a == 10 and b == 1)
280+assert(a < b == false and a > b == true)
281+assert((10 and 2) == 2)
282+assert((10 or 2) == 10)
283+assert((10 or assert(nil)) == 10)
284+assert(not (nil and assert(nil)))
285+assert((nil or "alo") == "alo")
286+assert((nil and 10) == nil)
287+assert((false and 10) == false)
288+assert((true or 10) == true)
289+assert((false or 10) == 10)
290+assert(false ~= nil)
291+assert(nil ~= false)
292+assert(not nil == true)
293+assert(not not nil == false)
294+assert(not not 1 == true)
295+assert(not not a == true)
296+assert(not not (6 or nil) == true)
297+assert(not not (nil and 56) == false)
298+assert(not not (nil and true) == false)
299+assert(not 10 == false)
300+assert(not {} == false)
301+assert(not 0.5 == false)
302+assert(not "x" == false)
303+assert({} ~= {})
304+print("+")
305+a={}
306+a[true]=20
307+a[false]=10
308+assert(a[1 < 2] == 20 and a[1 > 2] == 10)
309+function f(a)
310+return a
311+end
312+local a = {}
313+for i = 3e3, - 3e3, - 1
314+do
315+a[i + 0]=i
316+;
317+end
318+a[1e31]="alo"
319+;
320+a[true]=10
321+;
322+a[false]=20
323+assert(a[1e31] == "alo" and a[not 1] == 20 and a[10 < 20] == 10)
324+for i = 3e3, - 3e3, - 1
325+do
326+assert(a[i] == i)
327+;
328+end
329+a[print]=assert
330+a[f]=print
331+a[a]=a
332+assert(a[a][a][a][a][print] == assert)
333+a[print](a[a[f]] == a[print])
334+assert(not pcall(()
335+local a = {}
336+;
337+a[nil]=10
338+end))
339+assert(not pcall(()
340+local a = {[nil] = 10}
341+end))
342+assert(a[nil] == undef)
343+a=nil
344+local a,b,c =
345+a={10,9,8,7,6,5,4,3,2,[- 3] = "a",[f] = print,["a"] = "a",["b"] = "ab"}
346+a,a.x,a.y=a,a[- 3]
347+assert(a[1] == 10 and a[- 3] == a.a and a[f] == print and a.x == "a" and not a.y)
348+a[1],f(a)[2],b,c={["alo"] = assert},10,a[1],a[f],6,10,23,f(a),2
349+a[1].alo(a[2] == 10 and b == 10 and c == print)
350+a.aVeryLongName012345678901234567890123456789012345678901234567890123456789=10
351+local function foo
352+()
353+return a.aVeryLongName012345678901234567890123456789012345678901234567890123456789
354+end
355+assert(foo() == 10 and a.aVeryLongName012345678901234567890123456789012345678901234567890123456789 == 10)
356+local function foo
357+()
358+local _ENV <const> = 11
359+X="hi"
360+end
361+local st,msg = pcall(foo)
362+assert(not st and string.find(msg,"number"))
363+local maxint = math.maxinteger
364+while maxint ~= (maxint + 0) or (maxint - 1) ~= (maxint - 1) do
365+maxint=maxint // 2
366+local maxintF = maxint + 0
367+assert(maxintF == maxint and math.type(maxintF) == "float" and maxintF >= 2 ^ 14)
368+a[maxintF]=10
369+;
370+a[maxintF - 1]=11
371+;
372+a[- maxintF]=12
373+;
374+a[- maxintF + 1]=13
375+;
376+assert(a[maxint] == 10 and a[maxint - 1] == 11 and a[- maxint] == 12 and a[- maxint + 1] == 13)
377+a[maxint]=20
378+a[- maxint]=22
379+assert(a[maxintF] == 20 and a[maxintF - 1] == 11 and a[- maxintF] == 22 and a[- maxintF + 1] == 13)
380+a=nil
381+local a,i,j,b =
382+a={"a","b"}
383+;
384+i=1
385+;
386+j=2
387+;
388+b=a
389+i,a[i],a,j,a[j],a[i + j]=j,i,i,b,j,i
390+assert(i == 2 and b[1] == 1 and a == 1 and j == b and b[2] == 2 and b[3] == 1)
391+a={}
392+local function foo
393+()
394+b,a.x,a=a,10,20
395+end
396+foo()
397+assert(a == 20 and b.x == 10)
398+local a,i,j,b =
399+a={"a","b"}
400+;
401+i=1
402+;
403+j=2
404+;
405+b=a
406+local function foo
407+()
408+i,a[i],a,j,a[j],a[i + j]=j,i,i,b,j,i
409+end
410+foo()
411+assert(i == 2 and b[1] == 1 and a == 1 and j == b and b[2] == 2 and b[3] == 1)
412+local t = {}
413+((a)
414+t[a],a=10,20
415+end)(1)
416+;
417+assert(t[1] == 10)
418+local function foo
419+()
420+local a =
421+return ()
422+local b =
423+a,b=3,14
424+return a,b
425+end
426+end
427+local a,b = foo()()
428+assert(a == 3 and b == 14)
429+print("OK")
430+return res
zod/luau/res/lua/cycled/big.luanew file+69
@@ -0,0 +1,69 @@
1+if _soft then
2+return "a"
3+end
4+print("testing large tables")
5+local debug = require("debug")
6+local lim = 2 ^ 18 + 1e3
7+local prog = {"local y = {0"}
8+for i = 1, lim
9+do
10+prog[# prog + 1]=i
11+end
12+prog[# prog + 1]="}
13+"
14+prog[# prog + 1]="X = y
15+"
16+prog[# prog + 1]=("assert(X[%d] == %d)"):format(lim - 1,lim - 2)
17+prog[# prog + 1]="return 0"
18+prog=table.concat(prog,";")
19+local env = {["string"] = string,["assert"] = assert}
20+local f = assert(load(prog,nil,nil,env))
21+f()
22+assert(env.X[lim] == lim - 1 and env.X[lim + 1] == lim)
23+for k in pairs(env)
24+do
25+env[k]=undef
26+end
27+setmetatable(env,{["__index"] = (t,n)
28+coroutine.yield("g")
29+;
30+return _G[n]
31+end,["__newindex"] = (t,n,v)
32+coroutine.yield("s")
33+;
34+_G[n]=v
35+end})
36+X=nil
37+local co = coroutine.wrap(f)
38+assert(co() == "s")
39+assert(co() == "g")
40+assert(co() == "g")
41+assert(co() == 0)
42+assert(X[lim] == lim - 1 and X[lim + 1] == lim)
43+getmetatable(env).__index=()
44+
45+end
46+getmetatable(env).__newindex=()
47+
48+end
49+local e,m = pcall(f)
50+assert(not e and m:find("global 'X'"))
51+getmetatable(env).__newindex=()
52+error("hi")
53+end
54+local e,m = xpcall(f,debug.traceback)
55+assert(not e and m:find("'newindex'"))
56+f,X=nil
57+coroutine.yield("b")
58+if 2 ^ 32 == 0 then
59+print("testing string length overflow")
60+local repstrings = 192
61+local ssize = math.ceil(2 ^ 32 / repstrings) + 1
62+assert(repstrings * ssize > 2 ^ 32)
63+local longs = string.rep("",ssize)
64+local rep = assert(load("local a = ...; return " .. string.rep("a",repstrings,"..")))
65+local a,b = pcall(rep,longs)
66+assert(not a and string.find(b,"overflow"))
67+end
68+print("OK")
69+return "a"
zod/luau/res/lua/cycled/bitwise.luanew file+307
@@ -0,0 +1,307 @@
1+print("testing bitwise operations")
2+require("bwcoercion")
3+local numbits = string.packsize("j") * 8
4+assert(~ 0 == - 1)
5+assert((1 << (numbits - 1)) == math.mininteger)
6+local a,b,c,d =
7+a=18446744073709551615
8+assert(a == - 1 and a & - 1 == a and a & 35 == 35)
9+a=17361641481138401520
10+assert(a | - 1 == - 1)
11+assert(a ~ a == 0 and a ~ 0 == a and a ~ ~ a == - 1)
12+assert(a >> 4 == ~ a)
13+a=240
14+;
15+b=204
16+;
17+c=170
18+;
19+d=253
20+assert(a | b ~ c & d == 244)
21+a=240
22+;
23+b=204
24+;
25+c="0xAA.0"
26+;
27+d="0xFD.0"
28+assert(a | b ~ c & d == 244)
29+a=4026531840
30+;
31+b=3422552064
32+;
33+c=2852126720
34+;
35+d=4244635648
36+assert(a | b ~ c & d == 4093640704)
37+assert(~ ~ a == a and ~ a == - 1 ~ a and - d == ~ d + 1)
38+a=a << 32
39+b=b << 32
40+c=c << 32
41+d=d << 32
42+assert(a | b ~ c & d == 4093640704 << 32)
43+assert(~ ~ a == a and ~ a == - 1 ~ a and - d == ~ d + 1)
44+local code = string.format("return -1 >> %d",math.maxinteger)
45+assert(load(code)() == 0)
46+local code = string.format("return -1 >> %d",math.mininteger)
47+assert(load(code)() == 0)
48+local code = string.format("return -1 << %d",math.maxinteger)
49+assert(load(code)() == 0)
50+local code = string.format("return -1 << %d",math.mininteger)
51+assert(load(code)() == 0)
52+assert(- 1 >> 1 == (1 << (numbits - 1)) - 1 and 1 << 31 == 2147483648)
53+assert(- 1 >> (numbits - 1) == 1)
54+assert(- 1 >> numbits == 0 and - 1 >> - numbits == 0 and - 1 << numbits == 0 and - 1 << - numbits == 0)
55+assert(1 >> math.mininteger == 0)
56+assert(1 >> math.maxinteger == 0)
57+assert(1 << math.mininteger == 0)
58+assert(1 << math.maxinteger == 0)
59+assert((2 ^ 30 - 1) << 2 ^ 30 == 0)
60+assert((2 ^ 30 - 1) >> 2 ^ 30 == 0)
61+assert(1 >> - 3 == 1 << 3 and 1e3 >> 5 == 1e3 << - 5)
62+assert("0xffffffffffffffff" | 0 == - 1)
63+assert("0xfffffffffffffffe" & "-1" == - 2)
64+assert(" -0xfffffffffffffffe
65+ " & "-1" == 2)
66+assert("
67+ -45 " >> " -2 " == - 45 * 4)
68+assert("1234.0" << "5.0" == 1234 * 32)
69+assert("0xffff.0" ~ "0xAAAA" == 21845)
70+assert(~ "0x0.000p4" == - 1)
71+assert(("7" .. 3) << 1 == 146)
72+assert(4294967295 >> (1 .. "9") == 8191)
73+assert(10 | (1 .. "9") == 27)
74+local st,msg = pcall(()
75+return 4 & "a"
76+end)
77+assert(string.find(msg,"'band'"))
78+local st,msg = pcall(()
79+return ~ "a"
80+end)
81+assert(string.find(msg,"'bnot'"))
82+assert(not pcall(()
83+return "0xffffffffffffffff.0" | 0
84+end))
85+assert(not pcall(()
86+return "0xffffffffffffffff" | 0
87+end))
88+print("+")
89+package.preload.bit32=()
90+local bit = {}
91+function bit.bnot(a)
92+return ~ a & 4294967295
93+end
94+function bit.band(x,y,z, ...)
95+if not z then
96+return ((x or - 1) & (y or - 1)) & 4294967295
97+else
98+local arg = {...}
99+local res = x & y & z
100+for i = 1, # arg
101+do
102+res=res & arg[i]
103+end
104+return res & 4294967295
105+end
106+end
107+function bit.bor(x,y,z, ...)
108+if not z then
109+return ((x or 0) | (y or 0)) & 4294967295
110+else
111+local arg = {...}
112+local res = x | y | z
113+for i = 1, # arg
114+do
115+res=res | arg[i]
116+end
117+return res & 4294967295
118+end
119+end
120+function bit.bxor(x,y,z, ...)
121+if not z then
122+return ((x or 0) ~ (y or 0)) & 4294967295
123+else
124+local arg = {...}
125+local res = x ~ y ~ z
126+for i = 1, # arg
127+do
128+res=res ~ arg[i]
129+end
130+return res & 4294967295
131+end
132+end
133+function bit.btest(...)
134+return bit.band(...) ~= 0
135+end
136+function bit.lshift(a,b)
137+return ((a & 4294967295) << b) & 4294967295
138+end
139+function bit.rshift(a,b)
140+return ((a & 4294967295) >> b) & 4294967295
141+end
142+function bit.arshift(a,b)
143+a=a & 4294967295
144+if b <= 0 or (a & 2147483648) == 0 then
145+return (a >> b) & 4294967295
146+else
147+return ((a >> b) | ~ (4294967295 >> b)) & 4294967295
148+end
149+end
150+function bit.lrotate(a,b)
151+b=b & 31
152+a=a & 4294967295
153+a=(a << b) | (a >> (32 - b))
154+return a & 4294967295
155+end
156+function bit.rrotate(a,b)
157+return bit.lrotate(a,- b)
158+end
159+local function checkfield
160+(f,w)
161+w=w or 1
162+assert(f >= 0,"field cannot be negative")
163+assert(w > 0,"width must be positive")
164+assert(f + w <= 32,"trying to access non-existent bits")
165+return f,~ (- 1 << w)
166+end
167+function bit.extract(a,f,w)
168+local f,mask = checkfield(f,w)
169+return (a >> f) & mask
170+end
171+function bit.replace(a,v,f,w)
172+local f,mask = checkfield(f,w)
173+v=v & mask
174+a=(a & ~ (mask << f)) | (v << f)
175+return a & 4294967295
176+end
177+return bit
178+end
179+print("testing bitwise library")
180+local bit32 = require("bit32")
181+assert(bit32.band() == bit32.bnot(0))
182+assert(bit32.btest() == true)
183+assert(bit32.bor() == 0)
184+assert(bit32.bxor() == 0)
185+assert(bit32.band() == bit32.band(4294967295))
186+assert(bit32.band(1,2) == 0)
187+assert(bit32.band(- 1) == 4294967295)
188+assert(bit32.band((1 << 33) - 1) == 4294967295)
189+assert(bit32.band(- (1 << 33) - 1) == 4294967295)
190+assert(bit32.band((1 << 33) + 1) == 1)
191+assert(bit32.band(- (1 << 33) + 1) == 1)
192+assert(bit32.band(- (1 << 40)) == 0)
193+assert(bit32.band(1 << 40) == 0)
194+assert(bit32.band(- (1 << 40) - 2) == 4294967294)
195+assert(bit32.band((1 << 40) - 4) == 4294967292)
196+assert(bit32.lrotate(0,- 1) == 0)
197+assert(bit32.lrotate(0,7) == 0)
198+assert(bit32.lrotate(305419896,0) == 305419896)
199+assert(bit32.lrotate(305419896,32) == 305419896)
200+assert(bit32.lrotate(305419896,4) == 591751041)
201+assert(bit32.rrotate(305419896,- 4) == 591751041)
202+assert(bit32.lrotate(305419896,- 8) == 2014458966)
203+assert(bit32.rrotate(305419896,8) == 2014458966)
204+assert(bit32.lrotate(2863311530,2) == 2863311530)
205+assert(bit32.lrotate(2863311530,- 2) == 2863311530)
206+for i = - 50, 50
207+do
208+assert(bit32.lrotate(2309737967,i) == bit32.lrotate(2309737967,i % 32))
209+end
210+assert(bit32.lshift(305419896,4) == 591751040)
211+assert(bit32.lshift(305419896,8) == 878082048)
212+assert(bit32.lshift(305419896,- 4) == 19088743)
213+assert(bit32.lshift(305419896,- 8) == 1193046)
214+assert(bit32.lshift(305419896,32) == 0)
215+assert(bit32.lshift(305419896,- 32) == 0)
216+assert(bit32.rshift(305419896,4) == 19088743)
217+assert(bit32.rshift(305419896,8) == 1193046)
218+assert(bit32.rshift(305419896,32) == 0)
219+assert(bit32.rshift(305419896,- 32) == 0)
220+assert(bit32.arshift(305419896,0) == 305419896)
221+assert(bit32.arshift(305419896,1) == 305419896 // 2)
222+assert(bit32.arshift(305419896,- 1) == 305419896 * 2)
223+assert(bit32.arshift(- 1,1) == 4294967295)
224+assert(bit32.arshift(- 1,24) == 4294967295)
225+assert(bit32.arshift(- 1,32) == 4294967295)
226+assert(bit32.arshift(- 1,- 1) == bit32.band(- 1 * 2,4294967295))
227+assert(305419896 << 4 == 4886718336)
228+assert(305419896 << 8 == 78187493376)
229+assert(305419896 << - 4 == 19088743)
230+assert(305419896 << - 8 == 1193046)
231+assert(305419896 << 32 == 1311768464867721216)
232+assert(305419896 << - 32 == 0)
233+assert(305419896 >> 4 == 19088743)
234+assert(305419896 >> 8 == 1193046)
235+assert(305419896 >> 32 == 0)
236+assert(305419896 >> - 32 == 1311768464867721216)
237+print("+")
238+local c = {0,1,2,3,10,2147483648,2863311530,1431655765,4294967295,2147483647}
239+for _,b in pairs(c)
240+do
241+assert(bit32.band(b) == b)
242+assert(bit32.band(b,b) == b)
243+assert(bit32.band(b,b,b,b) == b)
244+assert(bit32.btest(b,b) == (b ~= 0))
245+assert(bit32.band(b,b,b) == b)
246+assert(bit32.band(b,b,b,~ b) == 0)
247+assert(bit32.btest(b,b,b) == (b ~= 0))
248+assert(bit32.band(b,bit32.bnot(b)) == 0)
249+assert(bit32.bor(b,bit32.bnot(b)) == bit32.bnot(0))
250+assert(bit32.bor(b) == b)
251+assert(bit32.bor(b,b) == b)
252+assert(bit32.bor(b,b,b) == b)
253+assert(bit32.bor(b,b,0,~ b) == 4294967295)
254+assert(bit32.bxor(b) == b)
255+assert(bit32.bxor(b,b) == 0)
256+assert(bit32.bxor(b,b,b) == b)
257+assert(bit32.bxor(b,b,b,b) == 0)
258+assert(bit32.bxor(b,0) == b)
259+assert(bit32.bnot(b) ~= b)
260+assert(bit32.bnot(bit32.bnot(b)) == b)
261+assert(bit32.bnot(b) == (1 << 32) - 1 - b)
262+assert(bit32.lrotate(b,32) == b)
263+assert(bit32.rrotate(b,32) == b)
264+assert(bit32.lshift(bit32.lshift(b,- 4),4) == bit32.band(b,bit32.bnot(15)))
265+assert(bit32.rshift(bit32.rshift(b,4),- 4) == bit32.band(b,bit32.bnot(15)))
266+end
267+c={0,1,2,3,10,8388608,11184810,5592405,16777215,8388607}
268+for _,b in pairs(c)
269+do
270+for i = - 40, 40
271+do
272+local x = bit32.lshift(b,i)
273+local y = math.floor(math.fmod(b * 2 ^ i,2 ^ 32))
274+assert(math.fmod(x - y,2 ^ 32) == 0)
275+end
276+end
277+assert(not pcall(bit32.band,{}))
278+assert(not pcall(bit32.bnot,"a"))
279+assert(not pcall(bit32.lshift,45))
280+assert(not pcall(bit32.lshift,45,print))
281+assert(not pcall(bit32.rshift,45,print))
282+print("+")
283+assert(bit32.extract(305419896,0,4) == 8)
284+assert(bit32.extract(305419896,4,4) == 7)
285+assert(bit32.extract(2684358929,28,4) == 10)
286+assert(bit32.extract(2684358929,31,1) == 1)
287+assert(bit32.extract(1342177553,31,1) == 0)
288+assert(bit32.extract(4063516281,0,32) == 4063516281)
289+assert(not pcall(bit32.extract,0,- 1))
290+assert(not pcall(bit32.extract,0,32))
291+assert(not pcall(bit32.extract,0,0,33))
292+assert(not pcall(bit32.extract,0,31,2))
293+assert(bit32.replace(305419896,5,28,4) == 1379161720)
294+assert(bit32.replace(305419896,2271560481,0,32) == 2271560481)
295+assert(bit32.replace(0,1,2) == 2 ^ 2)
296+assert(bit32.replace(0,- 1,4) == 2 ^ 4)
297+assert(bit32.replace(- 1,0,31) == (1 << 31) - 1)
298+assert(bit32.replace(- 1,0,1,2) == (1 << 32) - 7)
299+assert(bit32.bor(3) == 3)
300+assert(bit32.bor(- 4) == 4294967292)
301+if 2 ^ 50 < 2 ^ 50 + 1 and 2 ^ 50 < (- 1 >> 1) then
302+assert(bit32.bor(2 ^ 32 - 5) == 4294967291)
303+assert(bit32.bor(- 2 ^ 32 - 6) == 4294967290)
304+assert(bit32.bor(2 ^ 48 - 5) == 4294967291)
305+assert(bit32.bor(- 2 ^ 48 - 6) == 4294967290)
306+end
307+print("OK")
zod/luau/res/lua/cycled/bwcoercion.luanew file+59
@@ -0,0 +1,59 @@
1+local tonumber,tointeger = tonumber,math.tointeger
2+local type,getmetatable,rawget,error = type,getmetatable,rawget,error
3+local strsub = string.sub
4+local print = print
5+_ENV=nil
6+local function toint
7+(x)
8+x=tonumber(x)
9+if not x then
10+return false
11+end
12+return tointeger(x)
13+end
14+local function trymt
15+(x,y,mtname)
16+if type(y) ~= "string" then
17+local mt = getmetatable(y)
18+local mm = mt and rawget(mt,mtname)
19+if mm then
20+return mm(x,y)
21+end
22+end
23+error("attempt to '" .. strsub(mtname,3) .. "' a " .. type(x) .. " with a " .. type(y),4)
24+end
25+local function checkargs
26+(x,y,mtname)
27+local xi = toint(x)
28+local yi = toint(y)
29+if xi and yi then
30+return xi,yi
31+else
32+return trymt(x,y,mtname),nil
33+end
34+end
35+local smt = getmetatable("")
36+smt.__band=(x,y)
37+local x,y = checkargs(x,y,"__band")
38+return y and x & y or x
39+end
40+smt.__bor=(x,y)
41+local x,y = checkargs(x,y,"__bor")
42+return y and x | y or x
43+end
44+smt.__bxor=(x,y)
45+local x,y = checkargs(x,y,"__bxor")
46+return y and x ~ y or x
47+end
48+smt.__shl=(x,y)
49+local x,y = checkargs(x,y,"__shl")
50+return y and x << y or x
51+end
52+smt.__shr=(x,y)
53+local x,y = checkargs(x,y,"__shr")
54+return y and x >> y or x
55+end
56+smt.__bnot=(x)
57+local x,y = checkargs(x,x,"__bnot")
58+return y and ~ x or x
59+end
zod/luau/res/lua/cycled/calls.luanew file+483
@@ -0,0 +1,483 @@
1+print("testing functions and calls")
2+local debug = require("debug")
3+assert(type(1 < 2) == "boolean")
4+assert(type(true) == "boolean" and type(false) == "boolean")
5+assert(type(nil) == "nil" and type(- 3) == "number" and type("x") == "string" and type({}) == "table" and type(type) == "function")
6+assert(type(assert) == type(print))
7+local function f
8+(x)
9+return a:x(x)
10+end
11+assert(type(f) == "function")
12+assert(not pcall(type))
13+fact=false
14+local res = 1
15+local function fact
16+(n)
17+if n == 0 then
18+return res
19+else
20+return n * fact(n - 1)
21+end
22+end
23+assert(fact(5) == 120)
24+assert(fact == false)
25+fact=nil
26+local a = {["i"] = 10}
27+local self = 20
28+function a:x(x)
29+return x + self.i
30+end
31+function a.y(x)
32+return x + self
33+end
34+assert(a:x(1) + 10 == a.y(1))
35+a.t={["i"] = - 100}
36+a["t"].x=(self,a,b)
37+return self.i + a + b
38+end
39+assert(a.t:x(2,3) == - 95)
40+local a = {["x"] = 0}
41+function a:add(x)
42+self.x,a.y=self.x + x,20
43+;
44+return self
45+end
46+assert(a:add(10):add(20):add(30).x == 60 and a.y == 20)
47+local a = {["b"] = {["c"] = {}}}
48+function a.b.c.f1(x)
49+return x + 1
50+end
51+function a.b.c:f2(x,y)
52+self[x]=y
53+end
54+assert(a.b.c.f1(4) == 5)
55+a.b.c:f2("k",12)
56+;
57+assert(a.b.c.k == 12)
58+print("+")
59+t=nil
60+function f(a,b,c)
61+local d = "a"
62+;
63+t={a,b,c,d}
64+end
65+f(1,2)
66+assert(t[1] == 1 and t[2] == 2 and t[3] == nil and t[4] == "a")
67+f(1,2,3,4)
68+assert(t[1] == 1 and t[2] == 2 and t[3] == 3 and t[4] == "a")
69+t=nil
70+function fat(x)
71+if x <= 1 then
72+return 1
73+else
74+return x * load("return fat(" .. x - 1 .. ")","")()
75+end
76+end
77+assert(load("load 'assert(fat(6)==720)' () "))()
78+a=load("return fat(5), 3")
79+local a,b = a()
80+assert(a == 120 and b == 3)
81+fat=nil
82+print("+")
83+local function err_on_n
84+(n)
85+if n == 0 then
86+error()
87+;
88+exit(1)
89+;
90+else
91+err_on_n(n - 1)
92+;
93+exit(1)
94+;
95+end
96+end
97+local function dummy
98+(n)
99+if n > 0 then
100+assert(not pcall(err_on_n,n))
101+dummy(n - 1)
102+end
103+end
104+dummy(10)
105+_G.deep=nil
106+function deep(n)
107+if n > 0 then
108+deep(n - 1)
109+end
110+end
111+deep(10)
112+deep(180)
113+print("testing tail calls")
114+function deep(n)
115+if n > 0 then
116+return deep(n - 1)
117+else
118+return 101
119+end
120+end
121+assert(deep(3e4) == 101)
122+a={}
123+function a:deep(n)
124+if n > 0 then
125+return self:deep(n - 1)
126+else
127+return 101
128+end
129+end
130+assert(a:deep(3e4) == 101)
131+local function foo
132+(x, ...)
133+local a = {...}
134+;
135+return x,a[1],a[2]
136+end
137+local function foo1
138+(x)
139+return foo(10,x,x + 1)
140+end
141+local a,b,c = foo1(- 2)
142+assert(a == 10 and b == - 2 and c == - 1)
143+local t = setmetatable({},{["__call"] = foo})
144+local function foo2
145+(x)
146+return t(10,x)
147+end
148+a,b,c=foo2(100)
149+assert(a == t and b == 10 and c == 100)
150+a,b=(()
151+return foo()
152+end)()
153+assert(a == nil and b == nil)
154+local X,Y,A =
155+local function foo
156+(x,y, ...)
157+X=x
158+;
159+Y=y
160+;
161+A={...}
162+end
163+local function foo1
164+(...)
165+return foo(...)
166+end
167+local a,b,c = foo1()
168+assert(X == nil and Y == nil and # A == 0)
169+a,b,c=foo1(10)
170+assert(X == 10 and Y == nil and # A == 0)
171+a,b,c=foo1(10,20)
172+assert(X == 10 and Y == 20 and # A == 0)
173+a,b,c=foo1(10,20,30)
174+assert(X == 10 and Y == 20 and # A == 1 and A[1] == 30)
175+local function loop
176+()
177+assert(pcall(loop))
178+end
179+local err,msg = xpcall(loop,loop)
180+assert(not err and string.find(msg,"error"))
181+local n = 1e4
182+local function foo
183+()
184+if n == 0 then
185+return 1023
186+else
187+n=n - 1
188+;
189+return foo()
190+end
191+end
192+for i = 1, 100
193+do
194+foo=setmetatable({},{["__call"] = foo})
195+end
196+assert(coroutine.wrap(()
197+return foo()
198+end)() == 1023)
199+print("+")
200+local N = 20
201+local u = table.pack
202+for i = 1, N
203+do
204+u=setmetatable({i},{["__call"] = u})
205+end
206+local Res = u("a","b","c")
207+assert(Res.n == N + 3)
208+for i = 1, N
209+do
210+assert(Res[i][1] == i)
211+end
212+assert(Res[N + 1] == "a" and Res[N + 2] == "b" and Res[N + 3] == "c")
213+a=nil
214+((x)
215+a=x
216+end)(23)
217+assert(a == 23 and ((x)
218+return x * 2
219+end)(20) == 40)
220+local Z = (le)
221+local function a
222+(f)
223+return le((x)
224+return f(f)(x)
225+end)
226+end
227+return a(a)
228+end
229+local F = (f)
230+return (n)
231+if n == 0 then
232+return 1
233+else
234+return n * f(n - 1)
235+end
236+end
237+end
238+local fat = Z(F)
239+assert(fat(0) == 1 and fat(4) == 24 and Z(F)(5) == 5 * Z(F)(4))
240+local function g
241+(z)
242+local function f
243+(a,b,c,d)
244+return (x,y)
245+return a + b + c + d + a + x + y + z
246+end
247+end
248+return f(z,z + 1,z + 2,z + 3)
249+end
250+local f = g(10)
251+assert(f(9,16) == 10 + 11 + 12 + 13 + 10 + 9 + 16 + 10)
252+print("+")
253+local function unlpack
254+(t,i)
255+i=i or 1
256+if (i <= # t) then
257+return t[i],unlpack(t,i + 1)
258+end
259+end
260+local function equaltab
261+(t1,t2)
262+assert(# t1 == # t2)
263+for i = 1, # t1
264+do
265+assert(t1[i] == t2[i])
266+end
267+end
268+local pack = (...)
269+return (table.pack(...))
270+end
271+local function f
272+()
273+return 1,2,30,4
274+end
275+local function ret2
276+(a,b)
277+return a,b
278+end
279+local a,b,c,d = unlpack({1,2,3})
280+assert(a == 1 and b == 2 and c == 3 and d == nil)
281+a={1,2,3,4,false,10,"alo",false,assert}
282+equaltab(pack(unlpack(a)),a)
283+equaltab(pack(unlpack(a),- 1),{1,- 1})
284+a,b,c,d=ret2(f()),ret2(f())
285+assert(a == 1 and b == 1 and c == 2 and d == nil)
286+a,b,c,d=unlpack(pack(ret2(f()),ret2(f())))
287+assert(a == 1 and b == 1 and c == 2 and d == nil)
288+a,b,c,d=unlpack(pack(ret2(f()),(ret2(f()))))
289+assert(a == 1 and b == 1 and c == nil and d == nil)
290+a=ret2({unlpack({1,2,3}),unlpack({3,2,1}),unlpack({"a","b"})})
291+assert(a[1] == 1 and a[2] == 3 and a[3] == "a" and a[4] == "b")
292+rawget({},"x",1)
293+rawset({},"x",1,2)
294+assert(math.sin(1,2) == math.sin(1))
295+table.sort({10,9,8,4,19,23,0,0},(a,b)
296+return a < b
297+end,"extra arg")
298+local x = "-- a comment
299+ x = 10 +
300+23;
301+ local a = function () x = 'hi' end;
302+ return ''"
303+local function read1
304+(x)
305+local i = 0
306+return ()
307+collectgarbage()
308+i=i + 1
309+return string.sub(x,i,i)
310+end
311+end
312+local function cannotload
313+(msg,a,b)
314+assert(not a and string.find(b,msg))
315+end
316+a=assert(load(read1(x),"modname","t",_G))
317+assert(a() == "" and _G.x == 33)
318+assert(debug.getinfo(a).source == "modname")
319+cannotload("attempt to load a text chunk",load(read1(x),"modname","b",{}))
320+cannotload("attempt to load a text chunk",load(x,"modname","b"))
321+a=assert(load(()
322+return nil
323+end))
324+a()
325+assert(not load(()
326+return true
327+end))
328+local t = {nil,"return ","3"}
329+f,msg=load(()
330+return table.remove(t,1)
331+end)
332+assert(f() == nil)
333+f=load(string.dump(()
334+return 1
335+end),nil,"b",{})
336+assert(type(f) == "function" and f() == 1)
337+local f = string.dump(()
338+return "01234567890123456789012345678901234567890123456789"
339+end)
340+f=load(read1(f))
341+assert(f() == "01234567890123456789012345678901234567890123456789")
342+x=string.dump(load("x = 1; return x"))
343+a=assert(load(read1(x),nil,"b"))
344+assert(a() == 1 and _G.x == 1)
345+cannotload("attempt to load a binary chunk",load(read1(x),nil,"t"))
346+cannotload("attempt to load a binary chunk",load(x,nil,"t"))
347+_G.x=nil
348+assert(not pcall(string.dump,print))
349+cannotload("unexpected symbol",load(read1("*a = 123")))
350+cannotload("unexpected symbol",load("*a = 123"))
351+cannotload("hhi",load(()
352+error("hhi")
353+end))
354+assert(load("return _ENV",nil,nil,123)() == 123)
355+local x =
356+;
357+XX=123
358+local function h
359+()
360+local y = x
361+return XX
362+end
363+local d = string.dump(h)
364+x=load(d,"","b")
365+assert(debug.getupvalue(x,2) == "_ENV")
366+debug.setupvalue(x,2,_G)
367+assert(x() == 123)
368+assert(assert(load("return XX + ...",nil,nil,{["XX"] = 13}))(4) == 17)
369+XX=nil
370+x=" return function (x)
371+ return function (y)
372+ return function (z)
373+ return x+y+z
374+ end
375+ end
376+ end
377+"
378+a=assert(load(read1(x),"read","t"))
379+assert(a()(2)(3)(10) == 15)
380+x=string.dump(a)
381+a=assert(load(read1(x),"read","b"))
382+assert(a()(2)(3)(10) == 15)
383+local a,b = 20,30
384+x=load(string.dump((x)
385+if x == "set" then
386+a=10 + b
387+;
388+b=b + 1
389+else
390+return a
391+end
392+end),"","b",nil)
393+assert(x() == nil)
394+assert(debug.setupvalue(x,1,"hi") == "a")
395+assert(x() == "hi")
396+assert(debug.setupvalue(x,2,13) == "b")
397+assert(not debug.setupvalue(x,3,10))
398+x("set")
399+assert(x() == 23)
400+x("set")
401+assert(x() == 24)
402+local nup = 200
403+local prog = {"local a1"}
404+for i = 2, nup
405+do
406+prog[# prog + 1]=", a" .. i
407+end
408+prog[# prog + 1]=" = 1"
409+for i = 2, nup
410+do
411+prog[# prog + 1]=", " .. i
412+end
413+local sum = 1
414+prog[# prog + 1]="; return function () return a1"
415+for i = 2, nup
416+do
417+prog[# prog + 1]=" + a" .. i
418+;
419+sum=sum + i
420+end
421+prog[# prog + 1]=" end"
422+prog=table.concat(prog)
423+local f = assert(load(prog))()
424+assert(f() == sum)
425+f=load(string.dump(f))
426+local a = 10
427+local h = ()
428+return a
429+end
430+for i = 1, nup
431+do
432+debug.upvaluejoin(f,i,h,1)
433+end
434+assert(f() == 10 * nup)
435+local t = {["x"] = 1}
436+function t:_012345678901234567890123456789012345678901234567890123456789()
437+return self.x
438+end
439+assert(t:_012345678901234567890123456789012345678901234567890123456789() == 1)
440+assert((()
441+return nil
442+end)(4) == nil)
443+assert((()
444+local a =
445+;
446+return a
447+end)(4) == nil)
448+assert(((a)
449+return a
450+end)() == nil)
451+print("testing binary chunks")
452+local header = string.pack("c4BBc6BBB","Lua",84,0,"�
453+
454+",4,string.packsize("j"),string.packsize("n"))
455+local c = string.dump(()
456+local a = 1
457+;
458+local b = 3
459+;
460+local f = ()
461+return a + b + _ENV.c
462+end
463+local s1 = "a constant"
464+local s2 = "another constant"
465+return a + b * 3
466+end)
467+assert(assert(load(c))() == 10)
468+assert(string.sub(c,1,# header) == header)
469+local ci,cn = string.unpack("jn",c,# header + 1)
470+assert(ci == 22136 and cn == 370.5)
471+for i = 1, # header
472+do
473+local s = string.sub(c,1,i - 1) .. string.char(string.byte(string.sub(c,i,i)) + 1) .. string.sub(c,i + 1,- 1)
474+assert(# s == # c)
475+assert(not load(s))
476+end
477+for i = 1, # c - 1
478+do
479+local st,msg = load(string.sub(c,1,i))
480+assert(not st and string.find(msg,"truncated"))
481+end
482+print("OK")
483+return deep
zod/luau/res/lua/cycled/closure.luanew file+309
@@ -0,0 +1,309 @@
1+print("testing closures")
2+local A,B = 0,{["g"] = 10}
3+local function f
4+(x)
5+local a = {}
6+for i = 1, 1e3
7+do
8+local y = 0
9+a[i]=()
10+B.g=B.g + 1
11+;
12+y=y + x
13+;
14+return y + A
15+end
16+end
17+local dummy = ()
18+return a[A]
19+end
20+collectgarbage()
21+A=1
22+;
23+assert(dummy() == a[1])
24+;
25+A=0
26+;
27+assert(a[1]() == x)
28+assert(a[3]() == x)
29+collectgarbage()
30+assert(B.g == 12)
31+return a
32+end
33+local a = f(10)
34+local x = {[1] = {}}
35+setmetatable(x,{["__mode"] = "kv"})
36+while x[1] do
37+local a = A .. A .. A .. A
38+A=A + 1
39+assert(a[1]() == 20 + A)
40+assert(a[1]() == 30 + A)
41+assert(a[2]() == 10 + A)
42+collectgarbage()
43+assert(a[2]() == 20 + A)
44+assert(a[2]() == 30 + A)
45+assert(a[3]() == 20 + A)
46+assert(a[8]() == 10 + A)
47+assert(getmetatable(x).__mode == "kv")
48+assert(B.g == 19)
49+a={}
50+for i = 1, 5
51+do
52+a[i]=(x)
53+return i + a + _ENV
54+end
55+end
56+assert(a[3] ~= a[4] and a[4] ~= a[5])
57+local a = (x)
58+return math.sin(_ENV[x])
59+end
60+local function f
61+()
62+return a
63+end
64+assert(f() == f())
65+a={}
66+for i = 1, 10
67+do
68+a[i]={["set"] = (x)
69+i=x
70+end,["get"] = ()
71+return i
72+end}
73+if i == 3 then
74+break
75+end
76+end
77+assert(a[4] == undef)
78+a[1].set(10)
79+assert(a[2].get() == 2)
80+a[2].set("a")
81+assert(a[3].get() == 3)
82+assert(a[2].get() == "a")
83+a={}
84+local t = {"a","b"}
85+for i = 1, # t
86+do
87+local k = t[i]
88+a[i]={["set"] = (x,y)
89+i=x
90+;
91+k=y
92+end,["get"] = ()
93+return i,k
94+end}
95+if i == 2 then
96+break
97+end
98+end
99+a[1].set(10,20)
100+local r,s = a[2].get()
101+assert(r == 2 and s == "b")
102+r,s=a[1].get()
103+assert(r == 10 and s == 20)
104+a[2].set("a","b")
105+r,s=a[2].get()
106+assert(r == "a" and s == "b")
107+local f =
108+for i = 1, 3
109+do
110+f=()
111+return i
112+end
113+break
114+end
115+assert(f() == 1)
116+for k = 1, # t
117+do
118+local v = t[k]
119+f=()
120+return k,v
121+end
122+break
123+end
124+assert(({f()})[1] == 1)
125+assert(({f()})[2] == "a")
126+local b =
127+function f(x)
128+local first = 1
129+while 1 do
130+if x == 3 and not first then
131+return
132+end
133+local a = "xuxu"
134+b=(op,y)
135+if op == "set" then
136+a=x + y
137+else
138+return a
139+end
140+end
141+if x == 1 then
142+break
143+elseifx == 2 then
144+return
145+else
146+if x ~= 3 then
147+error()
148+end
149+end
150+first=nil
151+end
152+for i = 1, 3
153+do
154+f(i)
155+assert(b("get") == "xuxu")
156+b("set",10)
157+;
158+assert(b("get") == 10 + i)
159+b=nil
160+end
161+pcall(f,4)
162+;
163+assert(b("get") == "xuxu")
164+b("set",10)
165+;
166+assert(b("get") == 14)
167+local y,w =
168+function f(x)
169+return (y)
170+return (z)
171+return w + x + y + z
172+end
173+end
174+end
175+y=f(10)
176+w=1.345
177+assert(y(20)(30) == 60 + w)
178+local X,Y =
179+local a = math.sin(0)
180+while a do
181+local b = 10
182+X=()
183+return b
184+end
185+if a then
186+break
187+end
188+local b = 20
189+Y=()
190+return b
191+end
192+assert(X() == 10 and Y() == 20)
193+local a = {}
194+local i = 1
195+repeat
196+local x = i
197+a[i]=()
198+i=x + 1
199+;
200+return x
201+enduntil i > 10 or a[i]() ~= x
202+assert(i == 11 and a[1]() == 1 and a[3]() == 3 and i == 4)
203+a={}
204+for i = 1, 10
205+do
206+if i % 3 == 0 then
207+local y = 0
208+a[i]=(x)
209+local t = y
210+;
211+y=x
212+;
213+return t
214+end
215+elseifi % 3 == 1 then
216+goto L1
217+error("not here")
218+::L1::
219+local y = 1
220+a[i]=(x)
221+local t = y
222+;
223+y=x
224+;
225+return t
226+end
227+elseifi % 3 == 2 then
228+local t =
229+goto l4
230+::l4a::
231+a[i]=t
232+;
233+goto l4b
234+error("should never be here!")
235+::l4::
236+local y = 2
237+t=(x)
238+local t = y
239+;
240+y=x
241+;
242+return t
243+end
244+goto l4a
245+error("should never be here!")
246+::l4b::
247+end
248+end
249+for i = 1, 10
250+do
251+assert(a[i](i * 10) == i % 3 and a[i]() == i * 10)
252+end
253+print("+")
254+local function t
255+()
256+local function c
257+(a,b)
258+assert(a == "test" and b == "OK")
259+end
260+local function v
261+(f, ...)
262+c("test",f() ~= 1 and "FAILED" or "OK")
263+end
264+local x = 1
265+return v(()
266+return x
267+end)
268+end
269+t()
270+local debug = require("debug")
271+local foo1,foo2,foo3 =
272+local a,b,c = 3,5,7
273+foo1=()
274+return a + b
275+end
276+;
277+foo2=()
278+return b + a
279+end
280+;
281+local a = 10
282+foo3=()
283+return a + b
284+end
285+;
286+assert(debug.upvalueid(foo1,1))
287+assert(debug.upvalueid(foo1,2))
288+assert(not debug.upvalueid(foo1,3))
289+assert(debug.upvalueid(foo1,1) == debug.upvalueid(foo2,2))
290+assert(debug.upvalueid(foo1,2) == debug.upvalueid(foo2,1))
291+assert(debug.upvalueid(foo3,1))
292+assert(debug.upvalueid(foo1,1) ~= debug.upvalueid(foo3,1))
293+assert(debug.upvalueid(foo1,2) == debug.upvalueid(foo3,2))
294+assert(debug.upvalueid(string.gmatch("x","x"),1) ~= nil)
295+assert(foo1() == 3 + 5 and foo2() == 5 + 3)
296+debug.upvaluejoin(foo1,2,foo2,2)
297+assert(foo1() == 3 + 3 and foo2() == 5 + 3)
298+assert(foo3() == 10 + 5)
299+debug.upvaluejoin(foo3,2,foo2,1)
300+assert(foo3() == 10 + 5)
301+debug.upvaluejoin(foo3,2,foo2,2)
302+assert(foo3() == 10 + 3)
303+assert(not pcall(debug.upvaluejoin,foo1,3,foo2,1))
304+assert(not pcall(debug.upvaluejoin,foo1,1,foo2,3))
305+assert(not pcall(debug.upvaluejoin,foo1,0,foo2,1))
306+assert(not pcall(debug.upvaluejoin,print,1,foo2,1))
307+assert(not pcall(debug.upvaluejoin,{},1,foo2,1))
308+assert(not pcall(debug.upvaluejoin,foo1,1,print,1))
309+print("OK")
zod/luau/res/lua/cycled/code.luanew file+576
@@ -0,0 +1,576 @@
1+if T == nil then
2+(Message or print)("
3+ >>> testC not active: skipping opcode tests <<<
4+")
5+return
6+end
7+print("testing code generation and optimizations")
8+local k0aux <const> = 0
9+local k0 <const> = k0aux
10+local k1 <const> = 1
11+local k3 <const> = 3
12+local k6 <const> = k3 + (k3 << k0)
13+local kFF0 <const> = 4080
14+local k3_78 <const> = 3.78
15+local x,k3_78_4 <const> = 10,k3_78 / 4
16+assert(x == 10)
17+local kx <const> = "x"
18+local kTrue <const> = true
19+local kFalse <const> = false
20+local kNil <const> = nil
21+local function f
22+(a)
23+for k,v,w in a
24+do
25+
26+end
27+end
28+local function checkKlist
29+(func,list)
30+local k = T.listk(func)
31+assert(# k == # list)
32+for i = 1, # k
33+do
34+assert(k[i] == list[i] and math.type(k[i]) == math.type(list[i]))
35+end
36+end
37+local function foo
38+()
39+local a =
40+a=k3
41+;
42+a=0
43+;
44+a=0
45+;
46+a=- 7 + 7
47+a=k3_78 / 4
48+;
49+a=k3_78_4
50+a=- k3_78 / 4
51+;
52+a=k3_78 / 4
53+;
54+a=- 3.78 / 4
55+a=- 3.79 / 4
56+;
57+a=0
58+;
59+a=- 0
60+;
61+a=k3
62+;
63+a=3
64+;
65+a=3
66+;
67+a=3
68+end
69+checkKlist(foo,{3.78 / 4,- 3.78 / 4,- 3.79 / 4})
70+foo=(f,a)
71+f(100 * 1e3)
72+f(100 * 1e3)
73+f(- 100 * 1e3)
74+f(- 100 * 1e3)
75+f(1e5)
76+f(1e5)
77+f(- 1e5)
78+f(- 1e5)
79+end
80+checkKlist(foo,{1e5,1e5,- 1e5,- 1e5})
81+foo=(t,a)
82+t[a]=1
83+;
84+t[a]=1
85+t[a]=1
86+;
87+t[a]=1
88+t[a]=2
89+;
90+t[a]=2
91+t[a]=0
92+;
93+t[a]=0
94+t[a]=1
95+;
96+t[a]=1
97+t[a]=2
98+;
99+t[a]=2
100+t[a]=0
101+;
102+t[a]=0
103+end
104+checkKlist(foo,{1,1,2,2,0,0})
105+local function check
106+(f, ...)
107+local arg = {...}
108+local c = T.listcode(f)
109+for i = 1, # arg
110+do
111+local opcode = string.match(c[i],"%u%w+")
112+assert(arg[i] == opcode)
113+end
114+assert(c[# arg + 2] == undef)
115+end
116+local function checkR
117+(f,p,r, ...)
118+local r1 = f(p)
119+assert(r == r1 and math.type(r) == math.type(r1))
120+check(f,...)
121+end
122+local function checkequal
123+(a,b)
124+a=T.listcode(a)
125+b=T.listcode(b)
126+assert(# a == # b)
127+for i = 1, # a
128+do
129+a[i]=string.gsub(a[i],"%b()","")
130+b[i]=string.gsub(b[i],"%b()","")
131+assert(a[i] == b[i])
132+end
133+end
134+check(()
135+(()
136+
137+end)({f()})
138+end,"CLOSURE","NEWTABLE","EXTRAARG","GETTABUP","CALL","SETLIST","CALL","RETURN0")
139+check((x)
140+(()
141+return x
142+end)({f()})
143+end,"CLOSURE","NEWTABLE","EXTRAARG","GETTABUP","CALL","SETLIST","CALL","RETURN")
144+check(()
145+local kNil <const> = nil
146+local a,b,c =
147+local d =
148+;
149+local e =
150+;
151+local f,g,h =
152+;
153+d=nil
154+;
155+d=nil
156+;
157+b=nil
158+;
159+a=kNil
160+;
161+c=nil
162+;
163+end,"LOADNIL","RETURN0")
164+check(()
165+local a,b,c,d = 1,1,1,1
166+d=nil
167+;
168+c=nil
169+;
170+b=nil
171+;
172+a=nil
173+end,"LOADI","LOADI","LOADI","LOADI","LOADNIL","RETURN0")
174+local a,b,c,d = 1,1,1,1
175+d=nil
176+;
177+c=nil
178+;
179+b=nil
180+;
181+a=nil
182+assert(a == nil and b == nil and c == nil and d == nil)
183+check((a,b,c)
184+return a
185+end,"RETURN1")
186+check(()
187+while kTrue do
188+local a = - 1
189+end,"LOADI","JMP","RETURN0")
190+check(()
191+while 1 do
192+local a = - 1
193+end,"LOADI","JMP","RETURN0")
194+check(()
195+repeat
196+local x = 1until true
197+end,"LOADI","RETURN0")
198+check((a,b,c,d)
199+return a .. b .. c .. d
200+end,"MOVE","MOVE","MOVE","MOVE","CONCAT","RETURN1")
201+check(()
202+return not not nil
203+end,"LOADFALSE","RETURN1")
204+check(()
205+return not not kFalse
206+end,"LOADFALSE","RETURN1")
207+check(()
208+return not not true
209+end,"LOADTRUE","RETURN1")
210+check(()
211+return not not k3
212+end,"LOADTRUE","RETURN1")
213+check(()
214+local a,b,c,d =
215+a=b * a
216+c.x,a[b]=- ((a + d / b - a[b]) ^ a.x),b
217+end,"LOADNIL","MUL","MMBIN","DIV","MMBIN","ADD","MMBIN","GETTABLE","SUB","MMBIN","GETFIELD","POW","MMBIN","UNM","SETTABLE","SETFIELD","RETURN0")
218+check(()
219+local a,b =
220+local c = kNil
221+a[kx]=3.2
222+a.x=b
223+a[b]="x"
224+end,"LOADNIL","SETFIELD","SETFIELD","SETTABLE","RETURN0")
225+check((a)
226+local k255 <const> = 255
227+a[1]=a[100]
228+a[k255]=a[256]
229+a[256]=5
230+end,"GETI","SETI","LOADI","GETTABLE","SETI","LOADI","SETTABLE","RETURN0")
231+check(()
232+local a,b =
233+a=a - a
234+b=a / a
235+b=5 - 4
236+end,"LOADNIL","SUB","MMBIN","DIV","MMBIN","LOADI","RETURN0")
237+check(()
238+local a,b =
239+a[kTrue]=false
240+end,"LOADNIL","LOADTRUE","SETTABLE","RETURN0")
241+checkR((a)
242+if a == 1 then
243+return 2
244+end
245+end,1,2,"EQI","JMP","LOADI","RETURN1")
246+checkR((a)
247+if - 4 == a then
248+return 2
249+end
250+end,- 4,2,"EQI","JMP","LOADI","RETURN1")
251+checkR((a)
252+if a == "hi" then
253+return 2
254+end
255+end,10,nil,"EQK","JMP","LOADI","RETURN1")
256+checkR((a)
257+if a == 1e4 then
258+return 2
259+end
260+end,1,nil,"EQK","JMP","LOADI","RETURN1")
261+checkR((a)
262+if - 1e4 == a then
263+return 2
264+end
265+end,- 1e4,2,"EQK","JMP","LOADI","RETURN1")
266+checkR((a)
267+if - 10 <= a then
268+return 2
269+end
270+end,- 10,2,"GEI","JMP","LOADI","RETURN1")
271+checkR((a)
272+if 128 > a then
273+return 2
274+end
275+end,129,nil,"LTI","JMP","LOADI","RETURN1")
276+checkR((a)
277+if - 127 < a then
278+return 2
279+end
280+end,- 127,nil,"GTI","JMP","LOADI","RETURN1")
281+checkR((a)
282+if 10 < a then
283+return 2
284+end
285+end,11,2,"GTI","JMP","LOADI","RETURN1")
286+checkR((a)
287+if 129 < a then
288+return 2
289+end
290+end,130,2,"LOADI","LT","JMP","LOADI","RETURN1")
291+checkR((a)
292+if a >= 23 then
293+return 2
294+end
295+end,25,2,"GEI","JMP","LOADI","RETURN1")
296+checkR((a)
297+if a >= 23.1 then
298+return 2
299+end
300+end,0,nil,"LOADK","LE","JMP","LOADI","RETURN1")
301+checkR((a)
302+if a > 2300 then
303+return 2
304+end
305+end,0,nil,"LOADF","LT","JMP","LOADI","RETURN1")
306+local function checkK
307+(func,val)
308+check(func,"LOADK","RETURN1")
309+checkKlist(func,{val})
310+assert(func() == val)
311+end
312+local function checkI
313+(func,val)
314+check(func,"LOADI","RETURN1")
315+checkKlist(func,{})
316+assert(func() == val)
317+end
318+local function checkF
319+(func,val)
320+check(func,"LOADF","RETURN1")
321+checkKlist(func,{})
322+assert(func() == val)
323+end
324+checkF(()
325+return 0
326+end,0)
327+checkI(()
328+return k0
329+end,0)
330+checkI(()
331+return - k0 // 1
332+end,0)
333+checkK(()
334+return 3 ^ - 1
335+end,1 / 3)
336+checkK(()
337+return (1 + 1) ^ (50 + 50)
338+end,2 ^ 100)
339+checkK(()
340+return (- 2) ^ (31 - 2)
341+end,- 536870912 + 0)
342+checkF(()
343+return (- k3 ^ 0 + 5) // 3
344+end,1)
345+checkI(()
346+return - k3 % 5
347+end,2)
348+checkF(()
349+return - ((2 ^ 8 + - (- 1)) % 8) / 2 * 4 - 3
350+end,- 5)
351+checkF(()
352+return - ((2 ^ 8 + - (- 1)) % 8) // 2 * 4 - 3
353+end,- 7)
354+checkI(()
355+return 240 | 204 ~ 170 & 253
356+end,244)
357+checkI(()
358+return ~ (~ kFF0 | kFF0)
359+end,0)
360+checkI(()
361+return ~ ~ - 1024
362+end,- 1024)
363+checkI(()
364+return ((100 << k6) << - 4) >> 2
365+end,100)
366+local a = 17
367+;
368+local sbx = ((1 << a) - 1) >> 1
369+local border <const> = 65535
370+checkI(()
371+return border
372+end,sbx)
373+checkI(()
374+return - border
375+end,- sbx)
376+checkI(()
377+return border + 1
378+end,sbx + 1)
379+checkK(()
380+return border + 2
381+end,sbx + 2)
382+checkK(()
383+return - (border + 1)
384+end,- (sbx + 1))
385+local border <const> = 65535
386+checkF(()
387+return border
388+end,sbx + 0)
389+checkF(()
390+return - border
391+end,- sbx + 0)
392+checkF(()
393+return border + 1
394+end,(sbx + 1))
395+checkK(()
396+return border + 2
397+end,(sbx + 2))
398+checkK(()
399+return - (border + 1)
400+end,- (sbx + 1))
401+checkR((x)
402+return x + k1
403+end,10,11,"ADDI","MMBINI","RETURN1")
404+checkR((x)
405+return x - 127
406+end,10,- 117,"ADDI","MMBINI","RETURN1")
407+checkR((x)
408+return 128 + x
409+end,0,128,"ADDI","MMBINI","RETURN1")
410+checkR((x)
411+return x * - 127
412+end,- 1,127,"MULK","MMBINK","RETURN1")
413+checkR((x)
414+return 20 * x
415+end,2,40,"MULK","MMBINK","RETURN1")
416+checkR((x)
417+return x ^ - 2
418+end,2,0.25,"POWK","MMBINK","RETURN1")
419+checkR((x)
420+return x / 40
421+end,40,1,"DIVK","MMBINK","RETURN1")
422+checkR((x)
423+return x // 1
424+end,10,10,"IDIVK","MMBINK","RETURN1")
425+checkR((x)
426+return x % (100 - 10)
427+end,91,1,"MODK","MMBINK","RETURN1")
428+checkR((x)
429+return k1 << x
430+end,3,8,"SHLI","MMBINI","RETURN1")
431+checkR((x)
432+return x << 127
433+end,10,0,"SHRI","MMBINI","RETURN1")
434+checkR((x)
435+return x << - 127
436+end,10,0,"SHRI","MMBINI","RETURN1")
437+checkR((x)
438+return x >> 128
439+end,8,0,"SHRI","MMBINI","RETURN1")
440+checkR((x)
441+return x >> - 127
442+end,8,0,"SHRI","MMBINI","RETURN1")
443+checkR((x)
444+return x & 1
445+end,9,1,"BANDK","MMBINK","RETURN1")
446+checkR((x)
447+return 10 | x
448+end,1,11,"BORK","MMBINK","RETURN1")
449+checkR((x)
450+return - 10 ~ x
451+end,- 1,9,"BXORK","MMBINK","RETURN1")
452+checkR((x)
453+return x + 0
454+end,1,1,"ADDK","MMBINK","RETURN1")
455+checkR((x)
456+return x * - 1e4
457+end,2,- 2e4,"MULK","MMBINK","RETURN1")
458+checkR((x)
459+return x ^ 0.5
460+end,4,2,"POWK","MMBINK","RETURN1")
461+checkR((x)
462+return x / 2
463+end,4,2,"DIVK","MMBINK","RETURN1")
464+checkR((x)
465+return x // 1e4
466+end,1e4,1,"IDIVK","MMBINK","RETURN1")
467+checkR((x)
468+return x % (100 - 10)
469+end,91,1,"MODK","MMBINK","RETURN1")
470+check(()
471+return - 0
472+end,"LOADF","UNM","RETURN1")
473+check(()
474+return k3 / 0
475+end,"LOADI","DIVK","MMBINK","RETURN1")
476+check(()
477+return 0 % 0
478+end,"LOADI","MODK","MMBINK","RETURN1")
479+check(()
480+return - 4 // 0
481+end,"LOADI","IDIVK","MMBINK","RETURN1")
482+check((x)
483+return x >> 2
484+end,"LOADF","SHR","MMBIN","RETURN1")
485+check((x)
486+return x << 128
487+end,"LOADI","SHL","MMBIN","RETURN1")
488+check((x)
489+return x & 2
490+end,"LOADF","BAND","MMBIN","RETURN1")
491+check(()
492+for i = - 10, 10.5
493+do
494+
495+end
496+end,"LOADI","LOADK","LOADI","FORPREP","FORLOOP","RETURN0")
497+check(()
498+for i = 268435455, 10, 1
499+do
500+
501+end
502+end,"LOADK","LOADF","LOADI","FORPREP","FORLOOP","RETURN0")
503+check(()
504+return - nil
505+end,"LOADNIL","UNM","RETURN1")
506+check(()
507+local a,b,c =
508+b[c],a=c,b
509+b[a],a=c,b
510+a,b=c,a
511+a=a
512+end,"LOADNIL","MOVE","MOVE","SETTABLE","MOVE","MOVE","MOVE","SETTABLE","MOVE","MOVE","MOVE","RETURN0")
513+local t =
514+check(()
515+t[kx]=t.y
516+end,"GETTABUP","SETTABUP")
517+check((a)
518+t[a()]=t[a()]
519+end,"MOVE","CALL","GETUPVAL","MOVE","CALL","GETUPVAL","GETTABLE","SETTABLE")
520+checkequal(()
521+local a =
522+;
523+if not (a or b) then
524+b=a
525+end
526+end,()
527+local a =
528+;
529+if (not a and not b) then
530+b=a
531+end
532+end)
533+checkequal((l)
534+local a =
535+;
536+return 0 <= a and a <= l
537+end,(l)
538+local a =
539+;
540+return not (not (a >= 0) or not (a <= l))
541+end)
542+check((a,b)
543+while a do
544+if b then
545+break
546+else
547+a=a + 1
548+end
549+end,"TEST","JMP","TEST","JMP","ADDI","MMBINI","JMP","RETURN0")
550+checkequal(()
551+return 6 or true or nil
552+end,()
553+return k6 or kTrue or kNil
554+end)
555+checkequal(()
556+return 6 and true or nil
557+end,()
558+return k6 and kTrue or kNil
559+end)
560+local k0 <const> = "00000000000000000000000000000000000000000000000000"
561+local function f1
562+()
563+local k <const> = k0
564+return ()
565+return ()
566+return k
567+end
568+end
569+end
570+local f2 = f1()
571+local f3 = f2()
572+assert(f3() == k0)
573+checkK(f3,k0)
574+assert(T.listk(f1)[1] == nil)
575+assert(T.listk(f2)[1] == nil)
576+print("OK")
zod/luau/res/lua/cycled/constructs.luanew file+466
@@ -0,0 +1,466 @@
1+;
2+;
3+print("testing syntax")
4+;
5+;
6+local debug = require("debug")
7+local function checkload
8+(s,msg)
9+assert(string.find(select(2,load(s)),msg))
10+end
11+local a =
12+;
13+;
14+;
15+;
16+;
17+a=3
18+;
19+assert(a == 3)
20+;
21+;
22+if false then
23+a=3 // 0
24+;
25+a=0 % 0
26+end
27+assert(2 ^ 3 ^ 2 == 2 ^ (3 ^ 2))
28+;
29+assert(2 ^ 3 * 4 == (2 ^ 3) * 4)
30+;
31+assert(2 ^ - 2 == 1 / 4 and - 2 ^ - - 2 == - - - 4)
32+;
33+assert(not nil and 2 and not (2 > 3 or 3 < 2))
34+;
35+assert(- 3 - 1 - 5 == 0 + 0 - 9)
36+;
37+assert(- 2 ^ 2 == - 4 and (- 2) ^ 2 == 4 and 2 * 2 - 3 - 1 == 0)
38+;
39+assert(- 3 % 5 == 2 and - 3 + 5 == 2)
40+assert(2 * 1 + 3 / 3 == 3 and 1 + 2 .. 3 * 1 == "33")
41+;
42+assert(not (2 + 1 > 3 * 1) and "a" .. "b" > "a")
43+;
44+assert(240 | 204 ~ 170 & 253 == 244)
45+assert(253 & 170 ~ 204 | 240 == 244)
46+assert(240 & 15 + 1 == 16)
47+assert(3 ^ 4 // 2 ^ 3 // 5 == 2)
48+assert(- 3 + 4 * 5 // 2 ^ 3 ^ 2 // 9 + 4 % 10 / 3 == (- 3) + (((4 * 5) // (2 ^ (3 ^ 2))) // 9) + ((4 % 10) / 3))
49+assert(not ((true or false) and nil))
50+assert(true or false and nil)
51+assert((((1 or false) and true) or false) == true)
52+assert((((nil and true) or false) and true) == false)
53+local a,b = 1,nil
54+;
55+assert(- (1 or 2) == - 1 and (1 and 2) + (- 1.25 or - 4) == 0.75)
56+;
57+local x = ((b or a) + 1 == 2 and (10 or a) + 1 == 11)
58+;
59+assert(x)
60+;
61+x=(((2 < 3) or 1) == true and (2 < 3 and 4) == 4)
62+;
63+assert(x)
64+;
65+local x,y = 1,2
66+;
67+assert((x > y) and x or y == 2)
68+;
69+x,y=2,1
70+;
71+assert((x > y) and x or y == 2)
72+;
73+assert(1234567890 == tonumber("1234567890") and 1234567890 + 1 == 1234567891)
74+local operand = {3,100,5,- 10,- 5,1e4,- 1e4}
75+local operator = {"+","-","*","/","//","%","^","&","|","^","<<",">>","==","~=","<",">","<=",">="}
76+for _,op in ipairs(operator)
77+do
78+local f = assert(load(string.format("return function (x,y)
79+ return x %s y
80+ end",op)))()
81+;
82+for _,o1 in ipairs(operand)
83+do
84+for _,o2 in ipairs(operand)
85+do
86+local gab = f(o1,o2)
87+_ENV.XX=o1
88+local code = string.format("return XX %s %s",op,o2)
89+local res = assert(load(code))()
90+assert(res == gab)
91+_ENV.XX=o2
92+code=string.format("return (%s) %s XX",o1,op)
93+res=assert(load(code))()
94+assert(res == gab)
95+code=string.format("return (%s) %s %s",o1,op,o2)
96+res=assert(load(code))()
97+assert(res == gab)
98+end
99+end
100+end
101+_ENV.XX=nil
102+repeat
103+until 1
104+;
105+repeat
106+until true
107+;
108+while false do
109+
110+;
111+while nil do
112+
113+;
114+local a =
115+;
116+local function f
117+(x)
118+x={["a"] = 1}
119+;
120+x={["x"] = 1}
121+;
122+x={["G"] = 1}
123+end
124+local code = {"local x = {"}
125+for i = 1, 257
126+do
127+code[# code + 1]=i .. ".1,"
128+end
129+code[# code + 1]="};"
130+code=table.concat(code)
131+local function check
132+(ret,val)
133+local code = code .. ret
134+code=load(code)
135+assert(code() == val)
136+end
137+check("return (1 ~ (2 or 3))",1 ~ 2)
138+check("return (1 | (2 or 3))",1 | 2)
139+check("return (1 + (2 or 3))",1 + 2)
140+check("return (1 << (2 or 3))",1 << 2)
141+local function f
142+(i)
143+if type(i) ~= "number" then
144+return i,"jojo"
145+end
146+;
147+if i > 0 then
148+return i,f(i - 1)
149+end
150+;
151+end
152+x={f(3),f(5),f(10)}
153+;
154+assert(x[1] == 3 and x[2] == 5 and x[3] == 10 and x[4] == 9 and x[12] == 1)
155+;
156+assert(x[nil] == nil)
157+x={f("alo"),f("xixi"),nil}
158+;
159+assert(x[1] == "alo" and x[2] == "xixi" and x[3] == nil)
160+;
161+x={f("alo") .. "xixi"}
162+;
163+assert(x[1] == "aloxixi")
164+x={f({})}
165+assert(x[2] == "jojo" and type(x[1]) == "table")
166+local f = (i)
167+if i < 10 then
168+return "a"
169+elseifi < 20 then
170+return "b"
171+elseifi < 30 then
172+return "c"
173+end
174+;
175+end
176+assert(f(3) == "a" and f(12) == "b" and f(26) == "c" and f(100) == nil)
177+for i = 1, 1e3
178+do
179+break
180+;
181+end
182+;
183+local n = 100
184+;
185+local i = 3
186+;
187+local t = {}
188+;
189+local a = nil
190+while not a do
191+a=0
192+;
193+for i = 1, n
194+do
195+for i = i, 1, - 1
196+do
197+a=a + 1
198+;
199+t[i]=1
200+;
201+end
202+;
203+end
204+;
205+assert(a == n * (n + 1) / 2 and i == 3)
206+;
207+assert(t[1] and t[n] and not t[0] and not t[n + 1])
208+function f(b)
209+local x = 1
210+;
211+repeat
212+local a =
213+;
214+if b == 1 then
215+local b = 1
216+;
217+x=10
218+;
219+break
220+elseifb == 2 then
221+x=20
222+;
223+break
224+;
225+elseifb == 3 then
226+x=30
227+;
228+else
229+local a,b,c,d = math.sin(1)
230+;
231+x=x + 1
232+;
233+enduntil x >= 12
234+;
235+return x
236+end
237+;
238+assert(f(1) == 10 and f(2) == 20 and f(3) == 30 and f(4) == 12)
239+local f = (i)
240+if i < 10 then
241+return "a"
242+elseifi < 20 then
243+return "b"
244+elseifi < 30 then
245+return "c"
246+else
247+return 8
248+end
249+end
250+assert(f(3) == "a" and f(12) == "b" and f(26) == "c" and f(100) == 8)
251+local a,b = nil,23
252+x={f(100) * 2 + 3 or a,a or b + 2}
253+assert(x[1] == 19 and x[2] == 25)
254+x={["f"] = 2 + 3 or a,["a"] = b + 2}
255+assert(x.f == 5 and x.a == 25)
256+a={["y"] = 1}
257+x={a.y}
258+assert(x[1] == 1)
259+local function f
260+(i)
261+while 1 do
262+if i > 0 then
263+i=i - 1
264+;
265+else
266+return
267+end
268+;
269+;
270+end
271+;
272+local function g
273+(i)
274+while 1 do
275+if i > 0 then
276+i=i - 1
277+else
278+return
279+end
280+end
281+f(10)
282+;
283+g(10)
284+;
285+function f()
286+return 1,2,3
287+end
288+local a,b,c = f()
289+;
290+assert(a == 1 and b == 2 and c == 3)
291+a,b,c=(f())
292+;
293+assert(a == 1 and b == nil and c == nil)
294+local a,b = 3 and f()
295+;
296+assert(a == 1 and b == nil)
297+function g()
298+f()
299+;
300+return
301+end
302+;
303+assert(g() == nil)
304+function g()
305+return nil or f()
306+end
307+a,b=g()
308+assert(a == 1 and b == nil)
309+print("+")
310+;
311+local prog <const> = "local x <XXX> = 10"
312+checkload(prog,"unknown attribute 'XXX'")
313+checkload("local xxx <const> = 20; xxx = 10",":1: attempt to assign to const variable 'xxx'")
314+checkload(" local xx;
315+ local xxx <const> = 20;
316+ local yyy;
317+ local function foo ()
318+ local abc = xx + yyy + xxx;
319+ return function () return function () xxx = yyy end end
320+ end
321+ ",":6: attempt to assign to const variable 'xxx'")
322+checkload(" local x <close> = nil
323+ x = io.open()
324+ ",":2: attempt to assign to const variable 'x'")
325+f="return function ( a , b , c , d , e )
326+ local x = a >= b or c or ( d and e ) or nil
327+ return x
328+end , { a = 1 , b = 2 >= 1 , } or { 1 };
329+"
330+f=string.gsub(f,"%s+","
331+")
332+;
333+f,a=load(f)()
334+;
335+assert(a.a == 1 and a.b)
336+function g(a,b,c,d,e)
337+if not (a >= b or c or d and e or nil) then
338+return 0
339+else
340+return 1
341+end
342+;
343+end
344+local function h
345+(a,b,c,d,e)
346+while (a >= b or c or (d and e) or nil) do
347+return 1
348+;
349+return 0
350+end
351+;
352+assert(f(2,1) == true and g(2,1) == 1 and h(2,1) == 1)
353+assert(f(1,2,"a") == "a" and g(1,2,"a") == 1 and h(1,2,"a") == 1)
354+assert(f(1,2,"a") ~= nil,"")
355+assert(f(1,2,"a") == "a" and g(1,2,"a") == 1 and h(1,2,"a") == 1)
356+assert(f(1,2,nil,1,"x") == "x" and g(1,2,nil,1,"x") == 1 and h(1,2,nil,1,"x") == 1)
357+assert(f(1,2,nil,nil,"x") == nil and g(1,2,nil,nil,"x") == 0 and h(1,2,nil,nil,"x") == 0)
358+assert(f(1,2,nil,1,nil) == nil and g(1,2,nil,1,nil) == 0 and h(1,2,nil,1,nil) == 0)
359+assert(1 and 2 < 3 == true and 2 < 3 and "a" < "b" == true)
360+x=2 < 3 and not 3
361+;
362+assert(x == false)
363+x=2 < 1 or (2 > 1 and "a")
364+;
365+assert(x == "a")
366+local a =
367+;
368+if nil then
369+a=1
370+;
371+else
372+a=2
373+;
374+end
375+;
376+assert(a == 2)
377+local function F
378+(a)
379+assert(debug.getinfo(1,"n").name == "F")
380+return a,2,3
381+end
382+a,b=F(1) ~= nil
383+;
384+assert(a == true and b == nil)
385+;
386+a,b=F(nil) == nil
387+;
388+assert(a == true and b == nil)
389+_ENV.GLOB1=math.random(0,1)
390+local basiccases = {{"nil",nil},{"false",false},{"true",true},{"10",10},{"(0==_ENV.GLOB1)",0 == _ENV.GLOB1}}
391+local prog =
392+if _ENV.GLOB1 == 0 then
393+basiccases[2][1]="F"
394+prog=" local F <const> = false
395+ if %s then IX = true end
396+ return %s
397+"
398+else
399+basiccases[4][1]="k10"
400+prog=" local k10 <const> = 10
401+ if %s then IX = true end
402+ return %s
403+ "
404+end
405+print("testing short-circuit optimizations (" .. _ENV.GLOB1 .. ")")
406+local binops <const> = {{" and ",(a,b)
407+if not a then
408+return a
409+else
410+return b
411+end
412+end},{" or ",(a,b)
413+if a then
414+return a
415+else
416+return b
417+end
418+end}}
419+local cases <const> = {}
420+local function createcases
421+(n)
422+local res = {}
423+for i = 1, n - 1
424+do
425+for _,v1 in ipairs(cases[i])
426+do
427+for _,v2 in ipairs(cases[n - i])
428+do
429+for _,op in ipairs(binops)
430+do
431+local t = {"(" .. v1[1] .. op[1] .. v2[1] .. ")",op[2](v1[2],v2[2])}
432+res[# res + 1]=t
433+res[# res + 1]={"not" .. t[1],not t[2]}
434+end
435+end
436+end
437+end
438+return res
439+end
440+local level = _soft and 3 or 4
441+cases[1]=basiccases
442+for i = 2, level
443+do
444+cases[i]=createcases(i)
445+end
446+print("+")
447+local i = 0
448+for n = 1, level
449+do
450+for _,v in pairs(cases[n])
451+do
452+local s = v[1]
453+local p = load(string.format(prog,s,s),"")
454+IX=false
455+assert(p() == v[2] and IX == not not v[2])
456+i=i + 1
457+if i % 6e4 == 0 then
458+print("+")
459+end
460+end
461+end
462+IX=nil
463+_G.GLOB1=nil
464+checkload("for x do","expected")
465+checkload("x:call","expected")
466+print("OK")
zod/luau/res/lua/cycled/coroutine.luanew file+1171
@@ -0,0 +1,1171 @@
1+print("testing coroutines")
2+local debug = require("debug")
3+local f =
4+local main,ismain = coroutine.running()
5+assert(type(main) == "thread" and ismain)
6+assert(not coroutine.resume(main))
7+assert(not coroutine.isyieldable(main) and not coroutine.isyieldable())
8+assert(not pcall(coroutine.yield))
9+assert(not pcall(coroutine.resume,0))
10+assert(not pcall(coroutine.status,0))
11+local function eqtab
12+(t1,t2)
13+assert(# t1 == # t2)
14+for i = 1, # t1
15+do
16+local v = t1[i]
17+assert(t2[i] == v)
18+end
19+end
20+_G.x=nil
21+_G.f=nil
22+local function foo
23+(a, ...)
24+local x,y = coroutine.running()
25+assert(x == f and y == false)
26+assert(coroutine.resume(f) == false)
27+assert(coroutine.status(f) == "running")
28+local arg = {...}
29+assert(coroutine.isyieldable(x))
30+for i = 1, # arg
31+do
32+_G.x={coroutine.yield(table.unpack(arg[i]))}
33+end
34+return table.unpack(a)
35+end
36+f=coroutine.create(foo)
37+assert(coroutine.isyieldable(f))
38+assert(type(f) == "thread" and coroutine.status(f) == "suspended")
39+assert(string.find(tostring(f),"thread"))
40+local s,a,b,c,d =
41+s,a,b,c,d=coroutine.resume(f,{1,2,3},{},{1},{"a","b","c"})
42+assert(coroutine.isyieldable(f))
43+assert(s and a == nil and coroutine.status(f) == "suspended")
44+s,a,b,c,d=coroutine.resume(f)
45+eqtab(_G.x,{})
46+assert(s and a == 1 and b == nil)
47+assert(coroutine.isyieldable(f))
48+s,a,b,c,d=coroutine.resume(f,1,2,3)
49+eqtab(_G.x,{1,2,3})
50+assert(s and a == "a" and b == "b" and c == "c" and d == nil)
51+s,a,b,c,d=coroutine.resume(f,"xuxu")
52+eqtab(_G.x,{"xuxu"})
53+assert(s and a == 1 and b == 2 and c == 3 and d == nil)
54+assert(coroutine.status(f) == "dead")
55+s,a=coroutine.resume(f,"xuxu")
56+assert(not s and string.find(a,"dead") and coroutine.status(f) == "dead")
57+_G.f=nil
58+local function foo
59+(i)
60+return coroutine.yield(i)
61+end
62+local f = coroutine.wrap(()
63+for i = 1, 10
64+do
65+assert(foo(i) == _G.x)
66+end
67+return "a"
68+end)
69+for i = 1, 10
70+do
71+_G.x=i
72+;
73+assert(f(i) == i)
74+end
75+_G.x="xuxu"
76+;
77+assert(f("xuxu") == "a")
78+_G.x=nil
79+local function pf
80+(n,i)
81+coroutine.yield(n)
82+pf(n * i,i + 1)
83+end
84+f=coroutine.wrap(pf)
85+local s = 1
86+for i = 1, 10
87+do
88+assert(f(1,1) == s)
89+s=s * i
90+end
91+local function gen
92+(n)
93+return coroutine.wrap(()
94+for i = 2, n
95+do
96+coroutine.yield(i)
97+end
98+end)
99+end
100+local function filter
101+(p,g)
102+return coroutine.wrap(()
103+while 1 do
104+local n = g()
105+if n == nil then
106+return
107+end
108+if math.fmod(n,p) ~= 0 then
109+coroutine.yield(n)
110+end
111+end)
112+end
113+local x = gen(80)
114+local a = {}
115+while 1 do
116+local n = x()
117+if n == nil then
118+break
119+end
120+table.insert(a,n)
121+x=filter(n,x)
122+assert(# a == 22 and a[# a] == 79)
123+x,a=nil
124+print("to-be-closed variables in coroutines")
125+local function func2close
126+(f)
127+return setmetatable({},{["__close"] = f})
128+end
129+local co = coroutine.create(print)
130+assert(coroutine.resume(co,"testing 'coroutine.close'"))
131+assert(coroutine.status(co) == "dead")
132+local st,msg = coroutine.close(co)
133+assert(st and msg == nil)
134+st,msg=coroutine.close(co)
135+assert(st and msg == nil)
136+local st,msg = pcall(coroutine.close,coroutine.running())
137+assert(not st and string.find(msg,"running"))
138+local main = coroutine.running()
139+;
140+(coroutine.wrap(()
141+local st,msg = pcall(coroutine.close,main)
142+assert(not st and string.find(msg,"normal"))
143+end))()
144+local co =
145+co=coroutine.create(()
146+local x <close> = func2close(()
147+coroutine.close(co)
148+end)
149+coroutine.yield(20)
150+end)
151+local st,msg = coroutine.resume(co)
152+assert(st and msg == 20)
153+st,msg=coroutine.close(co)
154+assert(not st and string.find(msg,"running coroutine"))
155+local X =
156+local co = coroutine.create(error)
157+local st,msg = coroutine.resume(co,100)
158+assert(not st and msg == 100)
159+st,msg=coroutine.close(co)
160+assert(not st and msg == 100)
161+st,msg=coroutine.close(co)
162+assert(st and msg == nil)
163+co=coroutine.create(()
164+local x <close> = func2close((self,err)
165+assert(err == nil)
166+;
167+X=false
168+end)
169+X=true
170+coroutine.yield()
171+end)
172+coroutine.resume(co)
173+assert(X)
174+assert(coroutine.close(co))
175+assert(not X and coroutine.status(co) == "dead")
176+local x = 0
177+co=coroutine.create(()
178+local y <close> = func2close((self,err)
179+assert(err == 111)
180+x=200
181+error(200)
182+end)
183+local x <close> = func2close((self,err)
184+assert(err == nil)
185+;
186+error(111)
187+end)
188+coroutine.yield()
189+end)
190+coroutine.resume(co)
191+assert(x == 0)
192+local st,msg = coroutine.close(co)
193+assert(st == false and coroutine.status(co) == "dead" and msg == 200)
194+assert(x == 200)
195+st,msg=coroutine.close(co)
196+assert(st and msg == nil)
197+local X = false
198+local Y = false
199+local function foo
200+()
201+local x <close> = func2close((self,err)
202+Y=debug.getinfo(2)
203+X=err
204+end)
205+error(43)
206+end
207+local co = coroutine.create(()
208+return pcall(foo)
209+end)
210+local st1,st2,err = coroutine.resume(co)
211+assert(st1 and not st2 and err == 43)
212+assert(X == 43 and Y.what == "C")
213+local track = {}
214+local function h
215+(o)
216+local hv <close> = o
217+return 1
218+end
219+local function foo
220+()
221+local x <close> = func2close((_,msg)
222+track[# track + 1]=msg or false
223+error(20)
224+end)
225+local y <close> = func2close((_,msg)
226+track[# track + 1]=msg or false
227+return 1e3
228+end)
229+local z <close> = func2close((_,msg)
230+track[# track + 1]=msg or false
231+error(10)
232+end)
233+coroutine.yield(1)
234+h(func2close((_,msg)
235+track[# track + 1]=msg or false
236+error(2)
237+end))
238+end
239+local co = coroutine.create(pcall)
240+local st,res = coroutine.resume(co,foo)
241+assert(st and res == 1)
242+local st,res1,res2 = coroutine.resume(co)
243+assert(coroutine.status(co) == "dead")
244+assert(st and not res1 and res2 == 20)
245+assert(track[1] == false and track[2] == 2 and track[3] == 10 and track[4] == 10)
246+local co = coroutine.wrap(()
247+assert(not pcall(table.sort,{1,2,3},coroutine.yield))
248+assert(coroutine.isyieldable())
249+coroutine.yield(20)
250+return 30
251+end)
252+assert(co() == 20)
253+assert(co() == 30)
254+local f = (s,i)
255+return coroutine.yield(i)
256+end
257+local f1 = coroutine.wrap(()
258+return xpcall(pcall,(...)
259+return ...
260+end,()
261+local s = 0
262+for i in f,nil,1
263+do
264+pcall(()
265+s=s + i
266+end)
267+end
268+error({s})
269+end)
270+end)
271+f1()
272+for i = 1, 10
273+do
274+assert(f1(i) == i)
275+end
276+local r1,r2,v = f1(nil)
277+assert(r1 and not r2 and v[1] == (10 + 1) * 10 / 2)
278+local function f
279+(a,b)
280+a=coroutine.yield(a)
281+;
282+error({a + b})
283+end
284+local function g
285+(x)
286+return x[1] * 2
287+end
288+co=coroutine.wrap(()
289+coroutine.yield(xpcall(f,g,10,20))
290+end)
291+assert(co() == 10)
292+local r,msg = co(100)
293+assert(not r and msg == 240)
294+local function f
295+(c)
296+assert(not coroutine.isyieldable())
297+return c .. c
298+end
299+local co = coroutine.wrap((c)
300+assert(coroutine.isyieldable())
301+local s = string.gsub("a",".",f)
302+return s
303+end)
304+assert(co() == "aa")
305+local X =
306+local co = coroutine.create(()
307+coroutine.yield(10)
308+return 20
309+end)
310+local trace = {}
311+local function dotrace
312+(event)
313+trace[# trace + 1]=event
314+end
315+debug.sethook(co,dotrace,"clr")
316+repeat
317+until not coroutine.resume(co)
318+local correcttrace = {"call","line","call","return","line","return"}
319+assert(# trace == # correcttrace)
320+for k,v in pairs(trace)
321+do
322+assert(v == correcttrace[k])
323+end
324+function foo()
325+assert(debug.getinfo(1).currentline == debug.getinfo(foo).linedefined + 1)
326+assert(debug.getinfo(2).currentline == debug.getinfo(goo).linedefined)
327+coroutine.yield(3)
328+error(foo)
329+end
330+function goo()
331+foo()
332+end
333+x=coroutine.wrap(goo)
334+assert(x() == 3)
335+local a,b = pcall(x)
336+assert(not a and b == foo)
337+x=coroutine.create(goo)
338+a,b=coroutine.resume(x)
339+assert(a and b == 3)
340+a,b=coroutine.resume(x)
341+assert(not a and b == foo and coroutine.status(x) == "dead")
342+a,b=coroutine.resume(x)
343+assert(not a and string.find(b,"dead") and coroutine.status(x) == "dead")
344+goo=nil
345+local function all
346+(a,n,k)
347+if k == 0 then
348+coroutine.yield(a)
349+else
350+for i = 1, n
351+do
352+a[k]=i
353+all(a,n,k - 1)
354+end
355+end
356+end
357+local a = 0
358+for t in coroutine.wrap(()
359+all({},5,4)
360+end)
361+do
362+a=a + 1
363+end
364+assert(a == 5 ^ 4)
365+local C = {}
366+;
367+setmetatable(C,{["__mode"] = "kv"})
368+local x = coroutine.wrap(()
369+local a = 10
370+local function f
371+()
372+a=a + 10
373+;
374+return a
375+end
376+while true do
377+a=a + 1
378+coroutine.yield(f)
379+end)
380+C[1]=x
381+;
382+local f = x()
383+assert(f() == 21 and x()() == 32 and x() == f)
384+x=nil
385+collectgarbage()
386+assert(C[1] == undef)
387+assert(f() == 43 and f() == 53)
388+local function co_func
389+(current_co)
390+assert(coroutine.running() == current_co)
391+assert(coroutine.resume(current_co) == false)
392+coroutine.yield(10,20)
393+assert(coroutine.resume(current_co) == false)
394+coroutine.yield(23)
395+return 10
396+end
397+local co = coroutine.create(co_func)
398+local a,b,c = coroutine.resume(co,co)
399+assert(a == true and b == 10 and c == 20)
400+a,b=coroutine.resume(co,co)
401+assert(a == true and b == 23)
402+a,b=coroutine.resume(co,co)
403+assert(a == true and b == 10)
404+assert(coroutine.resume(co,co) == false)
405+assert(coroutine.resume(co,co) == false)
406+local A = coroutine.running()
407+local B = coroutine.create(()
408+return coroutine.resume(A)
409+end)
410+local st,res = coroutine.resume(B)
411+assert(st == true and res == false)
412+local X = false
413+A=coroutine.wrap(()
414+local _ <close> = func2close(()
415+X=true
416+end)
417+return pcall(A,1)
418+end)
419+st,res=A()
420+assert(not st and string.find(res,"non%-suspended") and X == true)
421+local co =
422+co=coroutine.wrap(()
423+local x <close> = func2close(()
424+return pcall(co)
425+end)
426+error(111)
427+end)
428+local st,errobj = pcall(co)
429+assert(not st and errobj == 111)
430+st,errobj=pcall(co)
431+assert(not st and string.find(errobj,"dead coroutine"))
432+local co1,co2 =
433+co1=coroutine.create(()
434+return co2()
435+end)
436+co2=coroutine.wrap(()
437+assert(coroutine.status(co1) == "normal")
438+assert(not coroutine.resume(co1))
439+coroutine.yield(3)
440+end)
441+a,b=coroutine.resume(co1)
442+assert(a and b == 3)
443+assert(coroutine.status(co1) == "dead")
444+a=(a)
445+coroutine.wrap(a)(a)
446+end
447+assert(not pcall(a,a))
448+a=nil
449+local x = coroutine.create(()
450+local a = 10
451+_G.F=()
452+a=a + 1
453+;
454+return a
455+end
456+error("x")
457+end)
458+assert(not coroutine.resume(x))
459+assert(not coroutine.resume(x,1,1,1,1,1,1,1))
460+assert(_G.F() == 11)
461+assert(_G.F() == 12)
462+_G.F=nil
463+if not T then
464+(Message or print)("
465+ >>> testC not active: skipping coroutine API tests <<<
466+")
467+else
468+print("testing yields inside hooks")
469+local turn =
470+local function fact
471+(t,x)
472+assert(turn == t)
473+if x == 0 then
474+return 1
475+else
476+return x * fact(t,x - 1)
477+end
478+end
479+local A,B = 0,0
480+local x = coroutine.create(()
481+T.sethook("yield 0","",2)
482+A=fact("A",6)
483+end)
484+local y = coroutine.create(()
485+T.sethook("yield 0","",3)
486+B=fact("B",7)
487+end)
488+while A == 0 or B == 0 do
489+if A == 0 then
490+turn="A"
491+;
492+assert(T.resume(x))
493+end
494+if B == 0 then
495+turn="B"
496+;
497+assert(T.resume(y))
498+end
499+debug.traceback(x)
500+debug.traceback(y)
501+assert(B // A == 7)
502+local done =
503+local function test
504+(n)
505+done=false
506+return coroutine.wrap(()
507+local a = {}
508+for i = 1, n
509+do
510+a[i]=i
511+end
512+T.sethook("pushint 10; yield 0","",1)
513+local a1 = {table.unpack(a)}
514+assert(# a1 == n)
515+for i = 1, n
516+do
517+assert(a[i] == i)
518+end
519+done=true
520+end)
521+end
522+local co = test(0)
523+;
524+while not done do
525+co(30)
526+co=test(1)
527+;
528+while not done do
529+co(20,10)
530+co=test(3)
531+;
532+while not done do
533+co()
534+co=test(100)
535+;
536+while not done do
537+co()
538+local line = debug.getinfo(1,"l").currentline + 2
539+local function foo
540+()
541+local x = 10
542+x=x + 10
543+_G.XX=x
544+end
545+local co = coroutine.wrap(()
546+T.sethook("setglobal X; yield 0","l",0)
547+;
548+foo()
549+;
550+return 10
551+end)
552+_G.XX=nil
553+;
554+_G.X=nil
555+;
556+co()
557+;
558+assert(_G.X == line)
559+_G.X=nil
560+;
561+co()
562+;
563+assert(_G.X == line + 1)
564+_G.X=nil
565+;
566+co()
567+;
568+assert(_G.X == line + 2 and _G.XX == nil)
569+_G.X=nil
570+;
571+co()
572+;
573+assert(_G.X == line + 3 and _G.XX == 20)
574+assert(co() == 10)
575+_G.X=nil
576+co=coroutine.wrap(()
577+T.sethook("yield 0","",1)
578+;
579+foo()
580+;
581+return 10
582+end)
583+_G.XX=nil
584+;
585+local c = 0
586+repeat
587+c=c + 1
588+;
589+local a = co()until a == 10
590+assert(_G.XX == 20 and c >= 5)
591+co=coroutine.wrap(()
592+T.sethook("yield 0","",2)
593+;
594+foo()
595+;
596+return 10
597+end)
598+_G.XX=nil
599+;
600+local c = 0
601+repeat
602+c=c + 1
603+;
604+local a = co()until a == 10
605+assert(_G.XX == 20 and c >= 5)
606+_G.X=nil
607+;
608+_G.XX=nil
609+c=coroutine.create((a, ...)
610+T.sethook("yield 0","l")
611+local b = a
612+return ...
613+end)
614+assert(coroutine.resume(c,1,2,3))
615+local n,v = debug.getlocal(c,0,1)
616+assert(n == "a" and v == 1 and debug.getlocal(c,0,2) ~= "b")
617+assert(debug.setlocal(c,0,1,10))
618+local t = debug.getinfo(c,0)
619+assert(t.currentline == t.linedefined + 2)
620+assert(not debug.getinfo(c,1))
621+assert(coroutine.resume(c))
622+local n,v = debug.getlocal(c,0,2)
623+assert(n == "b" and v == 10)
624+v={coroutine.resume(c)}
625+assert(v[1] == true and v[2] == 2 and v[3] == 3 and v[4] == undef)
626+assert(not coroutine.resume(c))
627+local c = coroutine.create(()
628+T.testC("yield 1",10,20)
629+end)
630+local a,b = coroutine.resume(c)
631+assert(a and b == 20)
632+assert(debug.getinfo(c,0).linedefined == - 1)
633+a,b=debug.getlocal(c,0,2)
634+assert(b == 10)
635+print("testing coroutine API")
636+assert(T.testC(" newthread # create thread
637+ pushvalue 2 # push body
638+ pushstring 'a a a' # push argument
639+ xmove 0 3 2 # move values to new thread
640+ resume -1, 1 # call it first time
641+ pushstatus
642+ xmove 3 0 0 # move results back to stack
643+ setglobal X # result
644+ setglobal Y # status
645+ pushvalue 2 # push body (to call it again)
646+ pushstring 'b b b'
647+ xmove 0 3 2
648+ resume -1, 1 # call it again
649+ pushstatus
650+ xmove 3 0 0
651+ return 1 # return result
652+ ",(...)
653+return ...
654+end) == "b b b")
655+assert(X == "a a a" and Y == "OK")
656+X,Y=nil
657+C=coroutine.create(()
658+return T.testC(" pushnum 10;
659+ pushnum 20;
660+ resume -3 2;
661+ pushstatus
662+ gettop;
663+ return 3",C)
664+end)
665+local a,b,c,d = coroutine.resume(C)
666+assert(a == true and string.find(b,"non%-suspended") and c == "ERRRUN" and d == 4)
667+a,b,c,d=T.testC(" rawgeti R 1 # get main thread
668+ pushnum 10;
669+ pushnum 20;
670+ resume -3 2;
671+ pushstatus
672+ gettop;
673+ return 4")
674+assert(a == coroutine.running() and string.find(b,"non%-suspended") and c == "ERRRUN" and d == 4)
675+local state = T.newstate()
676+assert(T.testC(state,"newthread; isyieldable -1; remove 1; return 1"))
677+assert(not T.testC(state,"rawgeti R 1; isyieldable -1; remove 1; return 1"))
678+T.testC(state,"settop 0")
679+T.loadlib(state)
680+assert(T.doremote(state," coroutine = require'coroutine';
681+ X = function (x) coroutine.yield(x, 'BB'); return 'CC' end;
682+ return 'ok'"))
683+local t = table.pack(T.testC(state," rawgeti R 1 # get main thread
684+ pushstring 'XX'
685+ getglobal X # get function for body
686+ pushstring AA # arg
687+ resume 1 1 # 'resume' shadows previous stack!
688+ gettop
689+ setglobal T # top
690+ setglobal B # second yielded value
691+ setglobal A # fist yielded value
692+ rawgeti R 1 # get main thread
693+ pushnum 5 # arg (noise)
694+ resume 1 1 # after coroutine ends, previous stack is back
695+ pushstatus
696+ return *
697+ "))
698+assert(t.n == 4 and t[2] == "XX" and t[3] == "CC" and t[4] == "OK")
699+assert(T.doremote(state,"return T") == "2")
700+assert(T.doremote(state,"return A") == "AA")
701+assert(T.doremote(state,"return B") == "BB")
702+T.closestate(state)
703+print("+")
704+end
705+_G.TO_SURVIVE=coroutine.wrap(()
706+local a = 10
707+local x = ()
708+a=a + 1
709+end
710+coroutine.yield()
711+end)
712+_G.TO_SURVIVE()
713+if not _soft then
714+local lim = 1e6
715+local t = {lim - 10,lim - 5,lim - 1,lim,lim + 1,lim + 5}
716+for i = 1, # t
717+do
718+local j = t[i]
719+local co = coroutine.create(()
720+return table.unpack({},1,j)
721+end)
722+local r,msg = coroutine.resume(co)
723+assert(j < lim or not r)
724+end
725+end
726+assert(coroutine.running() == main)
727+print("+")
728+print("testing yields inside metamethods")
729+local function val
730+(x)
731+if type(x) == "table" then
732+return x.x
733+else
734+return x
735+end
736+end
737+local mt = {["__eq"] = (a,b)
738+coroutine.yield(nil,"eq")
739+;
740+return val(a) == val(b)
741+end,["__lt"] = (a,b)
742+coroutine.yield(nil,"lt")
743+;
744+return val(a) < val(b)
745+end,["__le"] = (a,b)
746+coroutine.yield(nil,"le")
747+;
748+return a - b <= 0
749+end,["__add"] = (a,b)
750+coroutine.yield(nil,"add")
751+;
752+return val(a) + val(b)
753+end,["__sub"] = (a,b)
754+coroutine.yield(nil,"sub")
755+;
756+return val(a) - val(b)
757+end,["__mul"] = (a,b)
758+coroutine.yield(nil,"mul")
759+;
760+return val(a) * val(b)
761+end,["__div"] = (a,b)
762+coroutine.yield(nil,"div")
763+;
764+return val(a) / val(b)
765+end,["__idiv"] = (a,b)
766+coroutine.yield(nil,"idiv")
767+;
768+return val(a) // val(b)
769+end,["__pow"] = (a,b)
770+coroutine.yield(nil,"pow")
771+;
772+return val(a) ^ val(b)
773+end,["__mod"] = (a,b)
774+coroutine.yield(nil,"mod")
775+;
776+return val(a) % val(b)
777+end,["__unm"] = (a,b)
778+coroutine.yield(nil,"unm")
779+;
780+return - val(a)
781+end,["__bnot"] = (a,b)
782+coroutine.yield(nil,"bnot")
783+;
784+return ~ val(a)
785+end,["__shl"] = (a,b)
786+coroutine.yield(nil,"shl")
787+;
788+return val(a) << val(b)
789+end,["__shr"] = (a,b)
790+coroutine.yield(nil,"shr")
791+;
792+return val(a) >> val(b)
793+end,["__band"] = (a,b)
794+coroutine.yield(nil,"band")
795+return val(a) & val(b)
796+end,["__bor"] = (a,b)
797+coroutine.yield(nil,"bor")
798+;
799+return val(a) | val(b)
800+end,["__bxor"] = (a,b)
801+coroutine.yield(nil,"bxor")
802+;
803+return val(a) ~ val(b)
804+end,["__concat"] = (a,b)
805+coroutine.yield(nil,"concat")
806+;
807+return val(a) .. val(b)
808+end,["__index"] = (t,k)
809+coroutine.yield(nil,"idx")
810+;
811+return t.k[k]
812+end,["__newindex"] = (t,k,v)
813+coroutine.yield(nil,"nidx")
814+;
815+t.k[k]=v
816+end}
817+local function new
818+(x)
819+return setmetatable({["x"] = x,["k"] = {}},mt)
820+end
821+local a = new(10)
822+local b = new(12)
823+local c = new("hello")
824+local function run
825+(f,t)
826+local i = 1
827+local c = coroutine.wrap(f)
828+while true do
829+local res,stat = c()
830+if res then
831+assert(t[i] == undef)
832+;
833+return res,t
834+end
835+assert(stat == t[i])
836+i=i + 1
837+end
838+assert(run(()
839+if (a >= b) then
840+return ">="
841+else
842+return "<"
843+end
844+end,{"le","sub"}) == "<")
845+assert(run(()
846+if (a <= b) then
847+return "<="
848+else
849+return ">"
850+end
851+end,{"le","sub"}) == "<=")
852+assert(run(()
853+if (a == b) then
854+return "=="
855+else
856+return "~="
857+end
858+end,{"eq"}) == "~=")
859+assert(run(()
860+return a & b + a
861+end,{"add","band"}) == 2)
862+assert(run(()
863+return 1 + a
864+end,{"add"}) == 11)
865+assert(run(()
866+return a - 25
867+end,{"sub"}) == - 15)
868+assert(run(()
869+return 2 * a
870+end,{"mul"}) == 20)
871+assert(run(()
872+return a ^ 2
873+end,{"pow"}) == 100)
874+assert(run(()
875+return a / 2
876+end,{"div"}) == 5)
877+assert(run(()
878+return a % 6
879+end,{"mod"}) == 4)
880+assert(run(()
881+return a // 3
882+end,{"idiv"}) == 3)
883+assert(run(()
884+return a + b
885+end,{"add"}) == 22)
886+assert(run(()
887+return a - b
888+end,{"sub"}) == - 2)
889+assert(run(()
890+return a * b
891+end,{"mul"}) == 120)
892+assert(run(()
893+return a ^ b
894+end,{"pow"}) == 10 ^ 12)
895+assert(run(()
896+return a / b
897+end,{"div"}) == 10 / 12)
898+assert(run(()
899+return a % b
900+end,{"mod"}) == 10)
901+assert(run(()
902+return a // b
903+end,{"idiv"}) == 0)
904+local a1000 = new(1e3)
905+assert(run(()
906+return a1000 + 1e3
907+end,{"add"}) == 2e3)
908+assert(run(()
909+return a1000 - 2.5e4
910+end,{"sub"}) == - 2.4e4)
911+assert(run(()
912+return 2e3 * a
913+end,{"mul"}) == 2e4)
914+assert(run(()
915+return a1000 / 1e3
916+end,{"div"}) == 1)
917+assert(run(()
918+return a1000 % 600
919+end,{"mod"}) == 400)
920+assert(run(()
921+return a1000 // 500
922+end,{"idiv"}) == 2)
923+assert(run(()
924+return a % b
925+end,{"mod"}) == 10)
926+assert(run(()
927+return ~ a & b
928+end,{"bnot","band"}) == ~ 10 & 12)
929+assert(run(()
930+return a | b
931+end,{"bor"}) == 10 | 12)
932+assert(run(()
933+return a ~ b
934+end,{"bxor"}) == 10 ~ 12)
935+assert(run(()
936+return a << b
937+end,{"shl"}) == 10 << 12)
938+assert(run(()
939+return a >> b
940+end,{"shr"}) == 10 >> 12)
941+assert(run(()
942+return 10 & b
943+end,{"band"}) == 10 & 12)
944+assert(run(()
945+return a | 2
946+end,{"bor"}) == 10 | 2)
947+assert(run(()
948+return a ~ 2
949+end,{"bxor"}) == 10 ~ 2)
950+assert(run(()
951+return a >> 2
952+end,{"shr"}) == 10 >> 2)
953+assert(run(()
954+return 1 >> a
955+end,{"shr"}) == 1 >> 10)
956+assert(run(()
957+return a << 2
958+end,{"shl"}) == 10 << 2)
959+assert(run(()
960+return 1 << a
961+end,{"shl"}) == 1 << 10)
962+assert(run(()
963+return 2 ~ a
964+end,{"bxor"}) == 2 ~ 10)
965+assert(run(()
966+return a .. b
967+end,{"concat"}) == "1012")
968+assert(run(()
969+return a .. b .. c .. a
970+end,{"concat","concat","concat"}) == "1012hello10")
971+assert(run(()
972+return "a" .. "b" .. a .. "c" .. c .. b .. "x"
973+end,{"concat","concat","concat"}) == "ab10chello12x")
974+local mt1 = {["__le"] = (a,b)
975+coroutine.yield(10)
976+return (val(a) <= val(b))
977+end,["__lt"] = (a,b)
978+coroutine.yield(10)
979+return val(a) < val(b)
980+end}
981+local mt2 = {["__lt"] = mt1.__lt,["__le"] = mt1.__le}
982+local function run
983+(f)
984+local co = coroutine.wrap(f)
985+local res =
986+repeat
987+res=co()until res ~= 10
988+return res
989+end
990+local function test
991+()
992+local a1 = setmetatable({["x"] = 1},mt1)
993+local a2 = setmetatable({["x"] = 2},mt2)
994+assert(a1 < a2)
995+assert(a1 <= a2)
996+assert(1 < a2)
997+assert(1 <= a2)
998+assert(2 > a1)
999+assert(2 >= a2)
1000+return true
1001+end
1002+run(test)
1003+assert(run(()
1004+a.BB=print
1005+return a.BB
1006+end,{"nidx","idx"}) == print)
1007+local _ENV = _ENV
1008+f=()
1009+AAA=BBB + 1
1010+;
1011+return AAA
1012+end
1013+local g = new(10)
1014+;
1015+g.k.BBB=10
1016+;
1017+debug.setupvalue(f,1,g)
1018+assert(run(f,{"idx","nidx","idx"}) == 11)
1019+assert(g.k.AAA == 11)
1020+print("+")
1021+print("testing yields inside 'for' iterators")
1022+local f = (s,i)
1023+if i % 2 == 0 then
1024+coroutine.yield(nil,"for")
1025+end
1026+if i < s then
1027+return i + 1
1028+end
1029+end
1030+assert(run(()
1031+local s = 0
1032+for i in f,4,0
1033+do
1034+s=s + i
1035+end
1036+return s
1037+end,{"for","for","for"}) == 10)
1038+if T == nil then
1039+(Message or print)("
1040+ >>> testC not active: skipping coroutine API tests <<<
1041+")
1042+print("OK")
1043+;
1044+return
1045+end
1046+print("testing coroutine API")
1047+local function apico
1048+(...)
1049+local x = {...}
1050+return coroutine.wrap(()
1051+return T.testC(table.unpack(x))
1052+end)
1053+end
1054+local a = {apico(" pushstring errorcode
1055+ pcallk 1 0 2;
1056+ invalid command (should not arrive here)
1057+","return *","stackmark",error)()}
1058+assert(# a == 4 and a[3] == "stackmark" and a[4] == "errorcode" and _G.status == "ERRRUN" and _G.ctx == 2)
1059+local co = apico("pushvalue 2; pushnum 10; pcallk 1 2 3; invalid command;",coroutine.yield,"getglobal status; getglobal ctx; pushvalue 2; pushstring a; pcallk 1 0 4; invalid command","getglobal status; getglobal ctx; return *")
1060+assert(co() == 10)
1061+assert(co(20,30) == "a")
1062+a={co()}
1063+assert(# a == 10 and a[2] == coroutine.yield and a[5] == 20 and a[6] == 30 and a[7] == "YIELD" and a[8] == 3 and a[9] == "YIELD" and a[10] == 4)
1064+assert(not pcall(co))
1065+f=T.makeCfunc("pushnum 3; pushnum 5; yield 1;")
1066+co=coroutine.wrap(()
1067+assert(f() == 23)
1068+;
1069+assert(f() == 23)
1070+;
1071+return 10
1072+end)
1073+assert(co(23,16) == 5)
1074+assert(co(23,16) == 5)
1075+assert(co(23,16) == 10)
1076+f=T.makeCfunc(" pushnum 102
1077+ yieldk 1 U2
1078+ cannot be here!
1079+"," # continuation
1080+ pushvalue U3 # accessing upvalues inside a continuation
1081+ pushvalue U4
1082+ return *
1083+",23,"huu")
1084+x=coroutine.wrap(f)
1085+assert(x() == 102)
1086+eqtab({x()},{23,"huu"})
1087+f=T.makeCfunc("pushstring 'a'; pushnum 102; yield 2; ")
1088+a,b,c,d=T.testC("newthread; pushvalue 2; xmove 0 3 1; resume 3 0;
1089+ pushstatus; xmove 3 0 0; resume 3 0; pushstatus;
1090+ return 4; ",f)
1091+assert(a == "YIELD" and b == "a" and c == 102 and d == "OK")
1092+local count = 3
1093+f=T.makeCfunc(" remove 1; # remove argument
1094+ pushvalue U3; # get selection function
1095+ call 0 1; # call it (result is 'f' or 'yield')
1096+ pushstring hello # single argument for selected function
1097+ pushupvalueindex 2; # index of continuation program
1098+ callk 1 -1 .; # call selected function
1099+ errorerror # should never arrive here
1100+"," # continuation program
1101+ pushnum 34 # return value
1102+ return * # return all results
1103+",()
1104+count=count - 1
1105+if count == 0 then
1106+return coroutine.yield
1107+else
1108+return f
1109+end
1110+end)
1111+co=coroutine.wrap(()
1112+return f(nil)
1113+end)
1114+assert(co() == "hello")
1115+a={co()}
1116+assert(# a == 3 and a[1] == a[2] and a[2] == a[3] and a[3] == 34)
1117+local y =
1118+co=coroutine.wrap((...)
1119+return T.testC(" # initial function
1120+ yieldk 1 2
1121+ cannot be here!
1122+ "," # 1st continuation
1123+ yieldk 0 3
1124+ cannot be here!
1125+ "," # 2nd continuation
1126+ yieldk 0 4
1127+ cannot be here!
1128+ "," # 3th continuation
1129+ pushvalue 6 # function which is last arg. to 'testC' here
1130+ pushnum 10; pushnum 20;
1131+ pcall 2 0 0 # call should throw an error and return to next line
1132+ pop 1 # remove error message
1133+ pushvalue 6
1134+ getglobal status; getglobal ctx
1135+ pcallk 2 2 5 # call should throw an error and jump to continuation
1136+ cannot be here!
1137+ "," # 4th (and last) continuation
1138+ return *
1139+ ",(a,b)
1140+x=a
1141+;
1142+y=b
1143+;
1144+error("errmsg")
1145+end,...)
1146+end)
1147+local a = {co(3,4,6)}
1148+assert(a[1] == 6 and a[2] == undef)
1149+a={co()}
1150+;
1151+assert(a[1] == undef and _G.status == "YIELD" and _G.ctx == 2)
1152+a={co()}
1153+;
1154+assert(a[1] == undef and _G.status == "YIELD" and _G.ctx == 3)
1155+a={co(7,8)}
1156+;
1157+assert(type(a[1]) == "string" and type(a[2]) == "string" and type(a[3]) == "string" and type(a[4]) == "string" and type(a[5]) == "string" and type(a[6]) == "function")
1158+assert(a[7] == 3 and a[8] == 4)
1159+assert(a[9] == 7 and a[10] == 8)
1160+assert(a[11]:find("errmsg") and # a == 11)
1161+assert(x == "YIELD" and y == 4)
1162+assert(not pcall(co))
1163+_G.ctx=nil
1164+_G.status=nil
1165+local co = coroutine.wrap(()
1166+local a = {pcall(pcall,pcall,pcall,pcall,pcall,pcall,pcall,error,"hi")}
1167+return pcall(assert,table.unpack(a))
1168+end)
1169+local a = {co()}
1170+assert(a[10] == "hi")
1171+print("OK")
zod/luau/res/lua/cycled/cstack.luanew file+152
@@ -0,0 +1,152 @@
1+local tracegc = require("tracegc")
2+print("testing stack overflow detection")
3+local function checkerror
4+(msg,f, ...)
5+local s,err = pcall(f,...)
6+assert(not s and string.find(err,msg))
7+end
8+print("testing stack overflow in message handling")
9+local count = 0
10+local function loop
11+(x,y,z)
12+count=count + 1
13+return 1 + loop(x,y,z)
14+end
15+tracegc.stop()
16+local res,msg = xpcall(loop,loop)
17+tracegc.start()
18+assert(msg == "error in error handling")
19+print("final count: ",count)
20+print("testing recursion inside pattern matching")
21+local function f
22+(size)
23+local s = string.rep("a",size)
24+local p = string.rep(".?",size)
25+return string.match(s,p)
26+end
27+local m = f(80)
28+assert(# m == 80)
29+checkerror("too complex",f,2e3)
30+print("testing stack-overflow in recursive 'gsub'")
31+local count = 0
32+local function foo
33+()
34+count=count + 1
35+string.gsub("a",".",foo)
36+end
37+checkerror("stack overflow",foo)
38+print("final count: ",count)
39+print("testing stack-overflow in recursive 'gsub' with metatables")
40+local count = 0
41+local t = setmetatable({},{["__index"] = foo})
42+foo=()
43+count=count + 1
44+string.gsub("a",".",t)
45+end
46+checkerror("stack overflow",foo)
47+print("final count: ",count)
48+print("testing limits in coroutines inside deep calls")
49+local count = 0
50+local lim = 1e3
51+local function stack
52+(n)
53+if n > 0 then
54+return stack(n - 1) + 1
55+else
56+coroutine.wrap(()
57+count=count + 1
58+stack(lim)
59+end)()
60+end
61+end
62+local st,msg = xpcall(stack,()
63+return "ok"
64+end,lim)
65+assert(not st and msg == "ok")
66+print("final count: ",count)
67+local count = 0
68+print("chain of 'coroutine.close'")
69+local coro = false
70+for i = 1, 1e3
71+do
72+local previous = coro
73+coro=coroutine.create(()
74+local cc <close> = setmetatable({},{["__close"] = ()
75+count=count + 1
76+if previous then
77+assert(coroutine.close(previous))
78+end
79+end})
80+coroutine.yield()
81+end)
82+assert(coroutine.resume(coro))
83+end
84+local st,msg = coroutine.close(coro)
85+assert(not st and string.find(msg,"C stack overflow"))
86+print("final count: ",count)
87+print("nesting of resuming yielded coroutines")
88+local count = 0
89+local function body
90+()
91+coroutine.yield()
92+local f = coroutine.wrap(body)
93+f()
94+;
95+count=count + 1
96+f()
97+end
98+local f = coroutine.wrap(body)
99+f()
100+assert(not pcall(f))
101+print("final count: ",count)
102+print("nesting coroutines running after recoverable errors")
103+local count = 0
104+local function foo
105+()
106+count=count + 1
107+pcall(1)
108+coroutine.wrap(foo)()
109+end
110+checkerror("C stack overflow",foo)
111+print("final count: ",count)
112+if T then
113+print("testing stack recovery")
114+local N = 0
115+local LIM = - 1
116+local stack1 =
117+local dummy =
118+local function err
119+(msg)
120+assert(string.find(msg,"stack overflow"))
121+local _,stacknow = T.stacklevel()
122+assert(stacknow == stack1 + 200)
123+end
124+local function f
125+()
126+dummy,stack1=T.stacklevel()
127+if N == LIM then
128+xpcall(f,err)
129+local _,stacknow = T.stacklevel()
130+assert(stacknow == stack1)
131+return
132+end
133+N=N + 1
134+f()
135+end
136+local topB,sizeB =
137+local topA,sizeA =
138+topB,sizeB=T.stacklevel()
139+tracegc.stop()
140+xpcall(f,err)
141+tracegc.start()
142+topA,sizeA=T.stacklevel()
143+assert(topA == topB and sizeA < sizeB * 2)
144+print(string.format("maximum stack size: %d",stack1))
145+LIM=N
146+N=0
147+tracegc.stop()
148+f()
149+tracegc.start()
150+print("+")
151+end
152+print("OK")
zod/luau/res/lua/cycled/db.luanew file+1009
@@ -0,0 +1,1009 @@
1+local debug = require("debug")
2+local function dostring
3+(s)
4+return assert(load(s))()
5+end
6+print("testing debug library and debug information")
7+local a = 1
8+assert(not debug.gethook())
9+local testline = 19
10+local function test
11+(s,l,p)
12+collectgarbage()
13+local function f
14+(event,line)
15+assert(event == "line")
16+local l = table.remove(l,1)
17+if p then
18+print(l,line)
19+end
20+assert(l == line,"wrong trace!!")
21+end
22+debug.sethook(f,"l")
23+;
24+load(s)()
25+;
26+debug.sethook()
27+assert(# l == 0)
28+end
29+assert(not pcall(debug.getinfo,print,"X"))
30+assert(not pcall(debug.getinfo,0,">"))
31+assert(not debug.getinfo(1e3))
32+assert(not debug.getinfo(- 1))
33+local a = debug.getinfo(print)
34+assert(a.what == "C" and a.short_src == "[C]")
35+a=debug.getinfo(print,"L")
36+assert(a.activelines == nil)
37+local b = debug.getinfo(test,"SfL")
38+assert(b.name == nil and b.what == "Lua" and b.linedefined == testline and b.lastlinedefined == b.linedefined + 10 and b.func == test and not string.find(b.short_src,"%["))
39+assert(b.activelines[b.linedefined + 1] and b.activelines[b.lastlinedefined])
40+assert(not b.activelines[b.linedefined] and not b.activelines[b.lastlinedefined + 1])
41+local func = load(string.dump(load("print(10)"),true))
42+local actl = debug.getinfo(func,"L").activelines
43+assert(# actl == 0)
44+local a = "function f () end"
45+local function dostring
46+(s,x)
47+return load(s,x)()
48+end
49+dostring(a)
50+assert(debug.getinfo(f).short_src == string.format("[string "%s"]",a))
51+dostring(a .. string.format("; %s
52+=1",string.rep("p",400)))
53+assert(string.find(debug.getinfo(f).short_src,"^%[string [^
54+]*%.%.%."%]$"))
55+dostring(a .. string.format("; %s=1",string.rep("p",400)))
56+assert(string.find(debug.getinfo(f).short_src,"^%[string [^
57+]*%.%.%."%]$"))
58+dostring("
59+" .. a)
60+assert(debug.getinfo(f).short_src == "[string "..."]")
61+dostring(a,"")
62+assert(debug.getinfo(f).short_src == "[string ""]")
63+dostring(a,"@xuxu")
64+assert(debug.getinfo(f).short_src == "xuxu")
65+dostring(a,"@" .. string.rep("p",1e3) .. "t")
66+assert(string.find(debug.getinfo(f).short_src,"^%.%.%.p*t$"))
67+dostring(a,"=xuxu")
68+assert(debug.getinfo(f).short_src == "xuxu")
69+dostring(a,string.format("=%s",string.rep("x",500)))
70+assert(string.find(debug.getinfo(f).short_src,"^x*$"))
71+dostring(a,"=")
72+assert(debug.getinfo(f).short_src == "")
73+_G.a=nil
74+;
75+_G.f=nil
76+;
77+_G[string.rep("p",400)]=nil
78+repeat
79+local g = {["x"] = ()
80+local a = debug.getinfo(2)
81+assert(a.name == "f" and a.namewhat == "local")
82+a=debug.getinfo(1)
83+assert(a.name == "x" and a.namewhat == "field")
84+return "xixi"
85+end}
86+local f = ()
87+return 1 + 1 and (not 1 or g.x())
88+end
89+assert(f() == "xixi")
90+g=debug.getinfo(f)
91+assert(g.what == "Lua" and g.func == f and g.namewhat == "" and not g.name)
92+function f(x,name)
93+name=name or "f"
94+local a = debug.getinfo(1)
95+assert(a.name == name and a.namewhat == "local")
96+return x
97+end
98+if 3 > 4 then
99+break
100+end
101+;
102+f()
103+if 3 < 4 then
104+a=1
105+else
106+break
107+end
108+;
109+f()
110+while 1 do
111+local x = 10
112+;
113+break
114+;
115+f()
116+local b = 1
117+if 3 > 4 then
118+return math.sin(1)
119+end
120+;
121+f()
122+a=3 < 4
123+;
124+f()
125+a=3 < 4 or 1
126+;
127+f()
128+repeat
129+local x = 20
130+;
131+if 4 > 3 then
132+f()
133+else
134+break
135+end
136+;
137+f()until 1
138+g={}
139+f(g).x=f(2) and f(10) + f(9)
140+assert(g.x == f(19))
141+function g(x)
142+if not x then
143+return 3
144+end
145+return (x("a","x"))
146+end
147+assert(g(f) == "a")until 1
148+test("if
149+math.sin(1)
150+then
151+ a=1
152+else
153+ a=2
154+end
155+",{2,3,4,7})
156+test("local function foo()
157+end
158+foo()
159+A = 1
160+A = 2
161+A = 3
162+",{2,3,2,4,5,6})
163+_G.A=nil
164+test("--
165+if nil then
166+ a=1
167+else
168+ a=2
169+end
170+",{2,5,6})
171+test("a=1
172+repeat
173+ a=a+1
174+until a==3
175+",{1,3,4,3,4})
176+test(" do
177+ return
178+end
179+",{2})
180+test("local a
181+a=1
182+while a<=3 do
183+ a=a+1
184+end
185+",{1,2,3,4,3,4,3,4,3,5})
186+test("while math.sin(1) do
187+ if math.sin(1)
188+ then break
189+ end
190+end
191+a=1",{1,2,3,6})
192+test("for i=1,3 do
193+ a=i
194+end
195+",{1,2,1,2,1,2,1,3})
196+test("for i,v in pairs{'a','b'} do
197+ a=tostring(i) .. v
198+end
199+",{1,2,1,2,1,3})
200+test("for i=1,4 do a=1 end",{1,1,1,1})
201+_G.a=nil
202+local a = {1,2,3,10,124,125,126,127,128,129,130,255,256,257,500,1e3}
203+local s = " local b = {10}
204+ a = b[1] X + Y b[1]
205+ b = 4
206+ "
207+for _,i in ipairs(a)
208+do
209+local subs = {["X"] = string.rep("
210+",i)}
211+for _,j in ipairs(a)
212+do
213+subs.Y=string.rep("
214+",j)
215+local s = string.gsub(s,"[XY]",subs)
216+test(s,{1,2 + i,2 + i + j,2 + i,2 + i + j,3 + i + j})
217+end
218+end
219+_G.a=nil
220+local function checkactivelines
221+(f,lines)
222+local t = debug.getinfo(f,"SL")
223+for _,l in pairs(lines)
224+do
225+l=l + t.linedefined
226+assert(t.activelines[l])
227+t.activelines[l]=undef
228+end
229+assert(next(t.activelines) == nil)
230+end
231+checkactivelines((...)
232+local a = 20
233+local b = 30
234+end,{4,6,8})
235+checkactivelines((a)
236+local a = 20
237+local b = 30
238+end,{3,4,6})
239+checkactivelines((a,b, ...)
240+
241+end,{0})
242+checkactivelines((a,b)
243+
244+end,{1})
245+for _,n in pairs({0,1,2,10,50,100,1e3,1e4})
246+do
247+checkactivelines(load(string.format("%s return 1",string.rep("
248+",n))),{n + 1})
249+end
250+print("+")
251+assert(not pcall(debug.getlocal,20,1))
252+assert(not pcall(debug.setlocal,- 1,1,10))
253+local function foo
254+(a,b, ...)
255+local d,e =
256+end
257+local co = coroutine.create(foo)
258+assert(debug.getlocal(foo,1) == "a")
259+assert(debug.getlocal(foo,2) == "b")
260+assert(not debug.getlocal(foo,3))
261+assert(debug.getlocal(co,foo,1) == "a")
262+assert(debug.getlocal(co,foo,2) == "b")
263+assert(not debug.getlocal(co,foo,3))
264+assert(not debug.getlocal(print,1))
265+local function foo
266+()
267+return (debug.getlocal(1,- 1))
268+end
269+assert(not foo(10))
270+local function foo
271+(a, ...)
272+local t = table.pack(...)
273+for i = 1, t.n
274+do
275+local n,v = debug.getlocal(1,- i)
276+assert(n == "(vararg)" and v == t[i])
277+end
278+assert(not debug.getlocal(1,- (t.n + 1)))
279+assert(not debug.setlocal(1,- (t.n + 1),30))
280+if t.n > 0 then
281+((x)
282+assert(debug.setlocal(2,- 1,x) == "(vararg)")
283+assert(debug.setlocal(2,- t.n,x) == "(vararg)")
284+end)(430)
285+assert(... == 430)
286+end
287+end
288+foo()
289+foo(print)
290+foo(200,3,4)
291+local a = {}
292+for i = 1, (_soft and 100 or 1e3)
293+do
294+a[i]=i
295+end
296+foo(table.unpack(a))
297+assert(not debug.gethook())
298+local count = 0
299+local function f
300+()
301+assert(debug.getinfo(1).namewhat == "hook")
302+local sndline = string.match(debug.traceback(),"
303+(.-)
304+")
305+assert(string.find(sndline,"hook"))
306+count=count + 1
307+end
308+debug.sethook(f,"l")
309+local a = 0
310+_ENV.a=a
311+a=1
312+debug.sethook()
313+assert(count == 4)
314+_ENV.a=nil
315+assert(getmetatable(debug.getregistry()._HOOKKEY).__mode == "k")
316+a={}
317+;
318+local L = nil
319+local glob = 1
320+local oldglob = glob
321+debug.sethook((e,l)
322+collectgarbage()
323+local f,m,c = debug.gethook()
324+assert(m == "crl" and c == 0)
325+if e == "line" then
326+if glob ~= oldglob then
327+L=l - 1
328+oldglob=glob
329+end
330+elseife == "call" then
331+local f = debug.getinfo(2,"f").func
332+a[f]=1
333+else
334+assert(e == "return")
335+end
336+end,"crl")
337+function f(a,b)
338+collectgarbage()
339+local _,x = debug.getlocal(1,1)
340+local _,y = debug.getlocal(1,2)
341+assert(x == a and y == b)
342+assert(debug.setlocal(2,3,"pera") == "AA" .. "AA")
343+assert(debug.setlocal(2,4,"manga") == "B")
344+x=debug.getinfo(2)
345+assert(x.func == g and x.what == "Lua" and x.name == "g" and x.nups == 2 and string.find(x.source,"^@.*db%.lua$"))
346+glob=glob + 1
347+assert(debug.getinfo(1,"l").currentline == L + 1)
348+assert(debug.getinfo(1,"l").currentline == L + 2)
349+end
350+function foo()
351+glob=glob + 1
352+assert(debug.getinfo(1,"l").currentline == L + 1)
353+end
354+;
355+foo()
356+local _ = "alo
357+alo" .. "
358+"
359+assert(debug.getinfo(1,"l").currentline == L + 11)
360+function g(...)
361+local arg = {...}
362+local a,b,c =
363+;
364+a=math.sin(40)
365+;
366+local feijao =
367+local AAAA,B = "xuxu","abacate"
368+f(AAAA,B)
369+assert(AAAA == "pera" and B == "manga")
370+local B = 13
371+local x,y = debug.getlocal(1,5)
372+assert(x == "B" and y == 13)
373+end
374+g()
375+assert(a[f] and a[g] and a[assert] and a[debug.getlocal] and not a[print])
376+local n,v = debug.getlocal(0,1)
377+assert(v == 0 and n == "(C temporary)")
378+local n,v = debug.getlocal(0,2)
379+assert(v == 2 and n == "(C temporary)")
380+assert(not debug.getlocal(0,3))
381+assert(not debug.getlocal(0,0))
382+function f()
383+assert(select(2,debug.getlocal(2,3)) == 1)
384+assert(not debug.getlocal(2,4))
385+debug.setlocal(2,3,10)
386+return 20
387+end
388+function g(a,b)
389+return (a + 1) + f()
390+end
391+assert(g(0,0) == 30)
392+_G.f,_G.g=nil
393+debug.sethook(nil)
394+;
395+assert(not debug.gethook())
396+assert(not debug.setuservalue(io.stdin,10))
397+local a,b = debug.getuservalue(io.stdin,10)
398+assert(a == nil and not b)
399+local function f
400+(...)
401+return 3,...
402+end
403+local count = 0
404+local a = {}
405+for i = 1, 100
406+do
407+a[i]=i
408+end
409+debug.sethook(()
410+count=count + 1
411+end,"",1)
412+local t = {table.unpack(a)}
413+assert(# t == 100)
414+t={table.unpack(a,1,3)}
415+assert(# t == 3)
416+t={f(table.unpack(a,1,30))}
417+assert(# t == 31)
418+local function collectlocals
419+(level)
420+local tab = {}
421+for i = 1, math.huge
422+do
423+local n,v = debug.getlocal(level + 1,i)
424+if not (n and string.find(n,"^[a-zA-Z0-9_]+$")) then
425+break
426+end
427+tab[n]=v
428+end
429+return tab
430+end
431+local X = nil
432+a={}
433+function a:f(a,b, ...)
434+local arg = {...}
435+;
436+local c = 13
437+end
438+debug.sethook((e)
439+assert(e == "call")
440+dostring("XX = 12")
441+assert(not pcall(load("a='joao'+1")))
442+debug.sethook((e,l)
443+assert(debug.getinfo(2,"l").currentline == l)
444+local f,m,c = debug.gethook()
445+assert(e == "line")
446+assert(m == "l" and c == 0)
447+debug.sethook(nil)
448+assert(not X)
449+X=collectlocals(2)
450+end,"l")
451+end,"c")
452+a:f(1,2,3,4,5)
453+assert(X.self == a and X.a == 1 and X.b == 2 and X.c == nil)
454+assert(XX == 12)
455+assert(not debug.gethook())
456+_G.XX=nil
457+local X = false
458+local function foo
459+(a,b, ...)
460+local x,y,z =
461+local c,d = 10,20
462+return
463+end
464+local function aux
465+()
466+if debug.getinfo(2).name == "foo" then
467+X=true
468+local tab = {["a"] = 100,["b"] = 200,["c"] = 10,["d"] = 20}
469+for n,v in pairs(collectlocals(2))
470+do
471+assert(tab[n] == v)
472+tab[n]=undef
473+end
474+assert(next(tab) == nil)
475+end
476+end
477+debug.sethook(aux,"r")
478+;
479+foo(100,200)
480+;
481+debug.sethook()
482+assert(X)
483+local function eqseq
484+(t1,t2)
485+assert(# t1 == # t2)
486+for i = 1, # t1
487+do
488+assert(t1[i] == t2[i])
489+end
490+end
491+print("testing inspection of parameters/returned values")
492+local on = false
493+local inp,out =
494+local function hook
495+(event)
496+if not on then
497+return
498+end
499+local ar = debug.getinfo(2,"ruS")
500+local t = {}
501+for i = ar.ftransfer, ar.ftransfer + ar.ntransfer - 1
502+do
503+local _,v = debug.getlocal(2,i)
504+t[# t + 1]=v
505+end
506+if event == "return" then
507+out=t
508+else
509+inp=t
510+end
511+end
512+debug.sethook(hook,"cr")
513+on=true
514+;
515+math.sin(3)
516+;
517+on=false
518+eqseq(inp,{3})
519+;
520+eqseq(out,{math.sin(3)})
521+on=true
522+;
523+select(2,10,20,30,40)
524+;
525+on=false
526+eqseq(inp,{2,10,20,30,40})
527+;
528+eqseq(out,{20,30,40})
529+local function foo
530+(a, ...)
531+return ...
532+end
533+local function foo1
534+()
535+on=not on
536+;
537+return foo(20,10,0)
538+end
539+foo1()
540+;
541+on=false
542+eqseq(inp,{20})
543+;
544+eqseq(out,{10,0})
545+debug.sethook()
546+local function getupvalues
547+(f)
548+local t = {}
549+local i = 1
550+while true do
551+local name,value = debug.getupvalue(f,i)
552+if not name then
553+break
554+end
555+assert(not t[name])
556+t[name]=value
557+i=i + 1
558+return t
559+end
560+local a,b,c = 1,2,3
561+local function foo1
562+(a)
563+b=a
564+;
565+return c
566+end
567+local function foo2
568+(x)
569+a=x
570+;
571+return c + b
572+end
573+assert(not debug.getupvalue(foo1,3))
574+assert(not debug.getupvalue(foo1,0))
575+assert(not debug.setupvalue(foo1,3,"xuxu"))
576+local t = getupvalues(foo1)
577+assert(t.a == nil and t.b == 2 and t.c == 3)
578+t=getupvalues(foo2)
579+assert(t.a == 1 and t.b == 2 and t.c == 3)
580+assert(debug.setupvalue(foo1,1,"xuxu") == "b")
581+assert(({debug.getupvalue(foo2,3)})[2] == "xuxu")
582+assert(debug.getupvalue(string.gmatch("x","x"),1) == "")
583+local a = 0
584+debug.sethook((e)
585+a=a + 1
586+end,"",1)
587+a=0
588+;
589+for i = 1, 1e3
590+do
591+
592+end
593+;
594+assert(1e3 < a and a < 1012)
595+debug.sethook((e)
596+a=a + 1
597+end,"",4)
598+a=0
599+;
600+for i = 1, 1e3
601+do
602+
603+end
604+;
605+assert(250 < a and a < 255)
606+local f,m,c = debug.gethook()
607+assert(m == "" and c == 4)
608+debug.sethook((e)
609+a=a + 1
610+end,"",4e3)
611+a=0
612+;
613+for i = 1, 1e3
614+do
615+
616+end
617+;
618+assert(a == 0)
619+debug.sethook(print,"",2 ^ 24 - 1)
620+local f,m,c = debug.gethook()
621+assert(({debug.gethook()})[3] == 2 ^ 24 - 1)
622+debug.sethook()
623+local g,g1 =
624+local function f
625+(x)
626+if x then
627+assert(debug.getinfo(1,"S").what == "Lua")
628+assert(debug.getinfo(1,"t").istailcall == true)
629+local tail = debug.getinfo(2)
630+assert(tail.func == g1 and tail.istailcall == true)
631+assert(debug.getinfo(3,"S").what == "main")
632+print("+")
633+end
634+end
635+function g(x)
636+return f(x)
637+end
638+function g1(x)
639+g(x)
640+end
641+local function h
642+(x)
643+local f = g1
644+;
645+return f(x)
646+end
647+h(true)
648+local b = {}
649+debug.sethook((e)
650+table.insert(b,e)
651+end,"cr")
652+h(false)
653+debug.sethook()
654+local res = {"return","call","tail call","call","tail call","return","return","call"}
655+for i = 1, # res
656+do
657+assert(res[i] == table.remove(b,1))
658+end
659+b=0
660+debug.sethook((e)
661+if e == "tail call" then
662+b=b + 1
663+assert(debug.getinfo(2,"t").istailcall == true)
664+else
665+assert(debug.getinfo(2,"t").istailcall == false)
666+end
667+end,"c")
668+h(false)
669+debug.sethook()
670+assert(b == 2)
671+local lim = _soft and 3e3 or 3e4
672+local function foo
673+(x)
674+if x == 0 then
675+assert(debug.getinfo(2).what == "main")
676+local info = debug.getinfo(1)
677+assert(info.istailcall == true and info.func == foo)
678+else
679+return foo(x - 1)
680+end
681+end
682+foo(lim)
683+print("+")
684+co=load(" local A = function ()
685+ return x
686+ end
687+ return
688+")
689+local a = 0
690+debug.sethook((e,l)
691+if l == 3 then
692+a=a + 1
693+;
694+assert(debug.getlocal(2,1) == "(temporary)")
695+elseifl == 4 then
696+a=a + 1
697+;
698+assert(debug.getlocal(2,1) == "A")
699+end
700+end,"l")
701+co()
702+debug.sethook()
703+assert(a == 2)
704+assert(debug.traceback(print) == print)
705+assert(debug.traceback(print,4) == print)
706+assert(string.find(debug.traceback("hi",4),"^hi
707+"))
708+assert(string.find(debug.traceback("hi"),"^hi
709+"))
710+assert(not string.find(debug.traceback("hi"),"'debug.traceback'"))
711+assert(string.find(debug.traceback("hi",0),"'debug.traceback'"))
712+assert(string.find(debug.traceback(),"^stack traceback:
713+"))
714+local st,msg = (()
715+return pcall
716+end)()(debug.traceback)
717+assert(st == true and string.find(msg,"pcall"))
718+local t = debug.getinfo(print,"u")
719+assert(t.isvararg == true and t.nparams == 0 and t.nups == 0)
720+t=debug.getinfo((a,b,c)
721+
722+end,"u")
723+assert(t.isvararg == false and t.nparams == 3 and t.nups == 0)
724+t=debug.getinfo((a,b, ...)
725+return t[a]
726+end,"u")
727+assert(t.isvararg == true and t.nparams == 2 and t.nups == 1)
728+t=debug.getinfo(1)
729+assert(t.isvararg == true and t.nparams == 0 and t.nups == 1 and debug.getupvalue(t.func,1) == "_ENV")
730+t=debug.getinfo(math.sin)
731+assert(t.isvararg == true and t.nparams == 0 and t.nups == 0)
732+t=debug.getinfo(string.gmatch("abc","a"))
733+assert(t.isvararg == true and t.nparams == 0 and t.nups > 0)
734+local function checktraceback
735+(co,p,level)
736+local tb = debug.traceback(co,nil,level)
737+local i = 0
738+for l in string.gmatch(tb,"[^
739+]+
740+?")
741+do
742+assert(i == 0 or string.find(l,p[i]))
743+i=i + 1
744+end
745+assert(p[i] == undef)
746+end
747+local function f
748+(n)
749+if n > 0 then
750+f(n - 1)
751+else
752+coroutine.yield()
753+end
754+end
755+local co = coroutine.create(f)
756+coroutine.resume(co,3)
757+checktraceback(co,{"yield","db.lua","db.lua","db.lua","db.lua"})
758+checktraceback(co,{"db.lua","db.lua","db.lua","db.lua"},1)
759+checktraceback(co,{"db.lua","db.lua","db.lua"},2)
760+checktraceback(co,{"db.lua"},4)
761+checktraceback(co,{},40)
762+co=coroutine.create((x)
763+local a = 1
764+coroutine.yield(debug.getinfo(1,"l"))
765+coroutine.yield(debug.getinfo(1,"l").currentline)
766+return a
767+end)
768+local tr = {}
769+local foo = (e,l)
770+if l then
771+table.insert(tr,l)
772+end
773+end
774+debug.sethook(co,foo,"lcr")
775+local _,l = coroutine.resume(co,10)
776+local x = debug.getinfo(co,1,"lfLS")
777+assert(x.currentline == l.currentline and x.activelines[x.currentline])
778+assert(type(x.func) == "function")
779+for i = x.linedefined + 1, x.lastlinedefined
780+do
781+assert(x.activelines[i])
782+x.activelines[i]=undef
783+end
784+assert(next(x.activelines) == nil)
785+assert(not debug.getinfo(co,2))
786+local a,b = debug.getlocal(co,1,1)
787+assert(a == "x" and b == 10)
788+a,b=debug.getlocal(co,1,2)
789+assert(a == "a" and b == 1)
790+debug.setlocal(co,1,2,"hi")
791+assert(debug.gethook(co) == foo)
792+assert(# tr == 2 and tr[1] == l.currentline - 1 and tr[2] == l.currentline)
793+a,b,c=pcall(coroutine.resume,co)
794+assert(a and b and c == l.currentline + 1)
795+checktraceback(co,{"yield","in function <"})
796+a,b=coroutine.resume(co)
797+assert(a and b == "hi")
798+assert(# tr == 4 and tr[4] == l.currentline + 2)
799+assert(debug.gethook(co) == foo)
800+assert(not debug.gethook())
801+checktraceback(co,{})
802+co=coroutine.create((x)
803+local a,b = coroutine.yield(x)
804+assert(a == 100 and b == nil)
805+return x
806+end)
807+a,b=coroutine.resume(co,10)
808+assert(a and b == 10)
809+a,b=debug.getlocal(co,1,1)
810+assert(a == "x" and b == 10)
811+assert(not debug.getlocal(co,1,5))
812+assert(debug.setlocal(co,1,1,30) == "x")
813+assert(not debug.setlocal(co,1,5,40))
814+a,b=coroutine.resume(co,100)
815+assert(a and b == 30)
816+function f(i)
817+if i == 0 then
818+error(i)
819+else
820+coroutine.yield()
821+;
822+f(i - 1)
823+end
824+end
825+co=coroutine.create((x)
826+f(x)
827+end)
828+a,b=coroutine.resume(co,3)
829+t={"'coroutine.yield'","'f'","in function <"}
830+while coroutine.status(co) == "suspended" do
831+checktraceback(co,t)
832+a,b=coroutine.resume(co)
833+table.insert(t,2,"'f'")
834+t[1]="'error'"
835+checktraceback(co,t)
836+local function g
837+(x)
838+coroutine.yield(x)
839+end
840+local function f
841+(i)
842+debug.sethook(()
843+
844+end,"l")
845+for j = 1, 1e3
846+do
847+g(i + j)
848+end
849+end
850+local co = coroutine.wrap(f)
851+co(10)
852+pcall(co)
853+pcall(co)
854+assert(type(debug.getregistry()) == "table")
855+local a = {}
856+local function f
857+(t)
858+local info = debug.getinfo(1)
859+;
860+assert(info.namewhat == "metamethod")
861+a.op=info.name
862+return info.name
863+end
864+setmetatable(a,{["__index"] = f,["__add"] = f,["__div"] = f,["__mod"] = f,["__concat"] = f,["__pow"] = f,["__mul"] = f,["__idiv"] = f,["__unm"] = f,["__len"] = f,["__sub"] = f,["__shl"] = f,["__shr"] = f,["__bor"] = f,["__bxor"] = f,["__eq"] = f,["__le"] = f,["__lt"] = f,["__unm"] = f,["__len"] = f,["__band"] = f,["__bnot"] = f})
865+local b = setmetatable({},getmetatable(a))
866+assert(a[3] == "index" and a ^ 3 == "pow" and a .. a == "concat")
867+assert(a / 3 == "div" and 3 % a == "mod")
868+assert(a + 3 == "add" and 3 - a == "sub" and a * 3 == "mul" and - a == "unm" and # a == "len" and a & 3 == "band")
869+assert(a + 3e4 == "add" and a - 3 == "sub" and a * 3 == "mul" and - a == "unm" and # a == "len" and a & 3 == "band")
870+assert(a | 3 == "bor" and 3 ~ a == "bxor" and a << 3 == "shl" and a >> 1 == "shr")
871+assert(a == b and a.op == "eq")
872+assert(a >= b and a.op == "le")
873+assert("x" >= a and a.op == "le")
874+assert(a > b and a.op == "lt")
875+assert(a > 10 and a.op == "lt")
876+assert(~ a == "bnot")
877+local function f
878+()
879+assert(debug.getinfo(1).name == "for iterator")
880+end
881+for i in f
882+do
883+
884+end
885+local name = nil
886+setmetatable({},{["__gc"] = ()
887+local t = debug.getinfo(1)
888+assert(t.namewhat == "metamethod")
889+name=t.name
890+end})
891+repeat
892+local a = {}until name
893+assert(name == "__gc")
894+print("testing traceback sizes")
895+local function countlines
896+(s)
897+return select(2,string.gsub(s,"
898+",""))
899+end
900+local function deep
901+(lvl,n)
902+if lvl == 0 then
903+return (debug.traceback("message",n))
904+else
905+return (deep(lvl - 1,n))
906+end
907+end
908+local function checkdeep
909+(total,start)
910+local s = deep(total,start)
911+local rest = string.match(s,"^message
912+stack traceback:
913+(.*)$")
914+local cl = countlines(rest)
915+assert(cl <= 10 + 11 + 1)
916+local brk = string.find(rest,"%.%.%. %(skip")
917+if brk then
918+local rest1 = string.sub(rest,1,brk)
919+local rest2 = string.sub(rest,brk,# rest)
920+assert(countlines(rest1) == 10 and countlines(rest2) == 11)
921+else
922+assert(cl == total - start + 2)
923+end
924+end
925+for d = 1, 51, 10
926+do
927+for l = 1, d
928+do
929+coroutine.wrap(checkdeep)(d,l)
930+end
931+end
932+print("testing debug functions on chunk without debug info")
933+local prog = "-- program to be loaded without debug information (strip)
934+local debug = require'debug'
935+local a = 12 -- a local variable
936+
937+local n, v = debug.getlocal(1, 1)
938+assert(n == "(temporary)" and v == debug) -- unkown name but known value
939+n, v = debug.getlocal(1, 2)
940+assert(n == "(temporary)" and v == 12) -- unkown name but known value
941+
942+-- a function with an upvalue
943+local f = function () local x; return a end
944+n, v = debug.getupvalue(f, 1)
945+assert(n == "(no name)" and v == 12)
946+assert(debug.setupvalue(f, 1, 13) == "(no name)")
947+assert(a == 13)
948+
949+local t = debug.getinfo(f)
950+assert(t.name == nil and t.linedefined > 0 and
951+ t.lastlinedefined == t.linedefined and
952+ t.short_src == "?")
953+assert(debug.getinfo(1).currentline == -1)
954+
955+t = debug.getinfo(f, "L").activelines
956+assert(next(t) == nil) -- active lines are empty
957+
958+-- dump/load a function without debug info
959+f = load(string.dump(f))
960+
961+t = debug.getinfo(f)
962+assert(t.name == nil and t.linedefined > 0 and
963+ t.lastlinedefined == t.linedefined and
964+ t.short_src == "?")
965+assert(debug.getinfo(1).currentline == -1)
966+
967+return a
968+"
969+local f = assert(load(string.dump(load(prog),true)))
970+assert(f() == 13)
971+local function foo
972+()
973+local a = 1
974+local b = 2
975+return b
976+end
977+local s = load(string.dump(foo,true))
978+local line = true
979+debug.sethook((e,l)
980+assert(e == "line")
981+line=l
982+end,"l")
983+assert(s() == 2)
984+;
985+debug.sethook(nil)
986+assert(line == nil)
987+local prog = " return function (x)
988+ return function (y)
989+ return x + y
990+ end
991+ end
992+ "
993+local name = string.rep("x",1e3)
994+local p = assert(load(prog,name))
995+local c = string.dump(p)
996+assert(# c > 1e3 and # c < 2e3)
997+local f = assert(load(c))
998+local g = f()
999+local h = g(3)
1000+assert(h(5) == 8)
1001+assert(debug.getinfo(f).source == name and debug.getinfo(g).source == name and debug.getinfo(h).source == name)
1002+local c = string.dump(p,true)
1003+assert(# c < 500)
1004+local f = assert(load(c))
1005+local g = f()
1006+local h = g(30)
1007+assert(h(50) == 80)
1008+assert(debug.getinfo(f).source == "=?" and debug.getinfo(g).source == "=?" and debug.getinfo(h).source == "=?")
1009+print("OK")
zod/luau/res/lua/cycled/errors.luanew file+610
@@ -0,0 +1,610 @@
1+print("testing errors")
2+local debug = require("debug")
3+local mt = getmetatable(_G) or {}
4+local oldmm = mt.__index
5+mt.__index=nil
6+local function checkerr
7+(msg,f, ...)
8+local st,err = pcall(f,...)
9+assert(not st and string.find(err,msg))
10+end
11+local function doit
12+(s)
13+local f,msg = load(s)
14+if not f then
15+return msg
16+end
17+local cond,msg = pcall(f)
18+return (not cond) and msg
19+end
20+local function checkmessage
21+(prog,msg,debug)
22+local m = doit(prog)
23+if debug then
24+print(m,msg)
25+end
26+assert(string.find(m,msg,1,true))
27+end
28+local function checksyntax
29+(prog,extra,token,line)
30+local msg = doit(prog)
31+if not string.find(token,"^<%a") and not string.find(token,"^char%(") then
32+token="'" .. token .. "'"
33+end
34+token=string.gsub(token,"(%p)","%%%1")
35+local pt = string.format("^%%[string ".*"%%]:%d: .- near %s$",line,token)
36+assert(string.find(msg,pt))
37+assert(string.find(msg,msg,1,true))
38+end
39+assert(doit("error('hi', 0)") == "hi")
40+assert(doit("error()") == nil)
41+assert(doit("table.unpack({}, 1, n=2^30)"))
42+assert(doit("a=math.sin()"))
43+assert(not doit("tostring(1)") and doit("tostring()"))
44+assert(doit("tonumber()"))
45+assert(doit("repeat until 1; a"))
46+assert(doit("return;;"))
47+assert(doit("assert(false)"))
48+assert(doit("assert(nil)"))
49+assert(doit("function a (... , ...) end"))
50+assert(doit("function a (, ...) end"))
51+assert(doit("local t={}; t = t[#t] + 1"))
52+checksyntax(" local a = {4
53+
54+","'}' expected (to close '{' at line 1)","<eof>",3)
55+local function checksyntax
56+(prog,msg,line)
57+local st,err = load(prog)
58+assert(string.find(err,"line " .. line))
59+assert(string.find(err,msg,1,true))
60+end
61+checksyntax(" ::A:: a = 1
62+ ::A::
63+ ","label 'A' already defined",1)
64+checksyntax(" a = 1
65+ goto A
66+ do ::A:: end
67+ ","no visible label 'A'",2)
68+if not T then
69+(Message or print)("
70+ >>> testC not active: skipping tests for messages in C <<<
71+")
72+else
73+print("testing memory error message")
74+local a = {}
75+for i = 1, 1e4
76+do
77+a[i]=true
78+end
79+collectgarbage()
80+T.totalmem(T.totalmem() + 1e4)
81+local st,msg = pcall(()
82+for i = 1, 1e5
83+do
84+a[i]=tostring(i)
85+end
86+end)
87+T.totalmem(0)
88+assert(not st and msg == "not enough" .. " memory")
89+local res = T.testC(" # push 16 elements on the stack
90+ pushnum 1; pushnum 1; pushnum 1; pushnum 1; pushnum 1;
91+ pushnum 1; pushnum 1; pushnum 1; pushnum 1; pushnum 1;
92+ pushnum 1; pushnum 1; pushnum 1; pushnum 1; pushnum 1;
93+ pushnum 1;
94+ # traceback should work with 4 remaining slots
95+ traceback xuxu 1;
96+ return 1
97+ ")
98+assert(string.find(res,"xuxu.-main chunk"))
99+end
100+checkmessage("a = {} + 1","arithmetic")
101+checkmessage("a = {} | 1","bitwise operation")
102+checkmessage("a = {} < 1","attempt to compare")
103+checkmessage("a = {} <= 1","attempt to compare")
104+checkmessage("aaa=1; bbbb=2; aaa=math.sin(3)+bbbb(3)","global 'bbbb'")
105+checkmessage("aaa={}; do local aaa=1 end aaa:bbbb(3)","method 'bbbb'")
106+checkmessage("local a={}; a.bbbb(3)","field 'bbbb'")
107+assert(not string.find(doit("aaa={13}; local bbbb=1; aaa[bbbb](3)"),"'bbbb'"))
108+checkmessage("aaa={13}; local bbbb=1; aaa[bbbb](3)","number")
109+checkmessage("aaa=(1)..{}","a table value")
110+checkmessage("a = {_ENV = {}}; print(a._ENV.x + 1)","field 'x'")
111+_G.aaa,_G.bbbb=nil
112+checkmessage("local a; a(13)","local 'a'")
113+checkmessage(" local a = setmetatable({}, {__add = 34})
114+ a = a + 1
115+","metamethod 'add'")
116+checkmessage(" local a = setmetatable({}, {__lt = {}})
117+ a = a > a
118+","metamethod 'lt'")
119+checkmessage("local a={}; return a.bbbb(3)","field 'bbbb'")
120+checkmessage("aaa={}; do local aaa=1 end; return aaa:bbbb(3)","method 'bbbb'")
121+checkmessage("aaa = #print","length of a function value")
122+checkmessage("aaa = #3","length of a number value")
123+_G.aaa=nil
124+checkmessage("aaa.bbb:ddd(9)","global 'aaa'")
125+checkmessage("local aaa={bbb=1}; aaa.bbb:ddd(9)","field 'bbb'")
126+checkmessage("local aaa={bbb={}}; aaa.bbb:ddd(9)","method 'ddd'")
127+checkmessage("local a,b,c; (function () a = b+1.1 end)()","upvalue 'b'")
128+assert(not doit("local aaa={bbb={ddd=next}}; aaa.bbb:ddd(nil)"))
129+checkmessage("local a,b,cc; (function () a = cc[1] end)()","upvalue 'cc'")
130+checkmessage("local a,b,cc; (function () a.x = 1 end)()","upvalue 'a'")
131+checkmessage("local _ENV = {x={}}; a = a + 1","global 'a'")
132+checkmessage("BB=1; local aaa={}; x=aaa+BB","local 'aaa'")
133+checkmessage("aaa={}; x=3.3/aaa","global 'aaa'")
134+checkmessage("aaa=2; BB=nil;x=aaa*BB","global 'BB'")
135+checkmessage("aaa={}; x=-aaa","global 'aaa'")
136+checkmessage("aaa=1; local aaa,bbbb=2,3; aaa = math.sin(1) and bbbb(3)","local 'bbbb'")
137+checkmessage("aaa=1; local aaa,bbbb=2,3; aaa = bbbb(1) or aaa(3)","local 'bbbb'")
138+checkmessage("local a,b,c,f = 1,1,1; f((a and b) or c)","local 'f'")
139+checkmessage("local a,b,c = 1,1,1; ((a and b) or c)()","call a number value")
140+assert(not string.find(doit("aaa={}; x=(aaa or aaa)+(aaa and aaa)"),"'aaa'"))
141+assert(not string.find(doit("aaa={}; (aaa or aaa)()"),"'aaa'"))
142+checkmessage("print(print < 10)","function with number")
143+checkmessage("print(print < print)","two function values")
144+checkmessage("print('10' < 10)","string with number")
145+checkmessage("print(10 < '23')","number with string")
146+checkmessage("local a = 2.0^100; x = a << 2","local a")
147+checkmessage("local a = 1 >> 2.0^100","has no integer representation")
148+checkmessage("local a = 10.1 << 2.0^100","has no integer representation")
149+checkmessage("local a = 2.0^100 & 1","has no integer representation")
150+checkmessage("local a = 2.0^100 & 1e100","has no integer representation")
151+checkmessage("local a = 2.0 | 1e40","has no integer representation")
152+checkmessage("local a = 2e100 ~ 1","has no integer representation")
153+checkmessage("string.sub('a', 2.0^100)","has no integer representation")
154+checkmessage("string.rep('a', 3.3)","has no integer representation")
155+checkmessage("return 6e40 & 7","has no integer representation")
156+checkmessage("return 34 << 7e30","has no integer representation")
157+checkmessage("return ~-3e40","has no integer representation")
158+checkmessage("return ~-3.009","has no integer representation")
159+checkmessage("return 3.009 & 1","has no integer representation")
160+checkmessage("return 34 >> {}","table value")
161+checkmessage("aaa = 24 // 0","divide by zero")
162+checkmessage("aaa = 1 % 0","'n%0'")
163+checkmessage("local a = setmetatable({}, {__index = 10}).x","attempt to index a number value")
164+checkmessage("for i = {}, 10 do end","table")
165+checkmessage("for i = io.stdin, 10 do end","FILE")
166+checkmessage("for i = {}, 10 do end","initial value")
167+checkmessage("for i = 1, 'x', 10 do end","string")
168+checkmessage("for i = 1, {}, 10 do end","limit")
169+checkmessage("for i = 1, {} do end","limit")
170+checkmessage("for i = 1, 10, print do end","step")
171+checkmessage("for i = 1, 10, print do end","function")
172+_G.D=debug
173+checkmessage(" -- create light udata
174+ local x = D.upvalueid(function () return debug end, 1)
175+ D.setuservalue(x, {})
176+","light userdata")
177+_G.D=nil
178+checkmessage("math.sin(io.input())","(number expected, got FILE*)")
179+_G.XX=setmetatable({},{["__name"] = "My Type"})
180+assert(string.find(tostring(XX),"^My Type"))
181+checkmessage("io.input(XX)","(FILE* expected, got My Type)")
182+checkmessage("return XX + 1","on a My Type value")
183+checkmessage("return ~io.stdin","on a FILE* value")
184+checkmessage("return XX < XX","two My Type values")
185+checkmessage("return {} < XX","table with My Type")
186+checkmessage("return XX < io.stdin","My Type with FILE*")
187+_G.XX=nil
188+if T then
189+local x = setmetatable({},{["__name"] = "TABLE"})
190+assert(T.testC("Ltolstring -1; return 1",x) == tostring(x))
191+local a,b = T.testC("pushint 10; Ltolstring -2; return 2",x)
192+assert(a == 10 and b == tostring(x))
193+setmetatable(x,{["__tostring"] = (o)
194+assert(o == x)
195+return "ABC"
196+end})
197+local a,b,c = T.testC("pushint 10; Ltolstring -2; return 3",x)
198+assert(a == x and b == 10 and c == "ABC")
199+end
200+checkmessage("(io.write or print){}","io.write")
201+checkmessage("(collectgarbage or print){}","collectgarbage")
202+local f = (a)
203+return a + 1
204+end
205+f=assert(load(string.dump(f,true)))
206+assert(f(3) == 4)
207+checkerr("^%?:%-1:",f,{})
208+f=()
209+local a =
210+;
211+a={}
212+;
213+return a + 2
214+end
215+f=assert(load(string.dump(f,true)))
216+checkerr("^%?:%-1:.*table value",f)
217+local t = {}
218+for i = 1, 1e3
219+do
220+t[i]="aaa = x" .. i
221+end
222+local s = table.concat(t,"; ")
223+t=nil
224+checkmessage(s .. "; aaa = bbb + 1","global 'bbb'")
225+checkmessage("local _ENV=_ENV;" .. s .. "; aaa = bbb + 1","global 'bbb'")
226+checkmessage(s .. "; local t = {}; aaa = t.bbb + 1","field 'bbb'")
227+checkmessage(s .. "; local t = {}; t:bbb()","method 'bbb'")
228+checkmessage("aaa=9
229+repeat until 3==3
230+local x=math.sin(math.cos(3))
231+if math.sin(1) == x then return math.sin(1) end -- tail call
232+local a,b = 1, {
233+ {x='a'..'b'..'c', y='b', z=x},
234+ {1,2,3,4,5} or 3+3<=3+3,
235+ 3+1>3+1,
236+ {d = x and aaa[x or y]}}
237+","global 'aaa'")
238+checkmessage("local x,y = {},1
239+if math.sin(1) == 0 then return 3 end -- return
240+x.a()","field 'a'")
241+checkmessage("prefix = nil
242+insert = nil
243+while 1 do
244+ local a
245+ if nil then break end
246+ insert(prefix, a)
247+end","global 'insert'")
248+checkmessage(" -- tail call
249+ return math.sin("a")
250+","sin")
251+checkmessage("collectgarbage("nooption")","invalid option")
252+checkmessage("x = print .. "a"","concatenate")
253+checkmessage("x = "a" .. false","concatenate")
254+checkmessage("x = {} .. 2","concatenate")
255+checkmessage("getmetatable(io.stdin).__gc()","no value")
256+checkmessage("local Var
257+local function main()
258+ NoSuchName (function() Var=0 end)
259+end
260+main()
261+","global 'NoSuchName'")
262+print("+")
263+aaa={}
264+;
265+setmetatable(aaa,{["__index"] = string})
266+checkmessage("aaa:sub()","bad self")
267+checkmessage("string.sub('a', {})","#2")
268+checkmessage("('a'):sub{}","#1")
269+checkmessage("table.sort({1,2,3}, table.sort)","'table.sort'")
270+checkmessage("string.gsub('s', 's', setmetatable)","'setmetatable'")
271+_G.aaa=nil
272+local function f
273+(n)
274+local c = coroutine.create(f)
275+local a,b = coroutine.resume(c)
276+return b
277+end
278+assert(string.find(f(),"C stack overflow"))
279+checkmessage("coroutine.yield()","outside a coroutine")
280+f=coroutine.wrap(()
281+table.sort({1,2,3},coroutine.yield)
282+end)
283+checkerr("yield across",f)
284+local idsize = 60 - 1
285+local function checksize
286+(source)
287+local _,msg = load("x",source)
288+msg=string.match(msg,"^([^:]*):")
289+assert(msg:len() <= idsize)
290+end
291+for i = 60 - 10, 60 + 10
292+do
293+checksize("@" .. string.rep("x",i))
294+checksize(string.rep("x",i - 10))
295+checksize("=" .. string.rep("x",i))
296+end
297+local function lineerror
298+(s,l)
299+local err,msg = pcall(load(s))
300+local line = tonumber(string.match(msg,":(%d+):"))
301+assert(line == l or (not line and not l))
302+end
303+lineerror("local a
304+ for i=1,'a' do
305+ print(i)
306+ end",2)
307+lineerror("
308+ local a
309+ for k,v in 3
310+ do
311+ print(k)
312+ end",3)
313+lineerror("
314+
315+ for k,v in
316+ 3
317+ do
318+ print(k)
319+ end",4)
320+lineerror("function a.x.y ()
321+a=a+1
322+end",1)
323+lineerror("a =
324+a
325++
326+{}",3)
327+lineerror("a =
328+3
329++
330+(
331+4
332+/
333+print)",6)
334+lineerror("a =
335+print
336++
337+(
338+4
339+/
340+7)",3)
341+lineerror("a
342+=
343+-
344+
345+print
346+;",3)
347+lineerror("a
348+( -- <<
349+23)
350+",2)
351+lineerror("local a = {x = 13}
352+a
353+.
354+x
355+( -- <<
356+23
357+)
358+",5)
359+lineerror("local a = {x = 13}
360+a
361+.
362+x
363+(
364+23 + a
365+)
366+",6)
367+local p = " function g() f() end
368+ function f(x) error('a', XX) end
369+g()
370+"
371+XX=3
372+;
373+lineerror((p),3)
374+XX=0
375+;
376+lineerror((p),false)
377+XX=1
378+;
379+lineerror((p),2)
380+XX=2
381+;
382+lineerror((p),1)
383+_G.XX,_G.g,_G.f=nil
384+lineerror("local b = false
385+if not b then
386+ error 'test'
387+end",3)
388+lineerror("local b = false
389+if not b then
390+ if not b then
391+ if not b then
392+ error 'test'
393+ end
394+ end
395+end",5)
396+lineerror(" local a = 0
397+ local b = 1
398+ local c = b % a
399+",3)
400+local s = string.format("%s return __A.x",string.rep("
401+",300))
402+lineerror(s,301)
403+if not _soft then
404+collectgarbage()
405+print("testing stack overflow")
406+local C = 0
407+local l = debug.getinfo(1,"l").currentline + 1
408+local function auxy
409+()
410+C=C + 1
411+;
412+auxy()
413+end
414+function YY()
415+collectgarbage("stop")
416+auxy()
417+collectgarbage("restart")
418+end
419+local function checkstackmessage
420+(m)
421+print("(expected stack overflow after " .. C .. " calls)")
422+C=0
423+return (string.find(m,"stack overflow"))
424+end
425+assert(checkstackmessage(doit("YY()")))
426+assert(checkstackmessage(doit("YY()")))
427+assert(checkstackmessage(doit("YY()")))
428+_G.YY=nil
429+local l1 =
430+local function g
431+(x)
432+l1=debug.getinfo(x,"l").currentline + 2
433+collectgarbage("stop")
434+auxy()
435+collectgarbage("restart")
436+end
437+local _,stackmsg = xpcall(g,debug.traceback,1)
438+print("+")
439+local stack = {}
440+for line in string.gmatch(stackmsg,"[^
441+]*")
442+do
443+local curr = string.match(line,":(%d+):")
444+if curr then
445+table.insert(stack,tonumber(curr))
446+end
447+end
448+local i = 1
449+while stack[i] ~= l1 do
450+assert(stack[i] == l)
451+i=i + 1
452+assert(i > 15)
453+local res,msg = xpcall(error,error)
454+assert(not res and type(msg) == "string")
455+print("+")
456+local function f
457+(x)
458+if x == 0 then
459+error("a
460+")
461+else
462+local aux = ()
463+return f(x - 1)
464+end
465+local a,b = xpcall(aux,aux)
466+return a,b
467+end
468+end
469+f(3)
470+local function loop
471+(x,y,z)
472+return 1 + loop(x,y,z)
473+end
474+local res,msg = xpcall(loop,(m)
475+assert(string.find(m,"stack overflow"))
476+checkerr("error handling",loop)
477+assert(math.sin(0) == 0)
478+return 15
479+end)
480+assert(msg == 15)
481+local f = ()
482+for i = 999900, 1e6, 1
483+do
484+table.unpack({},1,i)
485+end
486+end
487+checkerr("too many results",f)
488+end
489+local t = {}
490+local res,msg = pcall(()
491+error(t)
492+end)
493+assert(not res and msg == t)
494+res,msg=pcall(()
495+error(nil)
496+end)
497+assert(not res and msg == nil)
498+local function f
499+()
500+error({["msg"] = "x"})
501+end
502+res,msg=xpcall(f,(r)
503+return {["msg"] = r.msg .. "y"}
504+end)
505+assert(msg.msg == "xy")
506+res,msg=pcall(assert,false,"X",t)
507+assert(not res and msg == "X")
508+res,msg=pcall(()
509+assert(false)
510+end)
511+local line = string.match(msg,"%w+%.lua:(%d+): assertion failed!$")
512+assert(tonumber(line) == debug.getinfo(1,"l").currentline - 2)
513+res,msg=pcall(assert,false,t)
514+assert(not res and msg == t)
515+res,msg=pcall(assert,nil,nil)
516+assert(not res and msg == nil)
517+res,msg=pcall(assert)
518+assert(not res and string.find(msg,"value expected"))
519+local a,b,c = xpcall(string.find,error,"alo","al")
520+assert(a and b == 1 and c == 2)
521+a,b,c=xpcall(string.find,(x)
522+return {}
523+end,true,"al")
524+assert(not a and type(b) == "table" and c == nil)
525+print("testing tokens in error messages")
526+checksyntax("syntax error","","error",1)
527+checksyntax("1.000","","1.000",1)
528+checksyntax("[[a]]","","[[a]]",1)
529+checksyntax("'aa'","","'aa'",1)
530+checksyntax("while << do end","","<<",1)
531+checksyntax("for >> do end","",">>",1)
532+checksyntax("aa = 1","","<\1>",1)
533+checksyntax("�a = 1","","<\255>",1)
534+doit("I = load("a=9+"); aaa=3")
535+assert(_G.aaa == 3 and not _G.I)
536+_G.I,_G.aaa=nil
537+print("+")
538+local lim = 1e3
539+if _soft then
540+lim=100
541+end
542+for i = 1, lim
543+do
544+doit("a = ")
545+doit("a = 4+nil")
546+end
547+local function testrep
548+(init,rep,close,repc,finalresult)
549+local s = init .. string.rep(rep,100) .. close .. string.rep(repc,100)
550+local res,msg = load(s)
551+assert(res)
552+if (finalresult) then
553+assert(res() == finalresult)
554+end
555+s=init .. string.rep(rep,500)
556+local res,msg = load(s)
557+assert(not res and (string.find(msg,"too many") or string.find(msg,"overflow")))
558+end
559+testrep("local a; a",",a","= 1",",1")
560+testrep("local a; a=","{","0","}")
561+testrep("return ","(","2",")",2)
562+testrep("local function a (x) return x end; return ","a(","2.2",")",2.2)
563+testrep("","do ",""," end")
564+testrep("","while a do ",""," end")
565+testrep("local a; ","if a then else ",""," end")
566+testrep("","function foo () ",""," end")
567+testrep("local a = ''; return ","a..","'a'","","a")
568+testrep("local a = 1; return ","a^","a","",1)
569+checkmessage("a = f(x" .. string.rep(",x",260) .. ")","too many registers")
570+local lim = 127
571+local s = "local function fooA ()
572+ local "
573+for j = 1, lim
574+do
575+s=s .. "a" .. j .. ", "
576+end
577+s=s .. "b,c
578+"
579+s=s .. "local function fooB ()
580+ local "
581+for j = 1, lim
582+do
583+s=s .. "b" .. j .. ", "
584+end
585+s=s .. "b
586+"
587+s=s .. "function fooC () return b+c"
588+local c = 1 + 2
589+for j = 1, lim
590+do
591+s=s .. "+a" .. j .. "+b" .. j
592+c=c + 2
593+end
594+s=s .. "
595+end end end"
596+local a,b = load(s)
597+assert(c > 255 and string.find(b,"too many upvalues") and string.find(b,"line 5"))
598+s="
599+function foo ()
600+ local "
601+for j = 1, 300
602+do
603+s=s .. "a" .. j .. ", "
604+end
605+s=s .. "b
606+"
607+local a,b = load(s)
608+assert(string.find(b,"line 2") and string.find(b,"too many local variables"))
609+mt.__index=oldmm
610+print("OK")
zod/luau/res/lua/cycled/events.luanew file+602
@@ -0,0 +1,602 @@
1+print("testing metatables")
2+local debug = require("debug")
3+X=20
4+;
5+B=30
6+_ENV=setmetatable({},{["__index"] = _G})
7+collectgarbage()
8+X=X + 10
9+assert(X == 30 and _G.X == 20)
10+B=false
11+assert(B == false)
12+_ENV["B"]=undef
13+assert(B == 30)
14+assert(getmetatable({}) == nil)
15+assert(getmetatable(4) == nil)
16+assert(getmetatable(nil) == nil)
17+a={["name"] = "NAME"}
18+;
19+setmetatable(a,{["__metatable"] = "xuxu",["__tostring"] = (x)
20+return x.name
21+end})
22+assert(getmetatable(a) == "xuxu")
23+assert(tostring(a) == "NAME")
24+assert(pcall(setmetatable,a,{}) == false)
25+a.name="gororoba"
26+assert(tostring(a) == "gororoba")
27+local a,t = {10,20,30,["x"] = "10",["y"] = "20"},{}
28+assert(setmetatable(a,t) == a)
29+assert(getmetatable(a) == t)
30+assert(setmetatable(a,nil) == a)
31+assert(getmetatable(a) == nil)
32+assert(setmetatable(a,t) == a)
33+function f(t,i,e)
34+assert(not e)
35+local p = rawget(t,"parent")
36+return (p and p[i] + 3),"dummy return"
37+end
38+t.__index=f
39+a.parent={["z"] = 25,["x"] = 12,[4] = 24}
40+assert(a[1] == 10 and a.z == 28 and a[4] == 27 and a.x == "10")
41+collectgarbage()
42+a=setmetatable({},t)
43+function f(t,i,v)
44+rawset(t,i,v - 3)
45+end
46+setmetatable(t,t)
47+t.__newindex=f
48+a[1]=30
49+;
50+a.x="101"
51+;
52+a[5]=200
53+assert(a[1] == 27 and a.x == 98 and a[5] == 197)
54+local mt = {}
55+mt.__newindex=mt
56+local t = setmetatable({},mt)
57+t[1]=10
58+assert(mt[1] == 10)
59+local c = {}
60+a=setmetatable({},t)
61+t.__newindex=c
62+t.__index=c
63+a[1]=10
64+;
65+a[2]=20
66+;
67+a[3]=90
68+;
69+for i = 4, 20
70+do
71+a[i]=i * 10
72+end
73+assert(a[1] == 10 and a[2] == 20 and a[3] == 90)
74+for i = 4, 20
75+do
76+assert(a[i] == i * 10)
77+end
78+assert(next(a) == nil)
79+local a =
80+;
81+a=setmetatable({},{["__index"] = setmetatable({},{["__index"] = setmetatable({},{["__index"] = (_,n)
82+return a[n - 3] + 4,"lixo"
83+end})})})
84+a[0]=20
85+for i = 0, 10
86+do
87+assert(a[i * 3] == 20 + i * 4)
88+end
89+local foi =
90+local a = {}
91+for i = 1, 10
92+do
93+a[i]=0
94+;
95+a["a" .. i]=0
96+;
97+end
98+setmetatable(a,{["__newindex"] = (t,k,v)
99+foi=true
100+;
101+rawset(t,k,v)
102+end})
103+foi=false
104+;
105+a[1]=0
106+;
107+assert(not foi)
108+foi=false
109+;
110+a["a1"]=0
111+;
112+assert(not foi)
113+foi=false
114+;
115+a["a11"]=0
116+;
117+assert(foi)
118+foi=false
119+;
120+a[11]=0
121+;
122+assert(foi)
123+foi=false
124+;
125+a[1]=undef
126+;
127+assert(not foi)
128+a[1]=undef
129+foi=false
130+;
131+a[1]=nil
132+;
133+assert(foi)
134+setmetatable(t,nil)
135+function f(t, ...)
136+return t,{...}
137+end
138+t.__call=f
139+local x,y = a(table.unpack({"a",1}))
140+assert(x == a and y[1] == "a" and y[2] == 1 and y[3] == undef)
141+x,y=a()
142+assert(x == a and y[1] == undef)
143+local b = setmetatable({},t)
144+setmetatable(b,t)
145+function f(op)
146+return (...)
147+cap={[0] = op,...}
148+;
149+return (...)
150+end
151+end
152+t.__add=f("add")
153+t.__sub=f("sub")
154+t.__mul=f("mul")
155+t.__div=f("div")
156+t.__idiv=f("idiv")
157+t.__mod=f("mod")
158+t.__unm=f("unm")
159+t.__pow=f("pow")
160+t.__len=f("len")
161+t.__band=f("band")
162+t.__bor=f("bor")
163+t.__bxor=f("bxor")
164+t.__shl=f("shl")
165+t.__shr=f("shr")
166+t.__bnot=f("bnot")
167+t.__lt=f("lt")
168+t.__le=f("le")
169+local function checkcap
170+(t)
171+assert(# cap + 1 == # t)
172+for i = 1, # t
173+do
174+assert(cap[i - 1] == t[i])
175+assert(math.type(cap[i - 1]) == math.type(t[i]))
176+end
177+end
178+assert(b + 5 == b)
179+;
180+checkcap({"add",b,5})
181+assert(5.2 + b == 5.2)
182+;
183+checkcap({"add",5.2,b})
184+assert(b + "5" == b)
185+;
186+checkcap({"add",b,"5"})
187+assert(5 + b == 5)
188+;
189+checkcap({"add",5,b})
190+assert("5" + b == "5")
191+;
192+checkcap({"add","5",b})
193+b=b - 3
194+;
195+assert(getmetatable(b) == t)
196+;
197+checkcap({"sub",b,3})
198+assert(5 - a == 5)
199+;
200+checkcap({"sub",5,a})
201+assert("5" - a == "5")
202+;
203+checkcap({"sub","5",a})
204+assert(a * a == a)
205+;
206+checkcap({"mul",a,a})
207+assert(a / 0 == a)
208+;
209+checkcap({"div",a,0})
210+assert(a / 0 == a)
211+;
212+checkcap({"div",a,0})
213+assert(a % 2 == a)
214+;
215+checkcap({"mod",a,2})
216+assert(a // (1 / 0) == a)
217+;
218+checkcap({"idiv",a,1 / 0})
219+;
220+(()
221+assert(a & "hi" == a)
222+end)()
223+;
224+checkcap({"band",a,"hi"})
225+;
226+(()
227+assert(10 & a == 10)
228+end)()
229+;
230+checkcap({"band",10,a})
231+;
232+(()
233+assert(a | 10 == a)
234+end)()
235+;
236+checkcap({"bor",a,10})
237+assert(a | "hi" == a)
238+;
239+checkcap({"bor",a,"hi"})
240+assert("hi" ~ a == "hi")
241+;
242+checkcap({"bxor","hi",a})
243+;
244+(()
245+assert(10 ~ a == 10)
246+end)()
247+;
248+checkcap({"bxor",10,a})
249+assert(- a == a)
250+;
251+checkcap({"unm",a,a})
252+assert(a ^ 4 == a)
253+;
254+checkcap({"pow",a,4})
255+assert(a ^ "4" == a)
256+;
257+checkcap({"pow",a,"4"})
258+assert(4 ^ a == 4)
259+;
260+checkcap({"pow",4,a})
261+assert("4" ^ a == "4")
262+;
263+checkcap({"pow","4",a})
264+assert(# a == a)
265+;
266+checkcap({"len",a,a})
267+assert(~ a == a)
268+;
269+checkcap({"bnot",a,a})
270+assert(a << 3 == a)
271+;
272+checkcap({"shl",a,3})
273+assert(1.5 >> a == 1.5)
274+;
275+checkcap({"shr",1.5,a})
276+assert(5 > a)
277+;
278+checkcap({"lt",a,5})
279+assert(a >= 10)
280+;
281+checkcap({"le",10,a})
282+assert(a <= - 10)
283+;
284+checkcap({"le",a,- 10})
285+assert(a < - 10)
286+;
287+checkcap({"lt",a,- 10})
288+t=setmetatable({1,2,3},{["__len"] = ()
289+return 10
290+end})
291+assert(# t == 10 and rawlen(t) == 3)
292+assert(rawlen("abc") == 3)
293+assert(not pcall(rawlen,io.stdin))
294+assert(not pcall(rawlen,34))
295+assert(not pcall(rawlen))
296+assert(rawlen(string.rep("a",1e3)) == 1e3)
297+t={}
298+t.__lt=(a,b,c)
299+collectgarbage()
300+assert(c == nil)
301+if type(a) == "table" then
302+a=a.x
303+end
304+if type(b) == "table" then
305+b=b.x
306+end
307+return a < b,"dummy"
308+end
309+t.__le=(a,b,c)
310+assert(c == nil)
311+if type(a) == "table" then
312+a=a.x
313+end
314+if type(b) == "table" then
315+b=b.x
316+end
317+return a <= b,"dummy"
318+end
319+t.__eq=(a,b,c)
320+assert(c == nil)
321+if type(a) == "table" then
322+a=a.x
323+end
324+if type(b) == "table" then
325+b=b.x
326+end
327+return a == b,"dummy"
328+end
329+function Op(x)
330+return setmetatable({["x"] = x},t)
331+end
332+local function test
333+(a,b,c)
334+assert(not (Op(1) < Op(1)) and (Op(1) < Op(2)) and not (Op(2) < Op(1)))
335+assert(not (1 < Op(1)) and (Op(1) < 2) and not (2 < Op(1)))
336+assert(not (Op("a") < Op("a")) and (Op("a") < Op("b")) and not (Op("b") < Op("a")))
337+assert(not ("a" < Op("a")) and (Op("a") < "b") and not (Op("b") < Op("a")))
338+assert((Op(1) <= Op(1)) and (Op(1) <= Op(2)) and not (Op(2) <= Op(1)))
339+assert((Op("a") <= Op("a")) and (Op("a") <= Op("b")) and not (Op("b") <= Op("a")))
340+assert(not (Op(1) > Op(1)) and not (Op(1) > Op(2)) and (Op(2) > Op(1)))
341+assert(not (Op("a") > Op("a")) and not (Op("a") > Op("b")) and (Op("b") > Op("a")))
342+assert((Op(1) >= Op(1)) and not (Op(1) >= Op(2)) and (Op(2) >= Op(1)))
343+assert((1 >= Op(1)) and not (1 >= Op(2)) and (Op(2) >= 1))
344+assert((Op("a") >= Op("a")) and not (Op("a") >= Op("b")) and (Op("b") >= Op("a")))
345+assert(("a" >= Op("a")) and not (Op("a") >= "b") and (Op("b") >= Op("a")))
346+assert(Op(1) == Op(1) and Op(1) ~= Op(2))
347+assert(Op("a") == Op("a") and Op("a") ~= Op("b"))
348+assert(a == a and a ~= b)
349+assert(Op(3) == c)
350+end
351+test(Op(1),Op(2),Op(3))
352+local function rawSet
353+(x)
354+local y = {}
355+for _,k in pairs(x)
356+do
357+y[k]=1
358+end
359+return y
360+end
361+local function Set
362+(x)
363+return setmetatable(rawSet(x),t)
364+end
365+t.__lt=(a,b)
366+for k in pairs(a)
367+do
368+if not b[k] then
369+return false
370+end
371+b[k]=undef
372+end
373+return next(b) ~= nil
374+end
375+t.__le=(a,b)
376+for k in pairs(a)
377+do
378+if not b[k] then
379+return false
380+end
381+end
382+return true
383+end
384+assert(Set({1,2,3}) < Set({1,2,3,4}))
385+assert(not (Set({1,2,3,4}) < Set({1,2,3,4})))
386+assert((Set({1,2,3,4}) <= Set({1,2,3,4})))
387+assert((Set({1,2,3,4}) >= Set({1,2,3,4})))
388+assert(not (Set({1,3}) <= Set({3,5})))
389+assert(not (Set({1,3}) <= Set({3,5})))
390+assert(not (Set({1,3}) >= Set({3,5})))
391+t.__eq=(a,b)
392+for k in pairs(a)
393+do
394+if not b[k] then
395+return false
396+end
397+b[k]=undef
398+end
399+return next(b) == nil
400+end
401+local s = Set({1,3,5})
402+assert(s == Set({3,5,1}))
403+assert(not rawequal(s,Set({3,5,1})))
404+assert(rawequal(s,s))
405+assert(Set({1,3,5,1}) == rawSet({3,5,1}))
406+assert(rawSet({1,3,5,1}) == Set({3,5,1}))
407+assert(Set({1,3,5}) ~= Set({3,5,1,6}))
408+t[Set({1,3,5})]=1
409+assert(t[Set({1,3,5})] == undef)
410+local mt = {["__eq"] = true}
411+local a = setmetatable({10},mt)
412+local b = setmetatable({10},mt)
413+mt.__eq=nil
414+assert(a ~= b)
415+mt.__eq=(x,y)
416+return x[1] == y[1]
417+end
418+assert(a == b)
419+if not T then
420+(Message or print)("
421+ >>> testC not active: skipping tests for userdata <<<
422+")
423+else
424+local u1 = T.newuserdata(0,1)
425+local u2 = T.newuserdata(0,1)
426+local u3 = T.newuserdata(0,1)
427+assert(u1 ~= u2 and u1 ~= u3)
428+debug.setuservalue(u1,1)
429+;
430+debug.setuservalue(u2,2)
431+;
432+debug.setuservalue(u3,1)
433+;
434+debug.setmetatable(u1,{["__eq"] = (a,b)
435+return debug.getuservalue(a) == debug.getuservalue(b)
436+end})
437+debug.setmetatable(u2,{["__eq"] = (a,b)
438+return true
439+end})
440+assert(u1 == u3 and u3 == u1 and u1 ~= u2)
441+assert(u2 == u1 and u2 == u3 and u3 == u2)
442+assert(u2 ~= {})
443+assert(rawequal(u1,u1) and not rawequal(u1,u3))
444+local mirror = {}
445+debug.setmetatable(u3,{["__index"] = mirror,["__newindex"] = mirror})
446+for i = 1, 10
447+do
448+u3[i]=i
449+end
450+for i = 1, 10
451+do
452+assert(u3[i] == i)
453+end
454+end
455+t.__concat=(a,b,c)
456+assert(c == nil)
457+if type(a) == "table" then
458+a=a.val
459+end
460+if type(b) == "table" then
461+b=b.val
462+end
463+if A then
464+return a .. b
465+else
466+return setmetatable({["val"] = a .. b},t)
467+end
468+end
469+c={["val"] = "c"}
470+;
471+setmetatable(c,t)
472+d={["val"] = "d"}
473+;
474+setmetatable(d,t)
475+A=true
476+assert(c .. d == "cd")
477+assert(0 .. "a" .. "b" .. c .. d .. "e" .. "f" .. (5 + 3) .. "g" == "0abcdef8g")
478+A=false
479+assert((c .. d .. c .. d).val == "cdcd")
480+x=c .. d
481+assert(getmetatable(x) == t and x.val == "cd")
482+x=0 .. "a" .. "b" .. c .. d .. "e" .. "f" .. "g"
483+assert(x.val == "0abcdefg")
484+c={}
485+local x =
486+setmetatable(c,{["__concat"] = (a,b)
487+assert(type(a) == "number" and b == c or type(b) == "number" and a == c)
488+return c
489+end})
490+assert(c .. 5 == c and 5 .. c == c)
491+assert(4 .. c .. 5 == c and 4 .. 5 .. 6 .. 7 .. c == c)
492+local t1,t2,c,d =
493+t1={}
494+;
495+c={}
496+;
497+setmetatable(c,t1)
498+d={}
499+t1.__eq=()
500+return true
501+end
502+t1.__lt=()
503+return true
504+end
505+t1.__le=()
506+return false
507+end
508+setmetatable(d,t1)
509+assert(c == d and c < d and not (d <= c))
510+t2={}
511+t2.__eq=t1.__eq
512+t2.__lt=t1.__lt
513+setmetatable(d,t2)
514+assert(c == d and c < d and not (d <= c))
515+local i =
516+local tt = {["__call"] = (t, ...)
517+i=i + 1
518+if t.f then
519+return t.f(...)
520+else
521+return {...}
522+end
523+end}
524+local a = setmetatable({},tt)
525+local b = setmetatable({["f"] = a},tt)
526+local c = setmetatable({["f"] = b},tt)
527+i=0
528+x=c(3,4,5)
529+assert(i == 3 and x[1] == 3 and x[3] == 5)
530+assert(_G.X == 20)
531+_G.X,_G.B=nil
532+print("+")
533+local _g = _G
534+_ENV=setmetatable({},{["__index"] = (_,k)
535+return _g[k]
536+end})
537+a={}
538+rawset(a,"x",1,2,3)
539+assert(a.x == 1 and rawget(a,"x",3) == 1)
540+print("+")
541+mt={["__index"] = (a,b)
542+return a + b
543+end,["__len"] = (x)
544+return math.floor(x)
545+end}
546+debug.setmetatable(10,mt)
547+assert(getmetatable(- 2) == mt)
548+assert((10)[3] == 13)
549+assert((10)["3"] == 13)
550+assert(# 3.45 == 3)
551+debug.setmetatable(23,nil)
552+assert(getmetatable(- 2) == nil)
553+debug.setmetatable(true,mt)
554+assert(getmetatable(false) == mt)
555+mt.__index=(a,b)
556+return a or b
557+end
558+assert((true)[false] == true)
559+assert((false)[false] == false)
560+debug.setmetatable(false,nil)
561+assert(getmetatable(true) == nil)
562+debug.setmetatable(nil,mt)
563+assert(getmetatable(nil) == mt)
564+mt.__add=(a,b)
565+return (a or 1) + (b or 2)
566+end
567+assert(10 + nil == 12)
568+assert(nil + 23 == 24)
569+assert(nil + nil == 3)
570+debug.setmetatable(nil,nil)
571+assert(getmetatable(nil) == nil)
572+debug.setmetatable(nil,{})
573+a={}
574+;
575+setmetatable(a,a)
576+;
577+a.__index=a
578+;
579+a.__newindex=a
580+assert(not pcall((a,b)
581+return a[b]
582+end,a,10))
583+assert(not pcall((a,b,c)
584+a[b]=c
585+end,a,10,true))
586+T,K,V=nil
587+grandparent={}
588+grandparent.__newindex=(t,k,v)
589+T=t
590+;
591+K=k
592+;
593+V=v
594+end
595+parent={}
596+parent.__newindex=parent
597+setmetatable(parent,grandparent)
598+child=setmetatable({},parent)
599+child.foo=10
600+assert(T == parent and K == "foo" and V == 10)
601+print("OK")
602+return 12
zod/luau/res/lua/cycled/files.luanew file+886
@@ -0,0 +1,886 @@
1+local debug = require("debug")
2+local maxint = math.maxinteger
3+assert(type(os.getenv("PATH")) == "string")
4+assert(io.input(io.stdin) == io.stdin)
5+assert(not pcall(io.input,"non-existent-file"))
6+assert(io.output(io.stdout) == io.stdout)
7+local function testerr
8+(msg,f, ...)
9+local stat,err = pcall(f,...)
10+return (not stat and string.find(err,msg,1,true))
11+end
12+local function checkerr
13+(msg,f, ...)
14+assert(testerr(msg,f,...))
15+end
16+assert(not io.close(io.stdin) and not io.stdout:close() and not io.stderr:close())
17+checkerr("got no value",io.stdin.close)
18+assert(type(io.input()) == "userdata" and io.type(io.output()) == "file")
19+assert(type(io.stdin) == "userdata" and io.type(io.stderr) == "file")
20+assert(not io.type(8))
21+local a = {}
22+;
23+setmetatable(a,{})
24+assert(not io.type(a))
25+assert(getmetatable(io.input()).__name == "FILE*")
26+local a,b,c = io.open("xuxu_nao_existe")
27+assert(not a and type(b) == "string" and type(c) == "number")
28+a,b,c=io.open("/a/b/c/d","w")
29+assert(not a and type(b) == "string" and type(c) == "number")
30+local file = os.tmpname()
31+local f,msg = io.open(file,"w")
32+if not f then
33+(Message or print)("'os.tmpname' file cannot be open; skipping file tests")
34+else
35+f:close()
36+print("testing i/o")
37+local otherfile = os.tmpname()
38+checkerr("invalid mode",io.open,file,"rw")
39+checkerr("invalid mode",io.open,file,"rb+")
40+checkerr("invalid mode",io.open,file,"r+bk")
41+checkerr("invalid mode",io.open,file,"")
42+checkerr("invalid mode",io.open,file,"+")
43+checkerr("invalid mode",io.open,file,"b")
44+assert(io.open(file,"r+b")):close()
45+assert(io.open(file,"r+")):close()
46+assert(io.open(file,"rb")):close()
47+assert(os.setlocale("C","all"))
48+io.input(io.stdin)
49+;
50+io.output(io.stdout)
51+;
52+os.remove(file)
53+assert(not loadfile(file))
54+checkerr("",dofile,file)
55+assert(not io.open(file))
56+io.output(file)
57+assert(io.output() ~= io.stdout)
58+if not _port then
59+local status,msg,code = io.stdin:seek("set",1e3)
60+assert(not status and type(msg) == "string" and type(code) == "number")
61+end
62+assert(io.output():seek() == 0)
63+assert(io.write("alo alo"):seek() == string.len("alo alo"))
64+assert(io.output():seek("cur",- 3) == string.len("alo alo") - 3)
65+assert(io.write("joao"))
66+assert(io.output():seek("end") == string.len("alo joao"))
67+assert(io.output():seek("set") == 0)
68+assert(io.write(""alo"","{a}
69+","second line
70+","third line
71+"))
72+assert(io.write("Xfourth_line"))
73+io.output(io.stdout)
74+collectgarbage()
75+assert(io.input() == io.stdin and rawequal(io.output(),io.stdout))
76+print("+")
77+collectgarbage()
78+for i = 1, 120
79+do
80+for i = 1, 5
81+do
82+io.input(file)
83+assert(io.open(file,"r"))
84+io.lines(file)
85+end
86+collectgarbage()
87+end
88+io.input():close()
89+io.close()
90+assert(os.rename(file,otherfile))
91+assert(not os.rename(file,otherfile))
92+io.output(io.open(otherfile,"ab"))
93+assert(io.write("
94+
95+ ",3450,"
96+"))
97+;
98+io.close()
99+local F = nil
100+local f <close> = assert(io.open(file,"w"))
101+F=f
102+assert(tostring(F) == "file (closed)")
103+assert(os.remove(file))
104+local f <close> = assert(io.open(file,"w"))
105+f:write(maxint,"
106+")
107+f:write(string.format("0X%x
108+",maxint))
109+f:write("0xABCp-3","
110+")
111+f:write(0,"
112+")
113+f:write(- maxint,"
114+")
115+f:write(string.format("0x%X
116+",- maxint))
117+f:write("-0xABCp-3","
118+")
119+assert(f:close())
120+local f <close> = assert(io.open(file,"r"))
121+assert(f:read("n") == maxint)
122+assert(f:read("n") == maxint)
123+assert(f:read("n") == 343.5)
124+assert(f:read("n") == 0)
125+assert(f:read("*n") == - maxint)
126+assert(f:read("n") == - maxint)
127+assert(f:read("*n") == - 343.5)
128+assert(os.remove(file))
129+local f <close> = assert(io.open(file,"w"))
130+f:write("a line
131+another line
132+1234
133+3.45
134+one
135+two
136+three
137+")
138+local l1,l2,l3,l4,n1,n2,c,dummy =
139+assert(f:close())
140+local f <close> = assert(io.open(file,"r"))
141+l1,l2,n1,n2,dummy=f:read("l","L","n","n")
142+assert(l1 == "a line" and l2 == "another line
143+" and n1 == 1234 and n2 == 3.45 and dummy == nil)
144+assert(f:close())
145+local f <close> = assert(io.open(file,"r"))
146+l1,l2,n1,n2,c,l3,l4,dummy=f:read(7,"l","n","n",1,"l","l")
147+assert(l1 == "a line
148+" and l2 == "another line" and c == "
149+" and n1 == 1234 and n2 == 3.45 and l3 == "one" and l4 == "two" and dummy == nil)
150+assert(f:close())
151+local f <close> = assert(io.open(file,"r"))
152+l1,n1,n2,dummy=f:read("l","n","n","l")
153+assert(l1 == "a line" and not n1)
154+assert(os.remove(file))
155+f=assert(io.open(file,"w"))
156+f:write("local x, z = coroutine.yield(10)
157+local y = coroutine.yield(20)
158+return x + y * z
159+")
160+assert(f:close())
161+f=coroutine.wrap(dofile)
162+assert(f(file) == 10)
163+assert(f(100,101) == 20)
164+assert(f(200) == 100 + 200 * 101)
165+assert(os.remove(file))
166+f=assert(io.open(file,"w"))
167+f:write("-12.3- -0xffff+ .3|5.E-3X +234e+13E 0xDEADBEEFDEADBEEFx
168+0x1.13Ap+3e
169+")
170+f:write("1234")
171+;
172+for i = 1, 1e3
173+do
174+f:write("0")
175+end
176+;
177+f:write("
178+")
179+f:write(".e+ 0.e; --; 0xX;
180+")
181+assert(f:close())
182+f=assert(io.open(file,"r"))
183+assert(f:read("n") == - 12.3)
184+;
185+assert(f:read(1) == "-")
186+assert(f:read("n") == - 65535)
187+;
188+assert(f:read(2) == "+ ")
189+assert(f:read("n") == 0.3)
190+;
191+assert(f:read(1) == "|")
192+assert(f:read("n") == 5e-3)
193+;
194+assert(f:read(1) == "X")
195+assert(f:read("n") == 2.34e15)
196+;
197+assert(f:read(1) == "E")
198+assert(f:read("n") == 16045690984833335023)
199+;
200+assert(f:read(2) == "x
201+")
202+assert(f:read("n") == 8.61328125)
203+;
204+assert(f:read(1) == "e")
205+assert(not f:read("n"))
206+local s = f:read("L")
207+assert(string.find(s,"^00*
208+$"))
209+assert(not f:read("n"))
210+;
211+assert(f:read(2) == "e+")
212+assert(not f:read("n"))
213+;
214+assert(f:read(1) == ";")
215+assert(not f:read("n"))
216+;
217+assert(f:read(2) == "-;")
218+assert(not f:read("n"))
219+;
220+assert(f:read(1) == "X")
221+assert(not f:read("n"))
222+;
223+assert(f:read(1) == ";")
224+assert(not f:read("n"))
225+;
226+assert(not f:read(0))
227+assert(f:close())
228+assert(os.remove(file))
229+assert(not pcall(io.lines,"non-existent-file"))
230+assert(os.rename(otherfile,file))
231+io.output(otherfile)
232+local n = 0
233+local f = io.lines(file)
234+while f() do
235+n=n + 1
236+;
237+assert(n == 6)
238+checkerr("file is already closed",f)
239+checkerr("file is already closed",f)
240+n=0
241+for l in io.lines(file)
242+do
243+io.write(l,"
244+")
245+;
246+n=n + 1
247+end
248+io.close()
249+assert(n == 6)
250+local f = assert(io.open(otherfile))
251+assert(io.type(f) == "file")
252+io.output(file)
253+assert(not io.output():read())
254+n=0
255+for l in f:lines()
256+do
257+io.write(l,"
258+")
259+;
260+n=n + 1
261+end
262+assert(tostring(f):sub(1,5) == "file ")
263+assert(f:close())
264+;
265+io.close()
266+assert(n == 6)
267+checkerr("closed file",io.close,f)
268+assert(tostring(f) == "file (closed)")
269+assert(io.type(f) == "closed file")
270+io.input(file)
271+f=io.open(otherfile):lines()
272+n=0
273+for l in io.lines()
274+do
275+assert(l == f())
276+;
277+n=n + 1
278+end
279+f=nil
280+;
281+collectgarbage()
282+assert(n == 6)
283+assert(os.remove(otherfile))
284+io.output(otherfile)
285+io.write(string.rep("a",300),"
286+")
287+io.close()
288+local t = {}
289+;
290+for i = 1, 250
291+do
292+t[i]=1
293+end
294+t={io.lines(otherfile,table.unpack(t))()}
295+assert(# t == 250 and t[1] == "a" and t[# t] == "a")
296+t[# t + 1]=1
297+checkerr("too many arguments",io.lines,otherfile,table.unpack(t))
298+collectgarbage()
299+assert(os.remove(otherfile))
300+io.input(file)
301+local a,b,c = io.input():write("xuxu")
302+assert(not a and type(b) == "string" and type(c) == "number")
303+checkerr("invalid format",io.read,"x")
304+assert(io.read(0) == "")
305+assert(io.read(5,"l") == ""alo"")
306+assert(io.read(0) == "")
307+assert(io.read() == "second line")
308+local x = io.input():seek()
309+assert(io.read() == "third line ")
310+assert(io.input():seek("set",x))
311+assert(io.read("L") == "third line
312+")
313+assert(io.read(1) == "X")
314+assert(io.read(string.len("fourth_line")) == "fourth_line")
315+assert(io.input():seek("cur",- string.len("fourth_line")))
316+assert(io.read() == "fourth_line")
317+assert(io.read() == "")
318+assert(io.read("n") == 3450)
319+assert(io.read(1) == "
320+")
321+assert(not io.read(0))
322+assert(not io.read(1))
323+assert(not io.read(3e4))
324+assert(({io.read(1)})[2] == undef)
325+assert(not io.read())
326+assert(({io.read()})[2] == undef)
327+assert(not io.read("n"))
328+assert(({io.read("n")})[2] == undef)
329+assert(io.read("a") == "")
330+assert(io.read("a") == "")
331+collectgarbage()
332+print("+")
333+io.close(io.input())
334+checkerr(" input file is closed",io.read)
335+assert(os.remove(file))
336+local t = "0123456789"
337+for i = 1, 10
338+do
339+t=t .. t
340+;
341+end
342+assert(string.len(t) == 10 * 2 ^ 10)
343+io.output(file)
344+io.write("alo"):write("
345+")
346+io.close()
347+checkerr(" output file is closed",io.write)
348+local f = io.open(file,"a+b")
349+io.output(f)
350+collectgarbage()
351+assert(io.write(" " .. t .. " "))
352+assert(io.write(";","end of file
353+"))
354+f:flush()
355+;
356+io.flush()
357+f:close()
358+print("+")
359+io.input(file)
360+assert(io.read() == "alo")
361+assert(io.read(1) == " ")
362+assert(io.read(string.len(t)) == t)
363+assert(io.read(1) == " ")
364+assert(io.read(0))
365+assert(io.read("a") == ";end of file
366+")
367+assert(not io.read(0))
368+assert(io.close(io.input()))
369+local function ismsg
370+(m)
371+return (type(m) == "string" and not tonumber(m))
372+end
373+local f = io.open(file,"w")
374+local r,m,c = f:read()
375+assert(not r and ismsg(m) and type(c) == "number")
376+assert(f:close())
377+f=io.open(file,"r")
378+r,m,c=f:write("whatever")
379+assert(not r and ismsg(m) and type(c) == "number")
380+assert(f:close())
381+f=io.open(file,"w")
382+r,m=pcall(f:lines())
383+assert(r == false and ismsg(m))
384+assert(f:close())
385+assert(os.remove(file))
386+io.output(file)
387+;
388+io.write("
389+
390+line
391+other"):close()
392+io.input(file)
393+assert(io.read("L") == "
394+")
395+assert(io.read("L") == "
396+")
397+assert(io.read("L") == "line
398+")
399+assert(io.read("L") == "other")
400+assert(not io.read("L"))
401+io.input():close()
402+local f = assert(io.open(file))
403+local s = ""
404+for l in f:lines("L")
405+do
406+s=s .. l
407+end
408+assert(s == "
409+
410+line
411+other")
412+f:close()
413+io.input(file)
414+s=""
415+for l in io.lines(nil,"L")
416+do
417+s=s .. l
418+end
419+assert(s == "
420+
421+line
422+other")
423+io.input():close()
424+s=""
425+for l in io.lines(file,"L")
426+do
427+s=s .. l
428+end
429+assert(s == "
430+
431+line
432+other")
433+s=""
434+for l in io.lines(file,"l")
435+do
436+s=s .. l
437+end
438+assert(s == "lineother")
439+io.output(file)
440+;
441+io.write("a = 10 + 34
442+a = 2*a
443+a = -a
444+"):close()
445+local t = {}
446+assert(load(io.lines(file,"L"),nil,nil,t))()
447+assert(t.a == - ((10 + 34) * 2))
448+local function gettoclose
449+(lv)
450+lv=lv + 1
451+local stvar = 0
452+for i = 1, 1e3
453+do
454+local n,v = debug.getlocal(lv,i)
455+if n == "(for state)" then
456+stvar=stvar + 1
457+if stvar == 4 then
458+return v
459+end
460+end
461+end
462+end
463+local f =
464+for l in io.lines(file)
465+do
466+f=gettoclose(1)
467+assert(io.type(f) == "file")
468+break
469+end
470+assert(io.type(f) == "closed file")
471+f=nil
472+local function foo
473+(name)
474+for l in io.lines(name)
475+do
476+f=gettoclose(1)
477+assert(io.type(f) == "file")
478+error(f)
479+end
480+end
481+local st,msg = pcall(foo,file)
482+assert(st == false and io.type(msg) == "closed file")
483+io.output(file)
484+;
485+io.write("0123456789
486+"):close()
487+for a,b in io.lines(file,1,1)
488+do
489+if a == "
490+" then
491+assert(not b)
492+else
493+assert(tonumber(a) == tonumber(b) - 1)
494+end
495+end
496+for a,b,c in io.lines(file,1,2,"a")
497+do
498+assert(a == "0" and b == "12" and c == "3456789
499+")
500+end
501+for a,b,c in io.lines(file,"a",0,1)
502+do
503+if a == "" then
504+break
505+end
506+assert(a == "0123456789
507+" and not b and not c)
508+end
509+collectgarbage()
510+io.output(file)
511+;
512+io.write("00
513+10
514+20
515+30
516+40
517+"):close()
518+for a,b in io.lines(file,"n","n")
519+do
520+if a == 40 then
521+assert(not b)
522+else
523+assert(a == b - 10)
524+end
525+end
526+io.output(file)
527+;
528+io.write("local y
529+= X
530+X =
531+X *
532+2 +
533+X;
534+X =
535+X
536+- y;
537+"):close()
538+_G.X=1
539+assert(not load((io.lines(file))))
540+collectgarbage()
541+load((io.lines(file,"L")))()
542+assert(_G.X == 2)
543+load((io.lines(file,1)))()
544+assert(_G.X == 4)
545+load((io.lines(file,3)))()
546+assert(_G.X == 8)
547+_G.X=nil
548+print("+")
549+local x1 = "string
550+
551+\com ""''coisas [[estranhas]] ]]'"
552+io.output(file)
553+assert(io.write(string.format("X2 = %q
554+-- comment without ending EOS",x1)))
555+io.close()
556+assert(loadfile(file))()
557+assert(x1 == _G.X2)
558+_G.X2=nil
559+print("+")
560+assert(os.remove(file))
561+assert(not os.remove(file))
562+assert(not os.remove(otherfile))
563+local function testloadfile
564+(s,expres)
565+io.output(file)
566+if s then
567+io.write(s)
568+end
569+io.close()
570+local res = assert(loadfile(file))()
571+assert(os.remove(file))
572+assert(res == expres)
573+end
574+testloadfile(nil,nil)
575+testloadfile("# a non-ending comment",nil)
576+testloadfile("# some comment
577+return 234",234)
578+testloadfile("return 239",239)
579+testloadfile("",nil)
580+testloadfile("# a comment
581+return require'debug'.getinfo(1).currentline",2)
582+io.output(io.open(file,"wb"))
583+assert(io.write(string.dump(()
584+return 10,"alo�","hi"
585+end)))
586+io.close()
587+a,b,c=assert(loadfile(file))()
588+assert(a == 10 and b == "alo�" and c == "hi")
589+assert(os.remove(file))
590+io.output(io.open(file,"wb"))
591+assert(io.write(string.dump(()
592+return 1
593+end)))
594+io.close()
595+f=assert(loadfile(file,"b",{}))
596+assert(type(f) == "function" and f() == 1)
597+assert(os.remove(file))
598+io.output(io.open(file,"wb"))
599+assert(io.write("#this is a comment for a binary file
600+",string.dump(()
601+return 20,""
602+end)))
603+io.close()
604+a,b,c=assert(loadfile(file))()
605+assert(a == 20 and b == "" and c == nil)
606+assert(os.remove(file))
607+local f = io.open(file,"w")
608+f:write(" if (...) then a = 15; return b, c, d
609+ else return _ENV
610+ end
611+ ")
612+f:close()
613+local t = {["b"] = 12,["c"] = "xuxu",["d"] = print}
614+local f = assert(loadfile(file,"t",t))
615+local b,c,d = f(1)
616+assert(t.a == 15 and b == 12 and c == t.c and d == print)
617+assert(f() == t)
618+f=assert(loadfile(file,"t",nil))
619+assert(f() == nil)
620+f=assert(loadfile(file))
621+assert(f() == _G)
622+assert(os.remove(file))
623+io.open(file,"w"):write("return 10"):close()
624+local s,m = loadfile(file,"b")
625+assert(not s and string.find(m,"a text chunk"))
626+io.open(file,"w"):write(" return 10"):close()
627+local s,m = loadfile(file,"t")
628+assert(not s and string.find(m,"a binary chunk"))
629+assert(os.remove(file))
630+io.output(file)
631+assert(io.write("qualquer coisa
632+"))
633+assert(io.write("mais qualquer coisa"))
634+io.close()
635+assert(io.output(assert(io.open(otherfile,"wb"))):write("outra coisa�"):close())
636+local filehandle = assert(io.open(file,"r+"))
637+local otherfilehandle = assert(io.open(otherfile,"rb"))
638+assert(filehandle ~= otherfilehandle)
639+assert(type(filehandle) == "userdata")
640+assert(filehandle:read("l") == "qualquer coisa")
641+io.input(otherfilehandle)
642+assert(io.read(string.len("outra coisa")) == "outra coisa")
643+assert(filehandle:read("l") == "mais qualquer coisa")
644+filehandle:close()
645+;
646+assert(type(filehandle) == "userdata")
647+io.input(otherfilehandle)
648+assert(io.read(4) == "")
649+assert(io.read(3) == "")
650+assert(io.read(0) == "")
651+assert(io.read(1) == "�")
652+assert(io.read("a") == "")
653+assert(not io.read(0))
654+assert(otherfilehandle == io.input())
655+otherfilehandle:close()
656+assert(os.remove(file))
657+assert(os.remove(otherfile))
658+collectgarbage()
659+io.output(file):write(" 123.4 -56e-2 not a number
660+second line
661+third line
662+
663+and the rest of the file
664+"):close()
665+io.input(file)
666+local _,a,b,c,d,e,h,__ = io.read(1,"n","n","l","l","l","a",10)
667+assert(io.close(io.input()))
668+assert(_ == " " and not __)
669+assert(type(a) == "number" and a == 123.4 and b == - 0.56)
670+assert(d == "second line" and e == "third line")
671+assert(h == "
672+and the rest of the file
673+")
674+assert(os.remove(file))
675+collectgarbage()
676+local f = assert(io.open(file,"w"))
677+local fr = assert(io.open(file,"r"))
678+assert(f:setvbuf("full",2e3))
679+f:write("x")
680+assert(fr:read("all") == "")
681+f:close()
682+fr:seek("set")
683+assert(fr:read("all") == "x")
684+f=assert(io.open(file),"w")
685+assert(f:setvbuf("no"))
686+f:write("x")
687+fr:seek("set")
688+assert(fr:read("all") == "x")
689+f:close()
690+f=assert(io.open(file,"a"))
691+assert(f:setvbuf("line"))
692+f:write("x")
693+fr:seek("set",1)
694+assert(fr:read("all") == "")
695+f:write("a
696+"):seek("set",1)
697+assert(fr:read("all") == "xa
698+")
699+f:close()
700+;
701+fr:close()
702+assert(os.remove(file))
703+if not _soft then
704+print("testing large files (> BUFSIZ)")
705+io.output(file)
706+for i = 1, 5001
707+do
708+io.write("0123456789123")
709+end
710+io.write("
711+12346"):close()
712+io.input(file)
713+local x = io.read("a")
714+io.input():seek("set",0)
715+local y = io.read(30001) .. io.read(1005) .. io.read(0) .. io.read(1) .. io.read(100003)
716+assert(x == y and string.len(x) == 5001 * 13 + 6)
717+io.input():seek("set",0)
718+y=io.read()
719+assert(x == y .. "
720+" .. io.read())
721+assert(not io.read())
722+io.close(io.input())
723+assert(os.remove(file))
724+x=nil
725+;
726+y=nil
727+end
728+if not _port then
729+local progname =
730+local arg = arg or ARG
731+local i = 0
732+while arg[i] do
733+i=i - 1
734+progname=""" .. arg[i + 1] .. """
735+print("testing popen/pclose and execute")
736+checkerr("invalid mode",io.popen,"cat","")
737+checkerr("invalid mode",io.popen,"cat","r+")
738+checkerr("invalid mode",io.popen,"cat","rw")
739+local file = os.tmpname()
740+local f = assert(io.popen("cat - > " .. file,"w"))
741+f:write("a line")
742+assert(f:close())
743+local f = assert(io.popen("cat - < " .. file,"r"))
744+assert(f:read("a") == "a line")
745+assert(f:close())
746+assert(os.remove(file))
747+local tests = {{"ls > /dev/null","ok"},{"not-to-be-found-command","exit"},{"exit 3","exit",3},{"exit 129","exit",129},{"kill -s HUP $$","signal",1},{"kill -s KILL $$","signal",9},{"sh -c 'kill -s HUP $$'","exit"},{progname .. " -e " "","ok"},{progname .. " -e "os.exit(0, true)"","ok"},{progname .. " -e "os.exit(20, true)"","exit",20}}
748+print("
749+(some error messages are expected now)")
750+for _,v in ipairs(tests)
751+do
752+local x,y,z = io.popen(v[1]):close()
753+local x1,y1,z1 = os.execute(v[1])
754+assert(x == x1 and y == y1 and z == z1)
755+if v[2] == "ok" then
756+assert(x and y == "exit" and z == 0)
757+else
758+assert(not x and y == v[2])
759+assert((v[3] == nil and z > 0) or v[3] == z)
760+end
761+end
762+end
763+f=io.tmpfile()
764+assert(io.type(f) == "file")
765+f:write("alo")
766+f:seek("set")
767+assert(f:read("a") == "alo")
768+end
769+print("+")
770+print("testing date/time")
771+assert(os.date("") == "")
772+assert(os.date("!") == "")
773+assert(os.date("") == "")
774+assert(os.date("!") == "")
775+local x = string.rep("a",1e4)
776+assert(os.date(x) == x)
777+local t = os.time()
778+D=os.date("*t",t)
779+assert(os.date(string.rep("%d",1e3),t) == string.rep(os.date("%d",t),1e3))
780+assert(os.date(string.rep("%",200)) == string.rep("%",100))
781+local function checkDateTable
782+(t)
783+_G.D=os.date("*t",t)
784+assert(os.time(D) == t)
785+load(os.date("assert(D.year==%Y and D.month==%m and D.day==%d and
786+ D.hour==%H and D.min==%M and D.sec==%S and
787+ D.wday==%w+1 and D.yday==%j)",t))()
788+_G.D=nil
789+end
790+checkDateTable(os.time())
791+if not _port then
792+checkDateTable(0)
793+checkDateTable(1)
794+checkDateTable(1e3)
795+checkDateTable(2147483647)
796+checkDateTable(2147483648)
797+end
798+checkerr("invalid conversion specifier",os.date,"%")
799+checkerr("invalid conversion specifier",os.date,"%9")
800+checkerr("invalid conversion specifier",os.date,"%")
801+checkerr("invalid conversion specifier",os.date,"%O")
802+checkerr("invalid conversion specifier",os.date,"%E")
803+checkerr("invalid conversion specifier",os.date,"%Ea")
804+checkerr("not an integer",os.time,{["year"] = 1e3,["month"] = 1,["day"] = 1,["hour"] = "x"})
805+checkerr("not an integer",os.time,{["year"] = 1e3,["month"] = 1,["day"] = 1,["hour"] = 1.5})
806+checkerr("missing",os.time,{["hour"] = 12})
807+if string.packsize("i") == 4 then
808+checkerr("field 'year' is out-of-bound",os.time,{["year"] = - (1 << 31) + 1899,["month"] = 1,["day"] = 1})
809+checkerr("field 'year' is out-of-bound",os.time,{["year"] = - (1 << 31),["month"] = 1,["day"] = 1})
810+if math.maxinteger > 2 ^ 31 then
811+checkerr("field 'year' is out-of-bound",os.time,{["year"] = (1 << 31) + 1900,["month"] = 1,["day"] = 1})
812+end
813+end
814+if not _port then
815+assert(type(os.date("%Ex")) == "string")
816+assert(type(os.date("%Oy")) == "string")
817+local t0 = os.time({["year"] = 1970,["month"] = 1,["day"] = 0})
818+local t1 = os.time({["year"] = 1970,["month"] = 1,["day"] = 0,["sec"] = (1 << 31) - 1})
819+assert(t1 - t0 == (1 << 31) - 1)
820+t0=os.time({["year"] = 1970,["month"] = 1,["day"] = 1})
821+t1=os.time({["year"] = 1970,["month"] = 1,["day"] = 1,["sec"] = - (1 << 31)})
822+assert(t1 - t0 == - (1 << 31))
823+if maxint >= 2 ^ 62 then
824+checkerr("out-of-bound",os.time,{["year"] = - maxint,["month"] = 1,["day"] = 1})
825+if string.packsize("i") == 4 then
826+if testerr("out-of-bound",os.date,"%Y",2 ^ 40) then
827+print(" 4-byte time_t")
828+checkerr("cannot be represented",os.time,{["year"] = 4e3,["month"] = 1,["day"] = 1})
829+else
830+print(" 8-byte time_t")
831+checkerr("cannot be represented",os.date,"%Y",2 ^ 60)
832+assert(tonumber(os.time({["year"] = (1 << 31) + 1899,["month"] = 12,["day"] = 31,["hour"] = 23,["min"] = 59,["sec"] = 59})))
833+checkerr("represented",os.time,{["year"] = (1 << 31) + 1899,["month"] = 12,["day"] = 31,["hour"] = 23,["min"] = 59,["sec"] = 60})
834+end
835+checkerr("field 'day' is out-of-bound",os.time,{["year"] = 0,["month"] = 1,["day"] = 2 ^ 32})
836+checkerr("field 'month' is out-of-bound",os.time,{["year"] = 0,["month"] = - ((1 << 31) + 1),["day"] = 1})
837+checkerr("field 'year' is out-of-bound",os.time,{["year"] = (1 << 31) + 1900,["month"] = 1,["day"] = 1})
838+else
839+print(" 8-byte time_t")
840+assert(tonumber(os.date("%Y",2 ^ 60)))
841+checkerr("cannot be represented",os.time,{["year"] = 2 ^ 60,["month"] = 1,["day"] = 1})
842+end
843+end
844+end
845+local D = os.date("*t")
846+local t = os.time(D)
847+if D.isdst == nil then
848+print("no daylight saving information")
849+else
850+assert(type(D.isdst) == "boolean")
851+end
852+D.isdst=nil
853+local t1 = os.time(D)
854+assert(t == t1)
855+local D = os.date("*t")
856+t=os.time(D)
857+D.year=D.year - 1
858+;
859+local t1 = os.time(D)
860+assert(math.abs(os.difftime(t,t1) / (24 * 3600) - 365) < 2)
861+t=os.time()
862+t1=os.time(os.date("*t"))
863+local diff = os.difftime(t1,t)
864+assert(0 <= diff and diff <= 1)
865+diff=os.difftime(t,t1)
866+assert(- 1 <= diff and diff <= 0)
867+local t1 = os.time({["year"] = 2e3,["month"] = 10,["day"] = 1,["hour"] = 23,["min"] = 12})
868+local t2 = os.time({["year"] = 2e3,["month"] = 10,["day"] = 1,["hour"] = 23,["min"] = 10,["sec"] = 19})
869+assert(os.difftime(t1,t2) == 60 * 2 - 19)
870+t1={["year"] = 2005,["month"] = 1,["day"] = 1,["hour"] = 1,["min"] = 0,["sec"] = - 3602}
871+os.time(t1)
872+assert(t1.day == 31 and t1.month == 12 and t1.year == 2004 and t1.hour == 23 and t1.min == 59 and t1.sec == 58 and t1.yday == 366)
873+io.output(io.stdout)
874+local t = os.date("%d %m %Y %H %M %S")
875+local d,m,a,h,min,s = string.match(t,"(%d+) (%d+) (%d+) (%d+) (%d+) (%d+)")
876+d=tonumber(d)
877+m=tonumber(m)
878+a=tonumber(a)
879+h=tonumber(h)
880+min=tonumber(min)
881+s=tonumber(s)
882+io.write(string.format("test done on %2.2d/%2.2d/%d",d,m,a))
883+io.write(string.format(", at %2.2d:%2.2d:%2.2d
884+",h,min,s))
885+io.write(string.format("%s
886+",_VERSION))
zod/luau/res/lua/cycled/foo.luanew file+75
@@ -0,0 +1,75 @@
1+foosjis=nil
2+az=bar[nil]
3+baz=bar(1).foo
4+i=3
5+i,a[i]=i + 1,20 >> 9
6+hello="hellodkndjвговшов"
7+x={[hello] = 8,["hello"] = 12}
8+;
9+test_cases={{2147483647,"2147483647"},{2147483647,"2147483647"},{4294967295,"4294967295"},{4294967295,"4294967295"},{9223372036854775807,"9.2233720368548e+18"},{9.223372036854776e18,"9.2233720368548e+18"},{18446744073709551615,"1.844674407371e+19"},{1.8446744073709552e19,"1.844674407371e+19"},{4294967296,"4294967296"},{4294967296,"4294967296"},{17592186044416,"17592186044416"},{17592186044416,"17592186044416"},{2147483648,"2147483648"},{2147483648,"2147483648"},{140737488355328,"1.4073748835533e+14"},{140737488355328,"1.4073748835533e+14"}}
10+::helli::
11+foo={3,3.1416,3.1416,3.1416,340,0.1171875,162.1875,162.1875,3.141592653589793,1984}
12+foo=1
13+return 8,foo
14+print("the way of the future")
15+print("hello")
16+h({["key1"] = "Sonmi~451"})
17+goto helli
18+break
19+while true do
20+break
21+repeat
22+foo=9
23+;until true
24+if l == 3 then
25+a=a + 1
26+;
27+assert(getlocal(2,1) == "(temporary)")
28+elseifl == 4 then
29+a=a + 1
30+;
31+assert(getlocal(2,1) == "A")
32+else
33+;
34+end
35+for i = 1, 100
36+do
37+karlSum=karlSum + i
38+end
39+for j = 100, 1, 1
40+do
41+fredSum=fredSum + j
42+end
43+for key,val in pairs(u)
44+do
45+print(key,val)
46+end
47+function Dog:new()
48+newObj={["sound"] = "woof"}
49+self.__index=self
50+return setmetatable(newObj,self)
51+end
52+function Dog:makeSound()
53+print("I say " .. self.sound)
54+end
55+local function g
56+(x)
57+return math.sin(x)
58+end
59+local a = require("mod2")
60+local b = require("mod2")
61+function adder(x)
62+return (y)
63+return x + y
64+end
65+end
66+x=- 1 + 8
67+if _VERSION ~= version then
68+io.stderr:write("This test suite is for ",version,", not for ",_VERSION,"
69+Exiting tests")
70+return
71+end
72+math.randomseed()
73+local random_x,random_y = math.randomseed()
74+local random_x,random_y = math.randomseed()
75+print(string.format("random seeds: %d, %d",random_x,random_y))
zod/luau/res/lua/cycled/gc.luanew file+762
@@ -0,0 +1,762 @@
1+print("testing incremental garbage collection")
2+local debug = require("debug")
3+assert(collectgarbage("isrunning"))
4+collectgarbage()
5+local oldmode = collectgarbage("incremental")
6+assert(collectgarbage("generational") == "incremental")
7+assert(collectgarbage("generational") == "generational")
8+assert(collectgarbage("incremental") == "generational")
9+assert(collectgarbage("incremental") == "incremental")
10+local function nop
11+()
12+
13+end
14+local function gcinfo
15+()
16+return collectgarbage("count") * 1024
17+end
18+local a = collectgarbage("setpause",200)
19+local b = collectgarbage("setstepmul",200)
20+local t = {0,2,10,90,500,5e3,3e4,2147483646}
21+for i = 1, # t
22+do
23+local p = t[i]
24+for j = 1, # t
25+do
26+local m = t[j]
27+collectgarbage("setpause",p)
28+collectgarbage("setstepmul",m)
29+collectgarbage("step",0)
30+collectgarbage("step",1e4)
31+end
32+end
33+collectgarbage("setpause",a)
34+collectgarbage("setstepmul",b)
35+collectgarbage()
36+_G["while"]=234
37+local function GC1
38+()
39+local u =
40+local b =
41+local finish = false
42+u=setmetatable({},{["__gc"] = ()
43+finish=true
44+end})
45+b={34}
46+repeat
47+u={}until finish
48+assert(b[1] == 34)
49+finish=false
50+;
51+local i = 1
52+u=setmetatable({},{["__gc"] = ()
53+finish=true
54+end})
55+repeat
56+i=i + 1
57+;
58+u=tostring(i) .. tostring(i)until finish
59+assert(b[1] == 34)
60+finish=false
61+u=setmetatable({},{["__gc"] = ()
62+finish=true
63+end})
64+repeat
65+local i =
66+;
67+u=()
68+return i
69+enduntil finish
70+assert(b[1] == 34)
71+end
72+local function GC2
73+()
74+local u =
75+local finish = false
76+u={setmetatable({},{["__gc"] = ()
77+finish=true
78+end})}
79+local b = {34}
80+repeat
81+u={{}}until finish
82+assert(b[1] == 34)
83+finish=false
84+;
85+local i = 1
86+u={setmetatable({},{["__gc"] = ()
87+finish=true
88+end})}
89+repeat
90+i=i + 1
91+;
92+u={tostring(i) .. tostring(i)}until finish
93+assert(b[1] == 34)
94+finish=false
95+u={setmetatable({},{["__gc"] = ()
96+finish=true
97+end})}
98+repeat
99+local i =
100+;
101+u={()
102+return i
103+end}until finish
104+assert(b[1] == 34)
105+end
106+local function GC
107+()
108+GC1()
109+;
110+GC2()
111+end
112+print("creating many objects")
113+local limit = 5e3
114+for i = 1, limit
115+do
116+local a = {}
117+;
118+a=nil
119+end
120+local a = "a"
121+for i = 1, limit
122+do
123+a=i .. "b"
124+;
125+a=string.gsub(a,"(%d%d*)","%1 %1")
126+a="a"
127+end
128+a={}
129+function a:test()
130+for i = 1, limit
131+do
132+load(string.format("function temp(a) return 'a%d' end",i),"")()
133+assert(temp() == string.format("a%d",i))
134+end
135+end
136+a:test()
137+_G.temp=nil
138+local f = ()
139+
140+end
141+print("functions with errors")
142+local prog = "do
143+ a = 10;
144+ function foo(x,y)
145+ a = sin(a+0.456-0.23e-12);
146+ return function (z) return sin(%x+z) end
147+ end
148+ local x = function (w) a=a+w; end
149+end
150+"
151+local step = 1
152+if _soft then
153+step=13
154+end
155+for i = 1, string.len(prog), step
156+do
157+for j = i, string.len(prog), step
158+do
159+pcall(load(string.sub(prog,i,j),""))
160+end
161+end
162+rawset(_G,"a",nil)
163+_G.x=nil
164+foo=nil
165+print("long strings")
166+local x = "01234567890123456789012345678901234567890123456789012345678901234567890123456789"
167+assert(string.len(x) == 80)
168+local s = ""
169+local k = math.min(300,(math.maxinteger // 80) // 2)
170+for n = 1, k
171+do
172+s=s .. x
173+;
174+local j = tostring(n)
175+end
176+assert(string.len(s) == k * 80)
177+s=string.sub(s,1,1e4)
178+local s,i = string.gsub(s,"(%d%d%d%d)","")
179+assert(i == 1e4 // 4)
180+assert(_G["while"] == 234)
181+_G["while"]=nil
182+print("steps")
183+print("steps (2)")
184+local function dosteps
185+(siz)
186+collectgarbage()
187+local a = {}
188+for i = 1, 100
189+do
190+a[i]={{}}
191+;
192+local b = {}
193+end
194+local x = gcinfo()
195+local i = 0
196+repeat
197+i=i + 1until collectgarbage("step",siz)
198+assert(gcinfo() < x)
199+return i
200+end
201+collectgarbage("stop")
202+if not _port then
203+assert(dosteps(10) < dosteps(2))
204+end
205+assert(dosteps(2e4) == 1)
206+assert(collectgarbage("step",2e4) == true)
207+assert(collectgarbage("step",2e4) == true)
208+assert(not collectgarbage("isrunning"))
209+collectgarbage("restart")
210+assert(collectgarbage("isrunning"))
211+if not _port then
212+collectgarbage()
213+;
214+collectgarbage()
215+local x = gcinfo()
216+collectgarbage("stop")
217+repeat
218+local a = {}until gcinfo() > 3 * x
219+collectgarbage("restart")
220+assert(collectgarbage("isrunning"))
221+repeat
222+local a = {}until gcinfo() <= x * 2
223+end
224+print("clearing tables")
225+local lim = 15
226+local a = {}
227+for i = 1, lim
228+do
229+a[{}]=i
230+end
231+b={}
232+for k,v in pairs(a)
233+do
234+b[k]=v
235+end
236+for n in pairs(b)
237+do
238+a[n]=undef
239+assert(type(n) == "table" and next(n) == nil)
240+collectgarbage()
241+end
242+b=nil
243+collectgarbage()
244+for n in pairs(a)
245+do
246+error("cannot be here")
247+end
248+for i = 1, lim
249+do
250+a[i]=i
251+end
252+for i = 1, lim
253+do
254+assert(a[i] == i)
255+end
256+print("weak tables")
257+a={}
258+;
259+setmetatable(a,{["__mode"] = "k"})
260+;
261+for i = 1, lim
262+do
263+a[{}]=i
264+end
265+for i = 1, lim
266+do
267+a[i]=i
268+end
269+for i = 1, lim
270+do
271+local s = string.rep("@",i)
272+;
273+a[s]=s .. "#"
274+end
275+collectgarbage()
276+local i = 0
277+for k,v in pairs(a)
278+do
279+assert(k == v or k .. "#" == v)
280+;
281+i=i + 1
282+end
283+assert(i == 2 * lim)
284+a={}
285+;
286+setmetatable(a,{["__mode"] = "v"})
287+;
288+a[1]=string.rep("b",21)
289+collectgarbage()
290+assert(a[1])
291+a[1]=undef
292+for i = 1, lim
293+do
294+a[i]={}
295+end
296+for i = 1, lim
297+do
298+a[i .. "x"]={}
299+end
300+for i = 1, lim
301+do
302+local t = {}
303+;
304+a[t]=t
305+end
306+for i = 1, lim
307+do
308+a[i + lim]=i .. "x"
309+end
310+collectgarbage()
311+local i = 0
312+for k,v in pairs(a)
313+do
314+assert(k == v or k - lim .. "x" == v)
315+;
316+i=i + 1
317+end
318+assert(i == 2 * lim)
319+a={}
320+;
321+setmetatable(a,{["__mode"] = "kv"})
322+;
323+local x,y,z = {},{},{}
324+a[1],a[2],a[3]=x,y,z
325+a[string.rep("$",11)]=string.rep("$",11)
326+for i = 4, lim
327+do
328+a[i]={}
329+end
330+for i = 1, lim
331+do
332+a[{}]=i
333+end
334+for i = 1, lim
335+do
336+local t = {}
337+;
338+a[t]=t
339+end
340+collectgarbage()
341+assert(next(a) ~= nil)
342+local i = 0
343+for k,v in pairs(a)
344+do
345+assert((k == 1 and v == x) or (k == 2 and v == y) or (k == 3 and v == z) or k == v)
346+;
347+i=i + 1
348+end
349+assert(i == 4)
350+x,y,z=nil
351+collectgarbage()
352+assert(next(a) == string.rep("$",11))
353+a={}
354+local t = {["x"] = 10}
355+local C = setmetatable({["key"] = t},{["__mode"] = "v"})
356+local C1 = setmetatable({[t] = 1},{["__mode"] = "k"})
357+a.x=t
358+setmetatable(a,{["__gc"] = (u)
359+assert(C.key == nil)
360+assert(type(next(C1)) == "table")
361+end})
362+a,t=nil
363+collectgarbage()
364+collectgarbage()
365+assert(next(C) == nil and next(C1) == nil)
366+C,C1=nil
367+local mt = {["__mode"] = "k"}
368+a={{10},{20},{30},{40}}
369+;
370+setmetatable(a,mt)
371+x=nil
372+for i = 1, 100
373+do
374+local n = {}
375+;
376+a[n]={["k"] = {x}}
377+;
378+x=n
379+end
380+GC()
381+local n = x
382+local i = 0
383+while n do
384+n=a[n].k[1]
385+;
386+i=i + 1
387+assert(i == 100)
388+x=nil
389+GC()
390+for i = 1, 4
391+do
392+assert(a[i][1] == i * 10)
393+;
394+a[i]=undef
395+end
396+assert(next(a) == nil)
397+local K = {}
398+a[K]={}
399+for i = 1, 10
400+do
401+a[K][i]={}
402+;
403+a[a[K][i]]=setmetatable({},mt)
404+end
405+x=nil
406+local k = 1
407+for j = 1, 100
408+do
409+local n = {}
410+;
411+local nk = k % 10 + 1
412+a[a[K][nk]][n]={x,["k"] = k}
413+;
414+x=n
415+;
416+k=nk
417+end
418+GC()
419+local n = x
420+local i = 0
421+while n do
422+local t = a[a[K][k]][n]
423+;
424+n=t[1]
425+;
426+k=t.k
427+;
428+i=i + 1
429+assert(i == 100)
430+K=nil
431+GC()
432+if T then
433+collectgarbage("stop")
434+local u = {}
435+local s = {}
436+;
437+setmetatable(s,{["__mode"] = "k"})
438+setmetatable(u,{["__gc"] = (o)
439+local i = s[o]
440+s[i]=true
441+assert(not s[i - 1])
442+if i == 8 then
443+error("@expected@")
444+end
445+end})
446+for i = 6, 10
447+do
448+local n = setmetatable({},getmetatable(u))
449+s[n]=i
450+end
451+warn("@on")
452+;
453+warn("@store")
454+collectgarbage()
455+assert(string.find(_WARN,"error in __gc"))
456+assert(string.match(_WARN,"@(.-)@") == "expected")
457+;
458+_WARN=false
459+for i = 8, 10
460+do
461+assert(s[i])
462+end
463+for i = 1, 5
464+do
465+local n = setmetatable({},getmetatable(u))
466+s[n]=i
467+end
468+collectgarbage()
469+for i = 1, 10
470+do
471+assert(s[i])
472+end
473+getmetatable(u).__gc=nil
474+warn("@normal")
475+end
476+print("+")
477+if T == nil then
478+(Message or print)("
479+ >>> testC not active: skipping userdata GC tests <<<
480+")
481+else
482+local function newproxy
483+(u)
484+return debug.setmetatable(T.newuserdata(0),debug.getmetatable(u))
485+end
486+collectgarbage("stop")
487+local u = newproxy(nil)
488+debug.setmetatable(u,{["__gc"] = true})
489+local s = 0
490+local a = {[u] = 0}
491+;
492+setmetatable(a,{["__mode"] = "vk"})
493+for i = 1, 10
494+do
495+a[newproxy(u)]=i
496+end
497+for k in pairs(a)
498+do
499+assert(getmetatable(k) == getmetatable(u))
500+end
501+local a1 = {}
502+;
503+for k,v in pairs(a)
504+do
505+a1[k]=v
506+end
507+for k,v in pairs(a1)
508+do
509+a[v]=k
510+end
511+for i = 1, 10
512+do
513+assert(a[i])
514+end
515+getmetatable(u).a=a1
516+getmetatable(u).u=u
517+local u = u
518+getmetatable(u).__gc=(o)
519+assert(a[o] == 10 - s)
520+assert(a[10 - s] == undef)
521+assert(getmetatable(o) == getmetatable(u))
522+assert(getmetatable(o).a[o] == 10 - s)
523+s=s + 1
524+end
525+a1,u=nil
526+assert(next(a) ~= nil)
527+collectgarbage()
528+assert(s == 11)
529+collectgarbage()
530+assert(next(a) == nil)
531+end
532+local u = setmetatable({},{["__gc"] = true})
533+setmetatable(getmetatable(u),{["__mode"] = "v"})
534+getmetatable(u).__gc=(o)
535+os.exit(1)
536+end
537+u=nil
538+collectgarbage()
539+local u = setmetatable({},{["__gc"] = true})
540+local m = getmetatable(u)
541+m.x={[{0}] = 1,[0] = {1}}
542+;
543+setmetatable(m.x,{["__mode"] = "kv"})
544+;
545+m.__gc=(o)
546+assert(next(getmetatable(o).x) == nil)
547+m=10
548+end
549+u,m=nil
550+collectgarbage()
551+assert(m == 10)
552+collectgarbage()
553+;
554+collectgarbage()
555+local m = collectgarbage("count")
556+local a = setmetatable({},{["__mode"] = "kv"})
557+a[string.rep("a",2 ^ 22)]=25
558+a[string.rep("b",2 ^ 22)]={}
559+a[{}]=14
560+assert(collectgarbage("count") > m + 2 ^ 13)
561+collectgarbage()
562+assert(collectgarbage("count") >= m + 2 ^ 12 and collectgarbage("count") < m + 2 ^ 13)
563+local k,v = next(a)
564+assert(k == string.rep("a",2 ^ 22) and v == 25)
565+assert(next(a,k) == nil)
566+assert(a[string.rep("b",2 ^ 22)] == undef)
567+a[k]=undef
568+k=nil
569+collectgarbage()
570+assert(next(a) == nil)
571+assert(a[string.rep("b",100)] == undef)
572+assert(collectgarbage("count") <= m + 1)
573+if T then
574+warn("@store")
575+u=setmetatable({},{["__gc"] = ()
576+error("@expected error")
577+end})
578+u=nil
579+collectgarbage()
580+assert(string.find(_WARN,"@expected error"))
581+;
582+_WARN=false
583+warn("@normal")
584+end
585+if not _soft then
586+print("long list")
587+local a = {}
588+for i = 1, 2e5
589+do
590+a={["next"] = a}
591+end
592+a=nil
593+collectgarbage()
594+end
595+print("self-referenced threads")
596+local thread_id = 0
597+local threads = {}
598+local function fn
599+(thread)
600+local x = {}
601+threads[thread_id]=()
602+thread=x
603+end
604+coroutine.yield()
605+end
606+while thread_id < 1e3 do
607+local thread = coroutine.create(fn)
608+coroutine.resume(thread,thread)
609+thread_id=thread_id + 1
610+local collected = false
611+collectgarbage()
612+;
613+collectgarbage("stop")
614+local function f
615+(param)
616+;
617+(()
618+assert(type(f) == "function" and type(param) == "thread")
619+param={param,f}
620+setmetatable(param,{["__gc"] = ()
621+collected=true
622+end})
623+coroutine.yield(100)
624+end)()
625+end
626+local co = coroutine.create(f)
627+assert(coroutine.resume(co,co))
628+collectgarbage()
629+assert(collected)
630+collectgarbage("restart")
631+collectgarbage()
632+collectgarbage("stop")
633+collectgarbage("step",0)
634+local x = gcinfo()
635+repeat
636+for i = 1, 1e3
637+do
638+_ENV.a={}
639+enduntil gcinfo() > 2 * x
640+collectgarbage("restart")
641+_ENV.a=nil
642+if T then
643+local function foo
644+()
645+local a = {["x"] = 20}
646+coroutine.yield(()
647+return a.x
648+end)
649+assert(a.x == 20)
650+a={["x"] = 30}
651+assert(T.gccolor(a) == "white")
652+coroutine.yield(100)
653+end
654+local t = setmetatable({},{["__mode"] = "kv"})
655+collectgarbage()
656+;
657+collectgarbage("stop")
658+t.co=coroutine.wrap(foo)
659+local f = t.co()
660+T.gcstate("atomic")
661+assert(T.gcstate() == "atomic")
662+assert(t.co() == 100)
663+assert(T.gccolor(t.co) == "white")
664+T.gcstate("pause")
665+assert(t.co == nil and f() == 30)
666+collectgarbage("restart")
667+local u = T.newuserdata(0,1)
668+collectgarbage()
669+collectgarbage("stop")
670+local a = {}
671+T.gcstate("atomic")
672+T.gcstate("sweepallgc")
673+local x = {}
674+assert(T.gccolor(u) == "black")
675+assert(T.gccolor(x) == "white")
676+debug.setuservalue(u,x)
677+assert(T.gccolor(u) == "gray")
678+collectgarbage("restart")
679+print("+")
680+end
681+if T then
682+local debug = require("debug")
683+collectgarbage("stop")
684+local x = T.newuserdata(0)
685+local y = T.newuserdata(0)
686+debug.setmetatable(y,{["__gc"] = nop})
687+debug.setmetatable(x,{["__gc"] = nop})
688+assert(T.gccolor(y) == "white")
689+T.checkmemory()
690+collectgarbage("restart")
691+end
692+if T then
693+print("emergency collections")
694+collectgarbage()
695+collectgarbage()
696+T.totalmem(T.totalmem() + 200)
697+for i = 1, 200
698+do
699+local a = {}
700+end
701+T.totalmem(0)
702+collectgarbage()
703+local t = T.totalmem("table")
704+local a = {{},{},{}}
705+assert(T.totalmem("table") == t + 4)
706+t=T.totalmem("function")
707+a=()
708+
709+end
710+assert(T.totalmem("function") == t + 1)
711+t=T.totalmem("thread")
712+a=coroutine.create(()
713+
714+end)
715+assert(T.totalmem("thread") == t + 1)
716+end
717+local setmetatable,assert,type,print,getmetatable = setmetatable,assert,type,print,getmetatable
718+local tt = {}
719+tt.__gc=(o)
720+assert(getmetatable(o) == tt)
721+local a = "xuxu" .. (10 + 3) .. "joao",{}
722+___Glob=o
723+setmetatable({},tt)
724+print(">>> closing state " .. "<<<
725+")
726+end
727+local u = setmetatable({},tt)
728+___Glob={u}
729+if T then
730+local error,assert,find,warn = error,assert,string.find,warn
731+local n = 0
732+local lastmsg =
733+local mt = {["__gc"] = (o)
734+n=n + 1
735+assert(n == o[1])
736+if n == 1 then
737+_WARN=false
738+elseifn == 2 then
739+assert(find(_WARN,"@expected warning"))
740+lastmsg=_WARN
741+else
742+assert(lastmsg == _WARN)
743+end
744+warn("@store")
745+;
746+_WARN=false
747+error("@expected warning")
748+end}
749+for i = 10, 1, - 1
750+do
751+table.insert(___Glob,setmetatable({i},mt))
752+end
753+end
754+assert(collectgarbage("isrunning"))
755+local res = true
756+setmetatable({},{["__gc"] = ()
757+res=collectgarbage()
758+end})
759+collectgarbage()
760+assert(not res)
761+collectgarbage(oldmode)
762+print("OK")
zod/luau/res/lua/cycled/gengc.luanew file+98
@@ -0,0 +1,98 @@
1+print("testing generational garbage collection")
2+local debug = require("debug")
3+assert(collectgarbage("isrunning"))
4+collectgarbage()
5+local oldmode = collectgarbage("generational")
6+local U = {}
7+collectgarbage()
8+assert(not T or T.gcage(U) == "old")
9+U[1]={["x"] = {234}}
10+assert(not T or (T.gcage(U) == "touched1" and T.gcage(U[1]) == "new"))
11+collectgarbage("step",0)
12+assert(not T or (T.gcage(U) == "touched2" and T.gcage(U[1]) == "survival"))
13+collectgarbage("step",0)
14+assert(not T or (T.gcage(U) == "old" and T.gcage(U[1]) == "old1"))
15+assert(U[1].x[1] == 234)
16+local function foo
17+()
18+
19+end
20+local old = {10}
21+collectgarbage()
22+assert(not T or T.gcage(old) == "old")
23+setmetatable(old,{})
24+assert(not T or T.gcage(getmetatable(old)) == "old0")
25+collectgarbage("step",0)
26+assert(not T or T.gcage(getmetatable(old)) == "old1")
27+setmetatable(getmetatable(old),{["__gc"] = foo})
28+collectgarbage("step",0)
29+local A = {}
30+A[1]=false
31+local function gcf
32+(obj)
33+A[1]=obj
34+assert(not T or T.gcage(obj) == "old1")
35+obj=nil
36+collectgarbage("step",0)
37+print(getmetatable(A[1]).x)
38+end
39+collectgarbage()
40+local obj = {}
41+collectgarbage("step",0)
42+assert(not T or T.gcage(obj) == "survival")
43+setmetatable(obj,{["__gc"] = gcf,["x"] = "+"})
44+assert(not T or T.gcage(getmetatable(obj)) == "new")
45+obj=nil
46+collectgarbage("step",0)
47+local old = {10}
48+collectgarbage()
49+local co = coroutine.create(()
50+local x = nil
51+local f = ()
52+return x[1]
53+end
54+x=coroutine.yield(f)
55+coroutine.yield()
56+end)
57+local _,f = coroutine.resume(co)
58+collectgarbage("step",0)
59+old[1]={"hello"}
60+coroutine.resume(co,{123})
61+co=nil
62+collectgarbage("step",0)
63+assert(f() == 123 and old[1][1] == "hello")
64+collectgarbage("step",0)
65+assert(f() == 123 and old[1][1] == "hello")
66+local t = setmetatable({},{["__mode"] = "kv"})
67+collectgarbage()
68+assert(not T or T.gcage(t) == "old")
69+t[1]={10}
70+assert(not T or (T.gcage(t) == "touched1" and T.gccolor(t) == "gray"))
71+collectgarbage("step",0)
72+assert(not T or (T.gcage(t) == "touched2" and T.gccolor(t) == "black"))
73+collectgarbage("step",0)
74+assert(not T or T.gcage(t) == "old")
75+t[1]={10}
76+collectgarbage("step",0)
77+assert(t[1] == nil)
78+if T == nil then
79+(Message or print)("
80+ >>> testC not active: skipping some generational tests <<<
81+")
82+print("OK")
83+return
84+end
85+local U = T.newuserdata(0,1)
86+collectgarbage()
87+assert(T.gcage(U) == "old")
88+debug.setuservalue(U,{["x"] = {234}})
89+assert(T.gcage(U) == "touched1" and T.gcage(debug.getuservalue(U)) == "new")
90+collectgarbage("step",0)
91+assert(T.gcage(U) == "touched2" and T.gcage(debug.getuservalue(U)) == "survival")
92+collectgarbage("step",0)
93+assert(T.gcage(U) == "old" and T.gcage(debug.getuservalue(U)) == "old1")
94+assert(debug.getuservalue(U).x[1] == 234)
95+assert(collectgarbage("isrunning"))
96+assert(collectgarbage("isrunning"))
97+collectgarbage(oldmode)
98+print("OK")
zod/luau/res/lua/cycled/goto.luanew file+262
@@ -0,0 +1,262 @@
1+collectgarbage()
2+local function errmsg
3+(code,m)
4+local st,msg = load(code)
5+assert(not st and string.find(msg,m))
6+end
7+errmsg(" goto l1; do ::l1:: end ","label 'l1'")
8+errmsg(" do ::l1:: end goto l1; ","label 'l1'")
9+errmsg(" ::l1:: ::l1:: ","label 'l1'")
10+errmsg(" ::l1:: do ::l1:: end","label 'l1'")
11+errmsg(" goto l1; local aa ::l1:: ::l2:: print(3) ","local 'aa'")
12+errmsg("do local bb, cc; goto l1; end
13+local aa
14+::l1:: print(3)
15+","local 'aa'")
16+errmsg(" do ::l1:: end goto l1 ","label 'l1'")
17+errmsg(" goto l1 do ::l1:: end ","label 'l1'")
18+errmsg(" repeat
19+ if x then goto cont end
20+ local xuxu = 10
21+ ::cont::
22+ until xuxu < x
23+","local 'xuxu'")
24+local x =
25+local y = 12
26+goto l1
27+::l2::
28+x=x + 1
29+;
30+goto l3
31+::l1::
32+x=y
33+;
34+goto l2
35+::l3::
36+::l3_1::
37+assert(x == 13)
38+local prog = " do
39+ local a = 1
40+ goto l%sa; a = a + 1
41+ ::l%sa:: a = a + 10
42+ goto l%sb; a = a + 2
43+ ::l%sb:: a = a + 20
44+ return a
45+ end
46+ "
47+local label = string.rep("0123456789",40)
48+prog=string.format(prog,label,label,label,label)
49+assert(assert(load(prog))() == 31)
50+goto l1
51+local a = 23
52+x=a
53+::l1::
54+;
55+while true do
56+goto l4
57+goto l1
58+goto l1
59+local x = 45
60+::l1::
61+;
62+;
63+;
64+::l4::
65+assert(x == 13)
66+if print then
67+goto l1
68+error("should not be here")
69+goto l2
70+local x =
71+::l1::
72+;
73+::l2::
74+;
75+;
76+else
77+
78+end
79+local function foo
80+()
81+local a = {}
82+goto l3
83+::l1::
84+a[# a + 1]=1
85+;
86+goto l2
87+;
88+::l2::
89+a[# a + 1]=2
90+;
91+goto l5
92+;
93+::l3::
94+::l3a::
95+a[# a + 1]=3
96+;
97+goto l1
98+;
99+::l4::
100+a[# a + 1]=4
101+;
102+goto l6
103+;
104+::l5::
105+a[# a + 1]=5
106+;
107+goto l4
108+;
109+::l6::
110+assert(a[1] == 3 and a[2] == 1 and a[3] == 2 and a[4] == 5 and a[5] == 4)
111+if not a[6] then
112+a[6]=true
113+;
114+goto l3a
115+end
116+end
117+::l6::
118+foo()
119+local x =
120+::L1::
121+local y =
122+assert(y == nil)
123+y=true
124+if x == nil then
125+x=1
126+goto L1
127+else
128+x=x + 1
129+end
130+assert(x == 2 and y == true)
131+local first = true
132+local a = false
133+if true then
134+goto LBL
135+::loop::
136+a=true
137+::LBL::
138+if first then
139+first=false
140+goto loop
141+end
142+end
143+assert(a)
144+goto escape
145+::a::
146+goto a
147+::b::
148+goto c
149+::c::
150+goto b
151+::escape::
152+local debug = require("debug")
153+local function foo
154+()
155+local t = {}
156+local i = 1
157+local a,b,c,d =
158+t[1]=()
159+return a,b,c,d
160+end
161+::l1::
162+local b =
163+local c =
164+t[# t + 1]=()
165+return a,b,c,d
166+end
167+if i > 2 then
168+goto l2
169+end
170+local d =
171+t[# t + 1]=()
172+return a,b,c,d
173+end
174+i=i + 1
175+local a =
176+goto l1
177+::l2::
178+return t
179+end
180+local a = foo()
181+assert(# a == 6)
182+for i = 2, 6
183+do
184+assert(debug.upvalueid(a[1],1) == debug.upvalueid(a[i],1))
185+end
186+for i = 2, 6
187+do
188+assert(debug.upvalueid(a[1],2) ~= debug.upvalueid(a[i],2))
189+assert(debug.upvalueid(a[1],3) ~= debug.upvalueid(a[i],3))
190+end
191+for i = 3, 5, 2
192+do
193+assert(debug.upvalueid(a[i],2) == debug.upvalueid(a[i - 1],2))
194+assert(debug.upvalueid(a[i],3) == debug.upvalueid(a[i - 1],3))
195+assert(debug.upvalueid(a[i],2) ~= debug.upvalueid(a[i + 1],2))
196+assert(debug.upvalueid(a[i],3) ~= debug.upvalueid(a[i + 1],3))
197+end
198+for i = 2, 6, 2
199+do
200+assert(debug.upvalueid(a[1],4) == debug.upvalueid(a[i],4))
201+end
202+for i = 3, 5, 2
203+do
204+for j = 1, 6
205+do
206+assert((debug.upvalueid(a[i],4) == debug.upvalueid(a[j],4)) == (i == j))
207+end
208+end
209+local function testG
210+(a)
211+if a == 1 then
212+goto l1
213+error("should never be here!")
214+elseifa == 2 then
215+goto l2
216+elseifa == 3 then
217+goto l3
218+elseifa == 4 then
219+goto l1
220+error("should never be here!")
221+::l1::
222+a=a + 1
223+else
224+goto l4
225+::l4a::
226+a=a * 2
227+;
228+goto l4b
229+error("should never be here!")
230+::l4::
231+goto l4a
232+error("should never be here!")
233+::l4b::
234+end
235+return a
236+::l2::
237+return "2"
238+::l3::
239+return "3"
240+::l1::
241+return "1"
242+end
243+assert(testG(1) == "1")
244+assert(testG(2) == "2")
245+assert(testG(3) == "3")
246+assert(testG(4) == 5)
247+assert(testG(5) == 10)
248+local X =
249+goto L1
250+::L2::
251+goto L3
252+::L1::
253+local a <close> = setmetatable({},{["__close"] = ()
254+X=true
255+end})
256+assert(X == nil)
257+if a then
258+goto L2
259+end
260+::L3::
261+assert(X == true)
262+print("OK")
zod/luau/res/lua/cycled/heavy.luanew file+132
@@ -0,0 +1,132 @@
1+local function teststring
2+()
3+print("creating a string too long")
4+local a = "x"
5+local st,msg = pcall(()
6+while true do
7+a=a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a .. a
8+print(string.format("string with %d bytes",# a))
9+end)
10+assert(not st and (string.find(msg,"string length overflow") or string.find(msg,"not enough memory")))
11+print("string length overflow with " .. # a * 100)
12+print("+")
13+end
14+local function loadrep
15+(x,what)
16+local p = 1 << 20
17+local s = string.rep(x,p)
18+local count = 0
19+local function f
20+()
21+count=count + p
22+if count % (128 * p) == 0 then
23+io.stderr:write("(",count // 2 ^ 20," M)")
24+end
25+return s
26+end
27+local st,msg = load(f,"=big")
28+print("
29+memory: ",collectgarbage("count") * 1024)
30+msg=string.match(msg,"^[^
31+]+")
32+print(string.format("total: 0x%x %s ('%s')",count,what,msg))
33+return st,msg
34+end
35+function controlstruct()
36+print("control structure too long")
37+local lim = ((1 << 24) - 2) // 3
38+local s = string.rep("a = a + 1
39+",lim)
40+s="while true do " .. s .. "end"
41+assert(load(s))
42+print("ok with " .. lim .. " lines")
43+lim=lim + 3
44+s=string.rep("a = a + 1
45+",lim)
46+s="while true do " .. s .. "end"
47+local st,msg = load(s)
48+assert(not st and string.find(msg,"too long"))
49+print(msg)
50+end
51+function manylines()
52+print("loading chunk with too many lines")
53+local st,msg = loadrep("
54+","lines")
55+assert(not st and string.find(msg,"too many lines"))
56+print("+")
57+end
58+function hugeid()
59+print("loading chunk with huge identifier")
60+local st,msg = loadrep("a","chars")
61+assert(not st and (string.find(msg,"lexical element too long") or string.find(msg,"not enough memory")))
62+print("+")
63+end
64+function toomanyinst()
65+print("loading chunk with too many instructions")
66+local st,msg = loadrep("a = 10; ","instructions")
67+print("+")
68+end
69+local function loadrepfunc
70+(prefix,f)
71+local count = - 1
72+local function aux
73+()
74+count=count + 1
75+if count == 0 then
76+return prefix
77+else
78+if count % (1048576) == 0 then
79+io.stderr:write("(",count // 2 ^ 20," M)")
80+end
81+return f(count)
82+end
83+end
84+local st,msg = load(aux,"k")
85+print("
86+memory: ",collectgarbage("count") * 1024)
87+msg=string.match(msg,"^[^
88+]+")
89+print("expected error: ",msg)
90+end
91+function toomanyconst()
92+print("loading function with too many constants")
93+loadrepfunc("function foo () return {0,",(n)
94+return string.char(34,((n // 128 ^ 0) & 127) + 128,((n // 128 ^ 1) & 127) + 128,((n // 128 ^ 2) & 127) + 128,((n // 128 ^ 3) & 127) + 128,((n // 128 ^ 4) & 127) + 128,34,44)
95+end)
96+end
97+function toomanystr()
98+local a = {}
99+local st,msg = pcall(()
100+for i = 1, math.huge
101+do
102+if i % (1048576) == 0 then
103+io.stderr:write("(",i // 2 ^ 20," M)")
104+end
105+a[i]=string.pack("I",i)
106+end
107+end)
108+local size = # a
109+a=collectgarbage("count")
110+print("
111+memory:",a * 1024)
112+print("expected error:",msg)
113+print("size:",size)
114+end
115+function toomanyidx()
116+local a = {}
117+local st,msg = pcall(()
118+for i = 1, math.huge
119+do
120+if i % (1048576) == 0 then
121+io.stderr:write("(",i // 2 ^ 20," M)")
122+end
123+a[i]=i
124+end
125+end)
126+print("
127+memory: ",collectgarbage("count") * 1024)
128+print("expected error: ",msg)
129+print("size:",# a)
130+end
131+toomanyidx()
132+print("OK")
zod/luau/res/lua/cycled/literals.luanew file+311
@@ -0,0 +1,311 @@
1+print("testing scanner")
2+local debug = require("debug")
3+local function dostring
4+(x)
5+return assert(load(x),"")()
6+end
7+dostring("x = 'aa' ")
8+assert(x == "aa" and string.len(x) == 3)
9+_G.x=nil
10+assert("
11+"'\" == "
12+"'\")
13+assert(string.find("
14+ ","^%c%c%c%c%c%c%c$"))
15+assert("c12" == "c12")
16+assert("cab" == "cab")
17+assert("c" == "c")
18+assert("c
19+" == "c
20+")
21+assert("alo" == "" .. "" .. "alo")
22+assert(10 .. 20 .. - 30 == "1020-30")
23+assert("<��" == "<��")
24+local function lexstring
25+(x,y,n)
26+local f = assert(load("return " .. x .. ", require"debug".getinfo(1).currentline",""))
27+local s,l = f()
28+assert(s == y and l == n)
29+end
30+lexstring("'abc\z
31+ efg'","abcefg",2)
32+lexstring("'abc\z
33+
34+
35+'","abc",4)
36+lexstring("'\z
37+
38+'","",3)
39+lexstring("[[
40+alo
41+alo
42+
43+]]","alo
44+alo
45+
46+",5)
47+lexstring("[[
48+alo alo
49+
50+]]","alo
51+alo
52+
53+",5)
54+lexstring("[[
55+alo alo
56+]]","alo
57+alo
58+",4)
59+lexstring("[[ alo
60+ alo
61+]]","alo
62+alo
63+",4)
64+lexstring("[[alo]
65+]alo]]","alo]
66+]alo",2)
67+assert("abcdefghi" == "abcdefghi")
68+assert("" == string.char(0,0,0,0))
69+assert("" == "")
70+assert("��" == "€߿")
71+assert("��" == "ࠀ￿")
72+assert("��" == "𐀀����")
73+assert(" ���" == "����������")
74+assert("���" == "������������")
75+local function lexerror
76+(s,err)
77+local st,msg = load("return " .. s,"")
78+if err ~= "<eof>" then
79+err=err .. "'"
80+end
81+assert(not st and string.find(msg,"near .-" .. err))
82+end
83+lexerror(""abc\x"","\x"")
84+lexerror(""abc\x","\x")
85+lexerror(""\x","\x")
86+lexerror(""\x5"","\x5"")
87+lexerror(""\x5","\x5")
88+lexerror(""\xr"","\xr")
89+lexerror(""\xr","\xr")
90+lexerror(""\x.","\x.")
91+lexerror(""\x8%"","\x8%%")
92+lexerror(""\xAG","\xAG")
93+lexerror(""\g"","\g")
94+lexerror(""\g","\g")
95+lexerror(""\."","\%.")
96+lexerror(""\999"","\999"")
97+lexerror(""xyz\300"","\300"")
98+lexerror("" \256"","\256"")
99+lexerror(""abc\u{100000000}"","abc\u{100000000")
100+lexerror(""abc\u11r"","abc\u1")
101+lexerror(""abc\u"","abc\u"")
102+lexerror(""abc\u{11r"","abc\u{11r")
103+lexerror(""abc\u{11"","abc\u{11"")
104+lexerror(""abc\u{11","abc\u{11")
105+lexerror(""abc\u{r"","abc\u{r")
106+lexerror("[=[alo]]","<eof>")
107+lexerror("[=[alo]=","<eof>")
108+lexerror("[=[alo]","<eof>")
109+lexerror("'alo","<eof>")
110+lexerror("'alo \z
111+
112+","<eof>")
113+lexerror("'alo \z","<eof>")
114+lexerror("'alo \98","<eof>")
115+for i = 0, 255
116+do
117+local s = string.char(i)
118+assert(not string.find(s,"[a-zA-Z_]") == not load(s .. "=1",""))
119+assert(not string.find(s,"[a-zA-Z_0-9]") == not load("a" .. s .. "1 = 1",""))
120+end
121+local var1 = string.rep("a",1.5e4) .. "1"
122+local var2 = string.rep("a",1.5e4) .. "2"
123+local prog = string.format(" %s = 5
124+ %s = %s + 1
125+ return function () return %s - %s end
126+",var1,var2,var1,var1,var2)
127+local f = dostring(prog)
128+assert(_G[var1] == 5 and _G[var2] == 6 and f() == - 1)
129+_G[var1],_G[var2]=nil
130+print("+")
131+assert("
132+ " == "
133+ ")
134+assert("
135+ $debug" == "
136+ $debug")
137+assert(" [ " ~= " ] ")
138+local b = "001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789"
139+assert(string.len(b) == 960)
140+prog="print('+')
141+
142+local a1 = [["this is a 'string' with several 'quotes'"]]
143+local a2 = "'quotes'"
144+
145+assert(string.find(a1, a2) == 34)
146+print('+')
147+
148+a1 = [==[temp = [[an arbitrary value]]; ]==]
149+assert(load(a1))()
150+assert(temp == 'an arbitrary value')
151+_G.temp = nil
152+-- long strings --
153+local b = "001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789"
154+assert(string.len(b) == 960)
155+print('+')
156+
157+local a = [[00123456789012345678901234567890123456789123456789012345678901234567890123456789
158+00123456789012345678901234567890123456789123456789012345678901234567890123456789
159+00123456789012345678901234567890123456789123456789012345678901234567890123456789
160+00123456789012345678901234567890123456789123456789012345678901234567890123456789
161+00123456789012345678901234567890123456789123456789012345678901234567890123456789
162+00123456789012345678901234567890123456789123456789012345678901234567890123456789
163+00123456789012345678901234567890123456789123456789012345678901234567890123456789
164+00123456789012345678901234567890123456789123456789012345678901234567890123456789
165+00123456789012345678901234567890123456789123456789012345678901234567890123456789
166+00123456789012345678901234567890123456789123456789012345678901234567890123456789
167+00123456789012345678901234567890123456789123456789012345678901234567890123456789
168+00123456789012345678901234567890123456789123456789012345678901234567890123456789
169+00123456789012345678901234567890123456789123456789012345678901234567890123456789
170+00123456789012345678901234567890123456789123456789012345678901234567890123456789
171+00123456789012345678901234567890123456789123456789012345678901234567890123456789
172+00123456789012345678901234567890123456789123456789012345678901234567890123456789
173+00123456789012345678901234567890123456789123456789012345678901234567890123456789
174+00123456789012345678901234567890123456789123456789012345678901234567890123456789
175+00123456789012345678901234567890123456789123456789012345678901234567890123456789
176+00123456789012345678901234567890123456789123456789012345678901234567890123456789
177+00123456789012345678901234567890123456789123456789012345678901234567890123456789
178+00123456789012345678901234567890123456789123456789012345678901234567890123456789
179+00123456789012345678901234567890123456789123456789012345678901234567890123456789
180+]]
181+assert(string.len(a) == 1863)
182+assert(string.sub(a, 1, 40) == string.sub(b, 1, 40))
183+x = 1
184+"
185+print("+")
186+_G.x=nil
187+dostring(prog)
188+assert(x)
189+_G.x=nil
190+local function getadd
191+(s)
192+return string.format("%p",s)
193+end
194+local s1 <const> = "01234567890123456789012345678901234567890123456789"
195+local s2 <const> = "01234567890123456789012345678901234567890123456789"
196+local s3 = "01234567890123456789012345678901234567890123456789"
197+local function foo
198+()
199+return s1
200+end
201+local function foo1
202+()
203+return s3
204+end
205+local function foo2
206+()
207+return "01234567890123456789012345678901234567890123456789"
208+end
209+local a1 = getadd(s1)
210+assert(a1 == getadd(s2))
211+assert(a1 == getadd(foo()))
212+assert(a1 == getadd(foo1()))
213+assert(a1 == getadd(foo2()))
214+local sd = "0123456789" .. "0123456789012345678901234567890123456789"
215+assert(sd == s1 and getadd(sd) ~= a1)
216+prog="local a = 1 -- a comment
217+local b = 2
218+
219+
220+x = [=[
221+hi
222+]=]
223+y = "\
224+hello\r\n\
225+"
226+return require"debug".getinfo(1).currentline
227+"
228+for _,n in pairs({"
229+"," ","
230+ ","
231+"})
232+do
233+local prog,nn = string.gsub(prog,"
234+",n)
235+assert(dostring(prog) == nn)
236+assert(_G.x == "hi
237+" and _G.y == "
238+hello
239+
240+")
241+end
242+_G.x,_G.y=nil
243+local a = "]="
244+assert(a == "]=")
245+a="[===[[=[]]=][====[]]===]==="
246+assert(a == "[===[[=[]]=][====[]]===]===")
247+a="[===[[=[]]=][====[]]===]==="
248+assert(a == "[===[[=[]]=][====[]]===]===")
249+a="]]]]]]]]"
250+assert(a == "]]]]]]]]")
251+local x = {"=","[","]","
252+"}
253+local len = 4
254+local function gen
255+(c,n)
256+if n == 0 then
257+coroutine.yield(c)
258+else
259+for _,a in pairs(x)
260+do
261+gen(c .. a,n - 1)
262+end
263+end
264+end
265+for s in coroutine.wrap(()
266+gen("",len)
267+end)
268+do
269+assert(s == load("return [====[
270+" .. s .. "]====]","")())
271+end
272+if os.setlocale("pt_BR") or os.setlocale("ptb") then
273+assert(tonumber("3,4") == 3.4 and tonumber("3.4") == 3.4)
274+assert(tonumber(" -.4 ") == - 0.4)
275+assert(tonumber(" +0x.41 ") == 0.25390625)
276+assert(not load("a = (3,4)"))
277+assert(assert(load("return 3.4"))() == 3.4)
278+assert(assert(load("return .4,3"))() == 0.4)
279+assert(assert(load("return 4."))() == 4)
280+assert(assert(load("return 4.+.5"))() == 4.5)
281+assert(" 0x.1 " + " 0x,1" + "-0X.1 " == 0.0625)
282+assert(not tonumber("inf") and not tonumber("NAN"))
283+assert(assert(load(string.format("return %q",4.51)))() == 4.51)
284+local a,b = load("return 4.5.")
285+assert(string.find(b,"'4%.5%.'"))
286+assert(os.setlocale("C"))
287+else
288+(Message or print)("
289+ >>> pt_BR locale not available: skipping decimal point tests <<<
290+")
291+end
292+local s = "a string with and
293+ and
294+ and
295+ "
296+local c = string.format("return %q",s)
297+assert(assert(load(c))() == s)
298+assert(not load("a = 'non-ending string"))
299+assert(not load("a = 'non-ending string
300+'"))
301+assert(not load("a = '\345'"))
302+assert(not load("a = [=x]"))
303+local function malformednum
304+(n,exp)
305+local s,msg = load("return " .. n)
306+assert(not s and string.find(msg,exp))
307+end
308+malformednum("0xe-","near <eof>")
309+malformednum("0xep-p","malformed number")
310+malformednum("1print()","malformed number")
311+print("OK")
zod/luau/res/lua/cycled/locals.luanew file+987
@@ -0,0 +1,987 @@
1+print("testing local variables and environments")
2+local debug = require("debug")
3+local tracegc = require("tracegc")
4+local function f
5+(x)
6+x=nil
7+;
8+return x
9+end
10+assert(f(10) == nil)
11+local function f
12+()
13+local x =
14+;
15+return x
16+end
17+assert(f(10) == nil)
18+local function f
19+(x)
20+x=nil
21+;
22+local y =
23+;
24+return x,y
25+end
26+assert(f(10) == nil and select(2,f(20)) == nil)
27+local i = 10
28+local i = 100
29+;
30+assert(i == 100)
31+local i = 1e3
32+;
33+assert(i == 1e3)
34+assert(i == 10)
35+if i ~= 10 then
36+local i = 20
37+else
38+local i = 30
39+assert(i == 30)
40+end
41+f=nil
42+local f =
43+local x = 1
44+a=nil
45+load("local a = {}")()
46+assert(a == nil)
47+function f(a)
48+local _1,_2,_3,_4,_5 =
49+local _6,_7,_8,_9,_10 =
50+local x = 3
51+local b = a
52+local c,d = a,b
53+if (d == b) then
54+local x = "q"
55+x=b
56+assert(x == 2)
57+else
58+assert(nil)
59+end
60+assert(x == 3)
61+local f = 10
62+end
63+local b = 10
64+local a =
65+;
66+repeat
67+local b =
68+;
69+a,b=1,2
70+;
71+assert(a + 1 == b)
72+;until a + b == 3
73+assert(x == 1)
74+f(2)
75+assert(type(f) == "function")
76+local function getenv
77+(f)
78+local a,b = debug.getupvalue(f,1)
79+assert(a == "_ENV")
80+return b
81+end
82+assert(getenv(load("a=3")) == _G)
83+local c = {}
84+;
85+local f = load("a = 3",nil,nil,c)
86+assert(getenv(f) == c)
87+assert(c.a == nil)
88+f()
89+assert(c.a == 3)
90+local i = 2
91+local p = 4
92+repeat
93+for j = - 3, 3
94+do
95+assert(load(string.format("local a=%s;
96+ a=a+%s;
97+ assert(a ==2^%s)",j,p - j,i),""))()
98+assert(load(string.format("local a=%s;
99+ a=a-%s;
100+ assert(a==-2^%s)",- j,p - j,i),""))()
101+assert(load(string.format("local a,b=0,%s;
102+ a=b-%s;
103+ assert(a==-2^%s)",- j,p - j,i),""))()
104+end
105+p=2 * p
106+;
107+i=i + 1until p <= 0
108+print("+")
109+if rawget(_G,"T") then
110+collectgarbage("stop")
111+local a = {[{}] = 4,[3] = 0,["alo"] = 1,["a1234567890123456789012345678901234567890"] = 10}
112+local t = T.querytab(a)
113+for k,_ in pairs(a)
114+do
115+a[k]=undef
116+end
117+collectgarbage()
118+for i = 0, t - 1
119+do
120+local k = querytab(a,i)
121+assert(k == nil or type(k) == "number" or k == "alo")
122+end
123+local a = {}
124+local function additems
125+()
126+a.x=true
127+;
128+a.y=true
129+;
130+a.z=true
131+a[1]=true
132+a[2]=true
133+end
134+for i = 1, math.huge
135+do
136+T.alloccount(i)
137+local st,msg = pcall(additems)
138+T.alloccount()
139+local count = 0
140+for k,v in pairs(a)
141+do
142+assert(a[k] == v)
143+count=count + 1
144+end
145+if st then
146+assert(count == 5)
147+;
148+break
149+end
150+end
151+end
152+assert(_ENV == _G)
153+local dummy =
154+local _ENV = ((...)
155+return ...
156+end)(_G,dummy)
157+local _ENV = {["assert"] = assert}
158+;
159+assert(true)
160+local mt = {["_G"] = _G}
161+local foo,x =
162+A=false
163+local _ENV = mt
164+function foo(x)
165+A=x
166+local _ENV = _G
167+;
168+A=1e3
169+return (x)
170+return A .. x
171+end
172+end
173+assert(getenv(foo) == mt)
174+x=foo("hi")
175+;
176+assert(mt.A == "hi" and A == 1e3)
177+assert(x("*") == mt.A .. "*")
178+local _ENV = {["assert"] = assert,["A"] = 10}
179+;
180+local _ENV = {["assert"] = assert,["A"] = 20}
181+;
182+assert(A == 20)
183+;
184+x=A
185+assert(A == 10 and x == 20)
186+assert(x == 20)
187+A=nil
188+local a <const>,b,c <const> = 10,20,30
189+b=a + c + b
190+assert(a == 10 and b == 60 and c == 30)
191+local function checkro
192+(name,code)
193+local st,msg = load(code)
194+local gab = string.format("attempt to assign to const variable '%s'",name)
195+assert(not st and string.find(msg,gab))
196+end
197+checkro("y","local x, y <const>, z = 10, 20, 30; x = 11; y = 12")
198+checkro("x","local x <const>, y, z <const> = 10, 20, 30; x = 11")
199+checkro("z","local x <const>, y, z <const> = 10, 20, 30; y = 10; z = 11")
200+checkro("foo","local foo <const> = 10; function foo() end")
201+checkro("foo","local foo <const> = {}; function foo() end")
202+checkro("z"," local a, z <const>, b = 10;
203+ function foo() a = 20; z = 32; end
204+ ")
205+checkro("var1"," local a, var1 <const> = 10;
206+ function foo() a = 20; z = function () var1 = 12; end end
207+ ")
208+print("testing to-be-closed variables")
209+local function stack
210+(n)
211+n=((n == 0) or stack(n - 1))
212+end
213+local function func2close
214+(f,x,y)
215+local obj = setmetatable({},{["__close"] = f})
216+if x then
217+return x,obj,y
218+else
219+return obj
220+end
221+end
222+local a = {}
223+local b <close> = false
224+local x <close> = setmetatable({"x"},{["__close"] = (self)
225+a[# a + 1]=self[1]
226+end})
227+local w,y <close>,z = func2close((self,err)
228+assert(err == nil)
229+;
230+a[# a + 1]="y"
231+end,10,20)
232+local c <close> = nil
233+a[# a + 1]="in"
234+assert(w == 10 and z == 20)
235+a[# a + 1]="out"
236+assert(a[1] == "in" and a[2] == "y" and a[3] == "x" and a[4] == "out")
237+local X = false
238+local x,closescope = func2close((_,msg)
239+stack(10)
240+;
241+assert(msg == nil)
242+X=true
243+end,100)
244+assert(x == 100)
245+;
246+x=101
247+;
248+local function foo
249+(x)
250+local _ <close> = closescope
251+return x,X,23
252+end
253+local a,b,c = foo(1.5)
254+assert(a == 1.5 and b == false and c == 23 and X == true)
255+X=false
256+foo=(x)
257+local _ <close> = func2close((_,msg)
258+assert(debug.getinfo(2).name == "foo")
259+assert(msg == nil)
260+end)
261+local _ <close> = closescope
262+local y = 15
263+return y
264+end
265+assert(foo() == 15 and X == true)
266+X=false
267+foo=()
268+local x <close> = closescope
269+return x
270+end
271+assert(foo() == closescope and X == true)
272+local flag = false
273+local x = setmetatable({},{["__close"] = ()
274+assert(flag == false)
275+;
276+flag=true
277+end})
278+local y <const> = nil
279+local z <const> = nil
280+local a <close> = x
281+assert(flag)
282+local flag = false
283+local x = setmetatable({},{["__close"] = ()
284+assert(flag == false)
285+;
286+flag=true
287+end})
288+local function a
289+()
290+return (()
291+return nil
292+end),nil,nil,x
293+end
294+local v <const> = 1
295+local w <const> = 1
296+local x <const> = 1
297+local y <const> = 1
298+local z <const> = 1
299+for k in a()
300+do
301+a=k
302+end
303+assert(flag)
304+local X,Y =
305+local function foo
306+()
307+local _ <close> = func2close(()
308+Y=10
309+end)
310+assert(X == true and Y == nil)
311+return 1,2,3
312+end
313+local function bar
314+()
315+local _ <close> = func2close(()
316+X=false
317+end)
318+X=true
319+return foo()
320+end
321+local a,b,c,d = bar()
322+assert(a == 1 and b == 2 and c == 3 and X == false and Y == 10 and d == nil)
323+local closed = false
324+local function foo
325+()
326+return ()
327+return true
328+end,0,0,func2close(()
329+closed=true
330+end)
331+end
332+local function tail
333+()
334+return closed
335+end
336+local function foo1
337+()
338+for k in foo()
339+do
340+return tail()
341+end
342+end
343+assert(foo1() == false)
344+assert(closed == true)
345+local closed = false
346+local o1 = setmetatable({},{["__close"] = ()
347+closed=true
348+end})
349+local function test
350+()
351+for k,v in next,{},nil,o1
352+do
353+local function f
354+()
355+return k
356+end
357+break
358+end
359+assert(closed)
360+end
361+test()
362+print("testing errors in __close")
363+local function foo
364+()
365+local x <close> = func2close((self,msg)
366+assert(string.find(msg,"@y"))
367+error("@x")
368+end)
369+local x1 <close> = func2close((self,msg)
370+assert(string.find(msg,"@y"))
371+end)
372+local gc <close> = func2close(()
373+collectgarbage()
374+end)
375+local y <close> = func2close((self,msg)
376+assert(string.find(msg,"@z"))
377+error("@y")
378+end)
379+local z <close> = func2close((self,msg)
380+assert(msg == nil)
381+error("@z")
382+end)
383+return 200
384+end
385+local stat,msg = pcall(foo,false)
386+assert(string.find(msg,"@x"))
387+local function foo
388+()
389+local x <close> = func2close((self,msg)
390+assert(debug.getinfo(2).name == "pcall")
391+assert(string.find(msg,"@x1"))
392+end)
393+local x1 <close> = func2close((self,msg)
394+assert(debug.getinfo(2).name == "pcall")
395+assert(string.find(msg,"@y"))
396+error("@x1")
397+end)
398+local gc <close> = func2close(()
399+collectgarbage()
400+end)
401+local y <close> = func2close((self,msg)
402+assert(debug.getinfo(2).name == "pcall")
403+assert(string.find(msg,"@z"))
404+error("@y")
405+end)
406+local first = true
407+local z <close> = func2close((self,msg)
408+assert(debug.getinfo(2).name == "pcall")
409+assert(first and msg == 4)
410+first=false
411+error("@z")
412+end)
413+error(4)
414+end
415+local stat,msg = pcall(foo,true)
416+assert(string.find(msg,"@x1"))
417+local function foo
418+(...)
419+local x1 <close> = func2close((self,msg)
420+assert(string.find(msg,"@X"))
421+error("@Y")
422+end)
423+local x123 <close> = func2close((_,msg)
424+assert(msg == nil)
425+error("@X")
426+end)
427+os.exit(false)
428+end
429+local st,msg = xpcall(foo,debug.traceback)
430+assert(string.match(msg,"^[^ ]* @Y"))
431+local function foo
432+(...)
433+local x123 <close> = func2close(()
434+error("@x123")
435+end)
436+end
437+local st,msg = xpcall(foo,debug.traceback)
438+assert(string.match(msg,"^[^ ]* @x123"))
439+assert(string.find(msg,"in metamethod 'close'"))
440+local function foo
441+()
442+local x <close> = {}
443+os.exit(false)
444+end
445+local stat,msg = pcall(foo)
446+assert(not stat and string.find(msg,"variable 'x' got a non%-closable value"))
447+local function foo
448+()
449+local xyz <close> = setmetatable({},{["__close"] = print})
450+getmetatable(xyz).__close=nil
451+end
452+local stat,msg = pcall(foo)
453+assert(not stat and string.find(msg,"metamethod 'close'"))
454+local function foo
455+()
456+local a1 <close> = func2close((_,msg)
457+assert(string.find(msg,"number value"))
458+error(12)
459+end)
460+local a2 <close> = setmetatable({},{["__close"] = print})
461+local a3 <close> = func2close((_,msg)
462+assert(msg == nil)
463+error(123)
464+end)
465+getmetatable(a2).__close=4
466+end
467+local stat,msg = pcall(foo)
468+assert(not stat and msg == 12)
469+local track = {}
470+local function foo
471+()
472+local x <close> = func2close(()
473+local xx <close> = func2close((_,msg)
474+assert(msg == nil)
475+track[# track + 1]="xx"
476+end)
477+track[# track + 1]="x"
478+end)
479+track[# track + 1]="foo"
480+return 20,30,40
481+end
482+local a,b,c,d = foo()
483+assert(a == 20 and b == 30 and c == 40 and d == nil)
484+assert(track[1] == "foo" and track[2] == "x" and track[3] == "xx")
485+local track = {}
486+local function foo
487+()
488+local x0 <close> = func2close((_,msg)
489+assert(msg == 202)
490+track[# track + 1]="x0"
491+end)
492+local x <close> = func2close(()
493+local xx <close> = func2close((_,msg)
494+assert(msg == 101)
495+track[# track + 1]="xx"
496+error(202)
497+end)
498+track[# track + 1]="x"
499+error(101)
500+end)
501+track[# track + 1]="foo"
502+return 20,30,40
503+end
504+local st,msg = pcall(foo)
505+assert(not st and msg == 202)
506+assert(track[1] == "foo" and track[2] == "x" and track[3] == "xx" and track[4] == "x0")
507+local function checktable
508+(t1,t2)
509+assert(# t1 == # t2)
510+for i = 1, # t1
511+do
512+assert(t1[i] == t2[i])
513+end
514+end
515+local function overflow
516+(n)
517+overflow(n + 1)
518+end
519+local function errorh
520+(m)
521+assert(string.find(m,"stack overflow"))
522+local x <close> = func2close((o)
523+o[1]=10
524+end)
525+return x
526+end
527+local flag =
528+local st,obj =
529+local co = coroutine.wrap(()
530+local y <close> = func2close((obj,msg)
531+assert(msg == nil)
532+obj[1]=100
533+flag=obj
534+end)
535+tracegc.stop()
536+st,obj=xpcall(overflow,errorh,0)
537+tracegc.start()
538+end)
539+co()
540+assert(not st and obj[1] == 10 and flag[1] == 100)
541+if rawget(_G,"T") then
542+collectgarbage()
543+;
544+collectgarbage()
545+;
546+collectgarbage()
547+local function loop
548+(n)
549+if n < 400 then
550+loop(n + 1)
551+end
552+end
553+local o = setmetatable({},{["__close"] = ()
554+loop(0)
555+end})
556+local script = "toclose 2; settop 1; return 1"
557+assert(T.testC(script,o) == script)
558+local function foo
559+()
560+local y <close> = func2close(()
561+T.alloccount()
562+end)
563+local x <close> = setmetatable({},{["__close"] = ()
564+T.alloccount(0)
565+;
566+local x = {}
567+end})
568+error(1e3)
569+end
570+stack(5)
571+local _,msg = pcall(foo)
572+assert(msg == "not enough memory")
573+local closemsg =
574+local close = func2close((self,msg)
575+T.alloccount()
576+closemsg=msg
577+end)
578+local function enter
579+(count)
580+stack(10)
581+T.alloccount(count)
582+closemsg=nil
583+return close
584+end
585+local function test
586+()
587+local x <close> = enter(0)
588+local y = {}
589+end
590+local _,msg = pcall(test)
591+assert(msg == "not enough memory" and closemsg == "not enough memory")
592+local function test
593+()
594+local xxx <close> = func2close((self,msg)
595+assert(msg == "not enough memory")
596+;
597+error(1e3)
598+end)
599+local xx <close> = func2close((self,msg)
600+assert(msg == "not enough memory")
601+;
602+end)
603+local x <close> = enter(0)
604+local y = {}
605+end
606+local _,msg = pcall(test)
607+assert(msg == 1e3 and closemsg == "not enough memory")
608+collectgarbage()
609+local s = string.rep("a",1e4)
610+local m = T.totalmem()
611+collectgarbage("stop")
612+s=string.upper(s)
613+assert(T.totalmem() - m <= 1.1e4)
614+collectgarbage("restart")
615+local lim = 1e4
616+local extra = 2e3
617+local s = string.rep("a",lim)
618+local a = {s,s}
619+collectgarbage()
620+;
621+collectgarbage()
622+local m = T.totalmem()
623+collectgarbage("stop")
624+T.totalmem(m + extra)
625+assert(not pcall(table.concat,a))
626+assert(T.totalmem() - m <= extra)
627+T.totalmem(m + lim + extra)
628+assert(not pcall(table.concat,a))
629+assert(T.totalmem() - m <= extra)
630+T.totalmem(m + 2 * lim + extra)
631+assert(not pcall(table.concat,a))
632+assert(T.totalmem() - m <= extra)
633+T.totalmem(m + 4 * lim + extra)
634+assert(# table.concat(a) == 2 * lim)
635+T.totalmem(0)
636+collectgarbage("restart")
637+print("+")
638+local trace = {}
639+local function hook
640+(event)
641+trace[# trace + 1]=event .. " " .. (debug.getinfo(2).name or "?")
642+end
643+local x = func2close((_,msg)
644+trace[# trace + 1]="x"
645+end)
646+local y = func2close((_,msg)
647+trace[# trace + 1]="y"
648+end)
649+debug.sethook(hook,"r")
650+local t = {T.testC(" toclose 2 # x
651+ pushnum 10
652+ pushint 20
653+ toclose 3 # y
654+ return 2
655+ ",x,y)}
656+debug.sethook()
657+checktable(trace,{"return sethook","y","return ?","x","return ?","return testC"})
658+checktable(t,{10,20})
659+end
660+local trace = {}
661+local function hook
662+(event)
663+trace[# trace + 1]=event .. " " .. debug.getinfo(2).name
664+end
665+local function foo
666+(...)
667+local x <close> = func2close((_,msg)
668+trace[# trace + 1]="x"
669+end)
670+local y <close> = func2close((_,msg)
671+debug.sethook(hook,"r")
672+end)
673+return ...
674+end
675+local t = {foo(10,20,30)}
676+debug.sethook()
677+checktable(t,{10,20,30})
678+checktable(trace,{"return sethook","return close","x","return close","return foo"})
679+print("to-be-closed variables in coroutines")
680+local trace = {}
681+local co = coroutine.wrap(()
682+trace[# trace + 1]="nowX"
683+local x <close> = func2close((_,msg)
684+assert(msg == nil)
685+trace[# trace + 1]="x1"
686+coroutine.yield("x")
687+trace[# trace + 1]="x2"
688+end)
689+return pcall(()
690+local z <close> = func2close((_,msg)
691+assert(msg == nil)
692+trace[# trace + 1]="z1"
693+coroutine.yield("z")
694+trace[# trace + 1]="z2"
695+end)
696+trace[# trace + 1]="nowY"
697+local y <close> = func2close((_,msg)
698+assert(msg == nil)
699+trace[# trace + 1]="y1"
700+coroutine.yield("y")
701+trace[# trace + 1]="y2"
702+end)
703+return 10,20,30
704+end)
705+end)
706+assert(co() == "z")
707+assert(co() == "y")
708+assert(co() == "x")
709+checktable({co()},{true,10,20,30})
710+checktable(trace,{"nowX","z1","z2","nowY","y1","y2","x1","x2"})
711+local extrares =
712+local function check
713+(body,extra, ...)
714+local t = table.pack(...)
715+local co = coroutine.wrap(body)
716+if extra then
717+extrares=co()
718+end
719+local res = table.pack(co())
720+assert(res.n == 2 and res[2] == nil)
721+local res2 = table.pack(co())
722+assert(res2.n == t.n)
723+for i = 1, # t
724+do
725+if t[i] == "x" then
726+assert(res2[i] == res[1])
727+else
728+assert(res2[i] == t[i])
729+end
730+end
731+end
732+local function foo
733+()
734+local x <close> = func2close(coroutine.yield)
735+local extra <close> = func2close((self)
736+assert(self == extrares)
737+coroutine.yield(100)
738+end)
739+extrares=extra
740+return table.unpack({10,x,30})
741+end
742+check(foo,true,10,"x",30)
743+assert(extrares == 100)
744+local function foo
745+()
746+local x <close> = func2close(coroutine.yield)
747+return
748+end
749+check(foo,false)
750+local function foo
751+()
752+local x <close> = func2close(coroutine.yield)
753+local y,z = 20,30
754+return x
755+end
756+check(foo,false,"x")
757+local function foo
758+()
759+local x <close> = func2close(coroutine.yield)
760+local extra <close> = func2close(coroutine.yield)
761+return table.unpack({},1,100)
762+end
763+check(foo,true,table.unpack({},1,100))
764+local co = coroutine.wrap(()
765+local function foo
766+(err)
767+local z <close> = func2close((_,msg)
768+assert(msg == nil or msg == err + 20)
769+coroutine.yield("z")
770+return 100,200
771+end)
772+local y <close> = func2close((_,msg)
773+assert(msg == err or (msg == nil and err == 1))
774+coroutine.yield("y")
775+if err then
776+error(err + 20)
777+end
778+end)
779+local x <close> = func2close((_,msg)
780+assert(msg == err or (msg == nil and err == 1))
781+coroutine.yield("x")
782+return 100,200
783+end)
784+if err == 10 then
785+error(err)
786+else
787+return 10,20
788+end
789+end
790+coroutine.yield(pcall(foo,nil))
791+coroutine.yield(pcall(foo,1))
792+return pcall(foo,10)
793+end)
794+local a,b = co()
795+assert(a == "x" and b == nil)
796+a,b=co()
797+assert(a == "y" and b == nil)
798+a,b=co()
799+assert(a == "z" and b == nil)
800+local a,b,c = co()
801+assert(a and b == 10 and c == 20)
802+local a,b = co()
803+assert(a == "x" and b == nil)
804+a,b=co()
805+assert(a == "y" and b == nil)
806+a,b=co()
807+assert(a == "z" and b == nil)
808+local st,msg = co()
809+assert(not st and msg == 21)
810+local a,b = co()
811+assert(a == "x" and b == nil)
812+a,b=co()
813+assert(a == "y" and b == nil)
814+a,b=co()
815+assert(a == "z" and b == nil)
816+local st,msg = co()
817+assert(not st and msg == 10 + 20)
818+local x = false
819+local y = false
820+local co = coroutine.wrap(()
821+local xv <close> = func2close(()
822+x=true
823+end)
824+local yv <close> = func2close(()
825+y=true
826+end)
827+coroutine.yield(100)
828+coroutine.yield(200)
829+error(23)
830+end)
831+local b = co()
832+assert(b == 100 and not x and not y)
833+b=co()
834+assert(b == 200 and not x and y)
835+local a,b = pcall(co)
836+assert(not a and b == 23 and x and y)
837+local x = 0
838+local co = coroutine.wrap(()
839+local xx <close> = func2close((_,msg)
840+x=x + 1
841+;
842+assert(string.find(msg,"@XXX"))
843+error("@YYY")
844+end)
845+local xv <close> = func2close(()
846+x=x + 1
847+;
848+error("@XXX")
849+end)
850+coroutine.yield(100)
851+error(200)
852+end)
853+assert(co() == 100)
854+;
855+assert(x == 0)
856+local st,msg = pcall(co)
857+;
858+assert(x == 2)
859+assert(not st and string.find(msg,"@YYY"))
860+local x = 0
861+local y = 0
862+co=coroutine.wrap(()
863+local xx <close> = func2close((_,err)
864+y=y + 1
865+;
866+assert(string.find(err,"XXX"))
867+error("YYY")
868+end)
869+local xv <close> = func2close(()
870+x=x + 1
871+;
872+error("XXX")
873+end)
874+coroutine.yield(100)
875+return 200
876+end)
877+assert(co() == 100)
878+;
879+assert(x == 0)
880+local st,msg = pcall(co)
881+assert(x == 1 and y == 1)
882+assert(not st and string.find(msg,"%w+%.%w+:%d+: YYY"))
883+local co =
884+co=coroutine.wrap(()
885+local x <close> = func2close(()
886+os.exit(false)
887+end)
888+co=nil
889+coroutine.yield()
890+end)
891+co()
892+assert(co == nil)
893+collectgarbage()
894+if rawget(_G,"T") then
895+print("to-be-closed variables x coroutines in C")
896+local token = 0
897+local count = 0
898+local f = T.makeCfunc(" toclose 1
899+ toclose 2
900+ return .
901+ ")
902+local obj = func2close((_,msg)
903+count=count + 1
904+token=coroutine.yield(count,token)
905+end)
906+local co = coroutine.wrap(f)
907+local ct,res = co(obj,obj,10,20,30,3)
908+assert(ct == 1 and res == 0)
909+ct,res=co(100)
910+assert(ct == 2 and res == 100)
911+res={co(200)}
912+assert(res[1] == 10 and res[2] == 20 and res[3] == 30 and res[4] == nil)
913+assert(token == 200)
914+local f = T.makeCfunc(" toclose 1
915+ return .
916+ ")
917+local obj = func2close(()
918+local temp =
919+local x <close> = func2close(()
920+coroutine.yield(temp)
921+return 1,2,3
922+end)
923+temp=coroutine.yield("closing obj")
924+return 1,2,3
925+end)
926+local co = coroutine.wrap(f)
927+local res = co(obj,10,30,1)
928+assert(res == "closing obj")
929+res=co("closing x")
930+assert(res == "closing x")
931+res={co()}
932+assert(res[1] == 30 and res[2] == nil)
933+local f = T.makeCfunc(" toclose 1
934+ closeslot 1
935+ ")
936+local obj = func2close(coroutine.yield)
937+local co = coroutine.create(f)
938+local st,msg = coroutine.resume(co,obj)
939+assert(not st and string.find(msg,"attempt to yield across"))
940+local f = T.makeCfunc(" toclose 1
941+ ")
942+local st,msg = pcall(f,obj)
943+assert(not st and string.find(msg,"attempt to yield from outside"))
944+end
945+local numopen = 0
946+local function open
947+(x)
948+numopen=numopen + 1
949+return ()
950+x=x - 1
951+if x > 0 then
952+return x
953+end
954+end,nil,nil,func2close(()
955+numopen=numopen - 1
956+end)
957+end
958+local s = 0
959+for i in open(10)
960+do
961+s=s + i
962+end
963+assert(s == 45 and numopen == 0)
964+local s = 0
965+for i in open(10)
966+do
967+if i < 5 then
968+break
969+end
970+s=s + i
971+end
972+assert(s == 35 and numopen == 0)
973+local s = 0
974+for i in open(10)
975+do
976+for j in open(10)
977+do
978+if i + j < 5 then
979+goto endloop
980+end
981+s=s + i
982+end
983+end
984+::endloop::
985+assert(s == 375 and numopen == 0)
986+print("OK")
987+return 5,f
zod/luau/res/lua/cycled/main.luanew file+447
@@ -0,0 +1,447 @@
1+if _port then
2+return
3+end
4+print("testing stand-alone interpreter")
5+assert(os.execute())
6+local arg = arg or ARG
7+local prog = os.tmpname()
8+local otherprog = os.tmpname()
9+local out = os.tmpname()
10+local progname =
11+local i = 0
12+while arg[i] do
13+i=i - 1
14+progname=arg[i + 1]
15+print("progname: " .. progname)
16+local prepfile = (s,mod,p)
17+mod=mod and "wb" or "w"
18+p=p or prog
19+local f = io.open(p,mod)
20+f:write(s)
21+assert(f:close())
22+end
23+local function getoutput
24+()
25+local f = io.open(out)
26+local t = f:read("a")
27+f:close()
28+assert(os.remove(out))
29+return t
30+end
31+local function checkprogout
32+(s)
33+assert(string.sub(s,- 1) == "
34+")
35+local t = getoutput()
36+for line in string.gmatch(s,".-
37+")
38+do
39+assert(string.find(t,line,1,true))
40+end
41+end
42+local function checkout
43+(s)
44+local t = getoutput()
45+if s ~= t then
46+print(string.format("'%s' - '%s'
47+",s,t))
48+end
49+assert(s == t)
50+return t
51+end
52+local function RUN
53+(p, ...)
54+p=string.gsub(p,"lua",""" .. progname .. """,1)
55+local s = string.format(p,...)
56+assert(os.execute(s))
57+end
58+local function NoRun
59+(msg,p, ...)
60+p=string.gsub(p,"lua",""" .. progname .. """,1)
61+local s = string.format(p,...)
62+s=string.format("%s >%s 2>&1",s,out)
63+assert(not os.execute(s))
64+assert(string.find(getoutput(),msg,1,true))
65+end
66+RUN("lua -v")
67+print(string.format("(temporary program file used in these tests: %s)",prog))
68+prepfile("")
69+RUN("lua - < %s > %s",prog,out)
70+checkout("")
71+prepfile(" print(
72+1, a
73+)
74+")
75+RUN("lua - < %s > %s",prog,out)
76+checkout("1 nil
77+")
78+RUN("echo "print(10)
79+print(2)
80+" | lua > %s",out)
81+checkout("10
82+2
83+")
84+prepfile("")
85+RUN("lua %s > %s",prog,out)
86+checkout("")
87+prepfile("print(3)")
88+RUN("lua %s > %s",prog,out)
89+checkout("3
90+")
91+prepfile("# comment!!
92+print(3)")
93+RUN("lua %s > %s",prog,out)
94+checkout("3
95+")
96+prepfile("�",true)
97+NoRun("unexpected symbol","lua %s",prog)
98+prepfile("�",true)
99+NoRun("unexpected symbol","lua %s",prog)
100+prepfile("�print(3)",true)
101+NoRun("unexpected symbol","lua %s",prog)
102+prepfile("�print(3)",true)
103+NoRun("unexpected symbol","lua %s",prog)
104+RUN("echo "print(arg[1])" | lua - -h > %s",out)
105+checkout("-h
106+")
107+prepfile("print(package.path)")
108+RUN("env LUA_INIT= LUA_PATH=x lua %s > %s",prog,out)
109+checkout("x
110+")
111+RUN("env LUA_INIT= LUA_PATH_5_4=y LUA_PATH=x lua %s > %s",prog,out)
112+checkout("y
113+")
114+prepfile("print(package.cpath)")
115+RUN("env LUA_INIT= LUA_CPATH=xuxu lua %s > %s",prog,out)
116+checkout("xuxu
117+")
118+RUN("env LUA_INIT= LUA_CPATH_5_4=yacc LUA_CPATH=x lua %s > %s",prog,out)
119+checkout("yacc
120+")
121+prepfile("print(X)")
122+RUN("env LUA_INIT="X=tonumber(arg[1])" lua %s 3.2 > %s",prog,out)
123+checkout("3.2
124+")
125+prepfile("print(X)")
126+RUN("env LUA_INIT_5_4="X=10" LUA_INIT="X=3" lua %s > %s",prog,out)
127+checkout("10
128+")
129+prepfile("x = x or 10; print(x); x = x + 1")
130+RUN("env LUA_INIT="@%s" lua %s > %s",prog,prog,out)
131+checkout("10
132+11
133+")
134+NoRun("LUA_INIT:1: msg","env LUA_INIT="error('msg')" lua")
135+local defaultpath,defaultCpath =
136+prepfile("print(package.path, package.cpath)")
137+RUN("env LUA_INIT="error(10)" LUA_PATH=xxx LUA_CPATH=xxx lua -E %s > %s",prog,out)
138+local output = getoutput()
139+defaultpath=string.match(output,"^(.-) ")
140+defaultCpath=string.match(output," (.-)$")
141+RUN("env -i lua %s > %s",prog,out)
142+local out = getoutput()
143+assert(defaultpath == string.match(output,"^(.-) "))
144+assert(defaultCpath == string.match(output," (.-)$"))
145+assert(not string.find(defaultpath,"xxx") and string.find(defaultpath,"lua") and not string.find(defaultCpath,"xxx") and string.find(defaultCpath,"lua"))
146+local function convert
147+(p)
148+prepfile("print(package.path)")
149+RUN("env LUA_PATH="%s" lua %s > %s",p,prog,out)
150+local expected = getoutput()
151+expected=string.sub(expected,1,- 2)
152+if string.find(p,";;") then
153+p=string.gsub(p,";;",";" .. defaultpath .. ";")
154+p=string.gsub(p,"^;","")
155+p=string.gsub(p,";$","")
156+end
157+assert(p == expected)
158+end
159+convert(";")
160+convert(";;")
161+convert("a;;b")
162+convert(";;b")
163+convert("a;;")
164+convert("a;b;;c")
165+prepfile("print(1); a=2; return {x=15}")
166+prepfile(("print(a); print(_G['%s'].x)"):format(prog),false,otherprog)
167+RUN("env LUA_PATH="?;;" lua -l %s -l%s -lstring -l io %s > %s",prog,otherprog,otherprog,out)
168+checkout("1
169+2
170+15
171+2
172+15
173+")
174+prepfile("print(str.upper'alo alo', m.max(10, 20))")
175+RUN("lua -l 'str=string' '-lm=math' -e 'print(m.sin(0))' %s > %s",prog,out)
176+checkout("0.0
177+ALO ALO 20
178+")
179+RUN("env LUA_CPATH='./libs/?.so' lua -l lib2-v2 -e 'print(lib2.id())' > %s",out)
180+checkout("true
181+")
182+local a = " assert(#arg == 3 and arg[1] == 'a' and
183+ arg[2] == 'b' and arg[3] == 'c')
184+ assert(arg[-1] == '--' and arg[-2] == "-e " and arg[-3] == '%s')
185+ assert(arg[4] == undef and arg[-4] == undef)
186+ local a, b, c = ...
187+ assert(... == 'a' and a == 'a' and b == 'b' and c == 'c')
188+"
189+a=string.format(a,progname)
190+prepfile(a)
191+RUN("lua "-e " -- %s a b c",prog)
192+prepfile("assert(arg)")
193+prepfile("assert(arg)",false,otherprog)
194+RUN("env LUA_PATH="?;;" lua -l%s - < %s",prog,otherprog)
195+RUN("echo "print(...)" | lua -e "arg[1] = 100" - > %s",out)
196+checkout("100
197+")
198+NoRun("'arg' is not a table","echo "" | lua -e "arg = 1" -")
199+RUN("echo 10 | lua -e "print=nil" -i > /dev/null 2> %s",out)
200+assert(string.find(getoutput(),"error calling 'print'"))
201+RUN("echo "io.stderr:write(1000)
202+cont" | lua -e "require'debug'.debug()" 2> %s",out)
203+checkout("lua_debug> 1000lua_debug> ")
204+print("testing warnings")
205+RUN("echo "io.stderr:write(1); warn[[XXX]]" | lua 2> %s",out)
206+checkout("1")
207+prepfile("warn("@allow") -- unknown control, ignored
208+warn("@off", "XXX", "@off") -- these are not control messages
209+warn("@off") -- this one is
210+warn("@on", "YYY", "@on") -- not control, but warn is off
211+warn("@off") -- keep it off
212+warn("@on") -- restart warnings
213+warn("", "@on") -- again, no control, real warning
214+warn("@on") -- keep it "started"
215+warn("Z", "Z", "Z") -- common warning
216+")
217+RUN("lua -W %s 2> %s",prog,out)
218+checkout("Lua warning: @offXXX@off
219+Lua warning: @on
220+Lua warning: ZZZ
221+")
222+prepfile("warn("@allow")
223+-- create two objects to be finalized when closing state
224+-- the errors in the finalizers must generate warnings
225+u1 = setmetatable({}, {__gc = function () error("XYZ") end})
226+u2 = setmetatable({}, {__gc = function () error("ZYX") end})
227+")
228+RUN("lua -W %s 2> %s",prog,out)
229+checkprogout("ZYX)
230+XYZ)
231+")
232+prepfile("-- should be called last
233+print("creating 1")
234+setmetatable({}, {__gc = function () print(1) end})
235+
236+print("creating 2")
237+setmetatable({}, {__gc = function ()
238+ print("2")
239+ print("creating 3")
240+ -- this finalizer should not be called, as object will be
241+ -- created after 'lua_close' has been called
242+ setmetatable({}, {__gc = function () print(3) end})
243+ print(collectgarbage()) -- cannot call collector here
244+ os.exit(0, true)
245+end})
246+")
247+RUN("lua -W %s > %s",prog,out)
248+checkout("creating 1
249+creating 2
250+2
251+creating 3
252+nil
253+1
254+")
255+prepfile("print(({...})[30])")
256+RUN("lua %s %s > %s",prog,string.rep(" a",30),out)
257+checkout("a
258+")
259+RUN("lua "-eprint(1)" -ea=3 -e "print(a)" > %s",out)
260+checkout("1
261+3
262+")
263+prepfile("(6*2-6) -- ===
264+a =
265+10
266+print(a)
267+a")
268+RUN("lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s",prog,out)
269+checkprogout("6
270+10
271+10
272+
273+")
274+prepfile("a = [[b
275+c
276+d
277+e]]
278+=a")
279+RUN("lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s",prog,out)
280+checkprogout("b
281+c
282+d
283+e
284+
285+")
286+local prompt = "alo"
287+prepfile(" --
288+a = 2
289+")
290+RUN("lua "-e_PROMPT='%s'" -i < %s > %s",prompt,prog,out)
291+local t = getoutput()
292+assert(string.find(t,prompt .. ".*" .. prompt .. ".*" .. prompt))
293+prepfile(" --
294+a = 2
295+")
296+RUN("lua -i < %s > %s",prog,out)
297+local t = getoutput()
298+prompt="> "
299+assert(string.find(t,prompt .. ".*" .. prompt .. ".*" .. prompt))
300+prompt="local C = 0;_PROMPT=setmetatable({},{__tostring = function () C = C + 1; return C end})"
301+prepfile(" --
302+a = 2
303+")
304+RUN("lua -e "%s" -i < %s > %s",prompt,prog,out)
305+local t = getoutput()
306+assert(string.find(t,"1 --
307+2a = 2
308+3
309+",1,true))
310+prepfile("debug = require "debug"
311+m = {x=0}
312+setmetatable(m, {__tostring = function(x)
313+ return tostring(debug.getinfo(4).currentline + x.x)
314+end})
315+error(m)
316+")
317+NoRun(progname .. ": 6
318+","lua %s",prog)
319+prepfile("error{}")
320+NoRun("error object is a table value","lua %s",prog)
321+local s = " --
322+function f ( x )
323+ local a = [[
324+xuxu
325+]]
326+ local b = "\
327+xuxu\n"
328+ if x == 11 then return 1 + 12 , 2 + 20 end --[[ test multiple returns ]]
329+ return x + 1
330+ --\\
331+end
332+return( f( 100 ) )
333+assert( a == b )
334+do return f( 11 ) end "
335+s=string.gsub(s," ","
336+
337+")
338+prepfile(s)
339+RUN("lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s",prog,out)
340+checkprogout("101
341+13 22
342+
343+")
344+prepfile("#comment in 1st line without \n at the end")
345+RUN("lua %s",prog)
346+prepfile("#comment
347+" .. string.dump(load("print(3)")),true)
348+RUN("lua %s > %s",prog,out)
349+checkout("3
350+")
351+prepfile(string.format("io.output(%q); io.write('alo')",out))
352+RUN("lua %s",prog)
353+checkout("alo")
354+RUN("lua -v -e"print'hello'" > %s",out)
355+t=getoutput()
356+assert(string.find(t,"PUC%-Rio
357+hello"))
358+prepfile("os.exit(nil, true)")
359+RUN("lua %s",prog)
360+prepfile("os.exit(0, true)")
361+RUN("lua %s",prog)
362+prepfile("os.exit(true, true)")
363+RUN("lua %s",prog)
364+prepfile("os.exit(1, true)")
365+NoRun("","lua %s",prog)
366+prepfile("os.exit(false, true)")
367+NoRun("","lua %s",prog)
368+prepfile(" local x <close> = setmetatable({},
369+ {__close = function (self, err)
370+ assert(err == nil)
371+ print("Ok")
372+ end})
373+ local e1 <close> = setmetatable({}, {__close = function () print(120) end})
374+ os.exit(true, true)
375+")
376+RUN("lua %s > %s",prog,out)
377+checkprogout("120
378+Ok
379+")
380+assert(os.remove(prog))
381+assert(os.remove(otherprog))
382+assert(not os.remove(out))
383+NoRun("unrecognized option '-h'","lua -h")
384+NoRun("unrecognized option '---'","lua ---")
385+NoRun("unrecognized option '-Ex'","lua -Ex")
386+NoRun("unrecognized option '-vv'","lua -vv")
387+NoRun("unrecognized option '-iv'","lua -iv")
388+NoRun("'-e' needs argument","lua -e")
389+NoRun("syntax error","lua -e a")
390+NoRun("'-l' needs argument","lua -l")
391+if T then
392+print("testing 'not enough memory' to create a state")
393+NoRun("not enough memory","env MEMLIMIT=100 lua")
394+warn("@store")
395+warn("@123","456","789")
396+assert(_WARN == "@123456789")
397+;
398+_WARN=false
399+warn("zip",""," ","zap")
400+assert(_WARN == "zip zap")
401+;
402+_WARN=false
403+warn("ZIP",""," ","ZAP")
404+assert(_WARN == "ZIP ZAP")
405+;
406+_WARN=false
407+warn("@normal")
408+end
409+local st,msg = pcall(warn)
410+assert(string.find(msg,"string expected"))
411+st,msg=pcall(warn,"SHOULD NOT APPEAR",{})
412+assert(string.find(msg,"string expected"))
413+print("+")
414+print("testing Ctrl C")
415+local function kill
416+(pid)
417+return os.execute(string.format("kill -INT %s 2> /dev/null",pid))
418+end
419+local function runback
420+(luaprg)
421+local shellprg = string.format("%s -e "%s" & echo $!",progname,luaprg)
422+local f = io.popen(shellprg,"r")
423+local pid = f:read()
424+print("(if test fails now, it may leave a Lua script running in background, pid " .. pid .. ")")
425+return f,pid
426+end
427+local f,pid = runback(" pcall(function () print(12); while true do end end); print(42)")
428+assert(f:read() == "12")
429+kill(pid)
430+assert(f:read() == "42")
431+assert(f:close())
432+print("done")
433+local f,pid = runback(" print(15); string.find(string.rep('a', 100000), '.*b')")
434+assert(f:read() == "15")
435+assert(os.execute("sleep 1"))
436+local n = 100
437+for i = 0, 100
438+do
439+if not kill(pid) then
440+n=i
441+break
442+end
443+end
444+assert(f:close())
445+assert(n >= 2)
446+print(string.format("done (with %d kills)",n))
447+print("OK")
zod/luau/res/lua/cycled/math.luanew file+831
@@ -0,0 +1,831 @@
1+print("testing numbers and math lib")
2+local minint <const> = math.mininteger
3+local maxint <const> = math.maxinteger
4+local intbits <const> = math.floor(math.log(maxint,2) + 0.5) + 1
5+assert((1 << intbits) == 0)
6+assert(minint == 1 << (intbits - 1))
7+assert(maxint == minint - 1)
8+local floatbits = 24
9+local p = 2 ^ floatbits
10+while p < p + 1 do
11+p=p * 2
12+floatbits=floatbits + 1
13+local function isNaN
14+(x)
15+return (x ~= x)
16+end
17+assert(isNaN(0 / 0))
18+assert(not isNaN(1 / 0))
19+local x = 2 ^ floatbits
20+assert(x > x - 1 and x == x + 1)
21+print(string.format("%d-bit integers, %d-bit (mantissa) floats",intbits,floatbits))
22+assert(math.type(0) == "integer" and math.type(0) == "float" and not math.type("10"))
23+local function checkerror
24+(msg,f, ...)
25+local s,err = pcall(f,...)
26+assert(not s and string.find(err,msg))
27+end
28+local msgf2i = "number.* has no integer representation"
29+local function eq
30+(a,b,limit)
31+if not limit then
32+if floatbits >= 50 then
33+limit=1e-11
34+else
35+limit=1e-5
36+end
37+end
38+return a == b or math.abs(a - b) <= limit
39+end
40+local function eqT
41+(a,b)
42+return a == b and math.type(a) == math.type(b)
43+end
44+assert(0 == 0 and 0 == 0 and 0 == 0 and 20 == 20 and 0.2 == 0.2)
45+local a,b,c = "2"," 3e0 "," 10 "
46+assert(a + b == 5 and - b == - 3 and b + "2" == 5 and "10" - c == 0)
47+assert(type(a) == "string" and type(b) == "string" and type(c) == "string")
48+assert(a == "2" and b == " 3e0 " and c == " 10 " and - c == - " 10 ")
49+assert(c % a == 0 and a ^ b == 8)
50+a=0
51+assert(a == - a and 0 == - 0)
52+local x = - 1
53+local mz = 0 / x
54+local t = {[0] = 10,20,30,40,50}
55+assert(t[mz] == t[0] and t[- 0] == t[0])
56+local a,b = math.modf(3.5)
57+assert(a == 3 and b == 0.5)
58+a,b=math.modf(- 2.5)
59+assert(a == - 2 and b == - 0.5)
60+a,b=math.modf(- 3e23)
61+assert(a == - 3e23 and b == 0)
62+a,b=math.modf(3e35)
63+assert(a == 3e35 and b == 0)
64+a,b=math.modf(- 1 / 0)
65+assert(a == - 1 / 0 and b == 0)
66+a,b=math.modf(1 / 0)
67+assert(a == 1 / 0 and b == 0)
68+a,b=math.modf(0 / 0)
69+assert(isNaN(a) and isNaN(b))
70+a,b=math.modf(3)
71+assert(eqT(a,3) and eqT(b,0))
72+a,b=math.modf(minint)
73+assert(eqT(a,minint) and eqT(b,0))
74+assert(math.huge > 1e31)
75+assert(- math.huge < - 1e31)
76+assert(minint < minint + 1)
77+assert(maxint - 1 < maxint)
78+assert(0 - minint == minint)
79+assert(minint * minint == 0)
80+assert(maxint * maxint * maxint == maxint)
81+for _,i in pairs({- 16,- 15,- 3,- 2,- 1,0,1,2,3,15})
82+do
83+for _,j in pairs({- 16,- 15,- 3,- 2,- 1,1,2,3,15})
84+do
85+for _,ti in pairs({0,0})
86+do
87+for _,tj in pairs({0,0})
88+do
89+local x = i + ti
90+local y = j + tj
91+assert(i // j == math.floor(i / j))
92+end
93+end
94+end
95+end
96+assert(1 // 0 == 1 / 0)
97+assert(- 1 // 0 == - 1 / 0)
98+assert(eqT(3.5 // 1.5,2))
99+assert(eqT(3.5 // - 1.5,- 3))
100+local x,y =
101+x=1
102+;
103+assert(x // 0 == 1 / 0)
104+x=1
105+;
106+assert(x // 0 == 1 / 0)
107+x=3.5
108+;
109+assert(eqT(x // 1,3))
110+assert(eqT(x // - 1,- 4))
111+x=3.5
112+;
113+y=1.5
114+;
115+assert(eqT(x // y,2))
116+x=3.5
117+;
118+y=- 1.5
119+;
120+assert(eqT(x // y,- 3))
121+assert(maxint // maxint == 1)
122+assert(maxint // 1 == maxint)
123+assert((maxint - 1) // maxint == 0)
124+assert(maxint // (maxint - 1) == 1)
125+assert(minint // minint == 1)
126+assert(minint // minint == 1)
127+assert((minint + 1) // minint == 0)
128+assert(minint // (minint + 1) == 1)
129+assert(minint // 1 == minint)
130+assert(minint // - 1 == - minint)
131+assert(minint // - 2 == 2 ^ (intbits - 2))
132+assert(maxint // - 1 == - maxint)
133+assert(2 ^ - 3 == 1 / 2 ^ 3)
134+assert(eq((- 3) ^ - 3,1 / (- 3) ^ 3))
135+for i = - 3, 3
136+do
137+for j = - 3, 3
138+do
139+if not _port or i ~= 0 or j > 0 then
140+assert(eq(i ^ j,1 / i ^ (- j)))
141+end
142+end
143+end
144+if floatbits < intbits then
145+assert(2 ^ floatbits == (1 << floatbits))
146+assert(2 ^ floatbits - 1 == (1 << floatbits) - 1)
147+assert(2 ^ floatbits - 1 ~= (1 << floatbits))
148+assert(2 ^ floatbits + 1 ~= (1 << floatbits) + 1)
149+else
150+assert(maxint == maxint + 0)
151+assert(maxint - 1 == maxint - 1)
152+assert(minint + 1 == minint + 1)
153+assert(maxint ~= maxint - 1)
154+end
155+assert(maxint + 0 == 2 ^ (intbits - 1) - 1)
156+assert(minint + 0 == minint)
157+assert(minint + 0 == - 2 ^ (intbits - 1))
158+assert(1 < 1.1)
159+;
160+assert(not (1 < 0.9))
161+assert(1 <= 1.1)
162+;
163+assert(not (1 <= 0.9))
164+assert(- 1 < - 0.9)
165+;
166+assert(not (- 1 < - 1.1))
167+assert(1 <= 1.1)
168+;
169+assert(not (- 1 <= - 1.1))
170+assert(- 1 < - 0.9)
171+;
172+assert(not (- 1 < - 1.1))
173+assert(- 1 <= - 0.9)
174+;
175+assert(not (- 1 <= - 1.1))
176+assert(minint <= minint + 0)
177+assert(minint + 0 <= minint)
178+assert(not (minint < minint + 0))
179+assert(not (minint + 0 < minint))
180+assert(maxint < minint * - 1)
181+assert(maxint <= minint * - 1)
182+local fmaxi1 = 2 ^ (intbits - 1)
183+assert(maxint < fmaxi1)
184+assert(maxint <= fmaxi1)
185+assert(not (fmaxi1 <= maxint))
186+assert(minint <= - 2 ^ (intbits - 1))
187+assert(- 2 ^ (intbits - 1) <= minint)
188+if floatbits < intbits then
189+print("testing order (floats cannot represent all integers)")
190+local fmax = 2 ^ floatbits
191+local ifmax = fmax | 0
192+assert(fmax < ifmax + 1)
193+assert(fmax - 1 < ifmax)
194+assert(- (fmax - 1) > - ifmax)
195+assert(not (fmax <= ifmax - 1))
196+assert(- fmax > - (ifmax + 1))
197+assert(not (- fmax >= - (ifmax - 1)))
198+assert(fmax / 2 - 0.5 < ifmax // 2)
199+assert(- (fmax / 2 - 0.5) > - ifmax // 2)
200+assert(maxint < 2 ^ intbits)
201+assert(minint > - 2 ^ intbits)
202+assert(maxint <= 2 ^ intbits)
203+assert(minint >= - 2 ^ intbits)
204+else
205+print("testing order (floats can represent all integers)")
206+assert(maxint < maxint + 1)
207+assert(maxint < maxint + 0.5)
208+assert(maxint - 1 < maxint)
209+assert(maxint - 0.5 < maxint)
210+assert(not (maxint + 0 < maxint))
211+assert(maxint + 0 <= maxint)
212+assert(not (maxint < maxint + 0))
213+assert(maxint + 0 <= maxint)
214+assert(maxint <= maxint + 0)
215+assert(not (maxint + 1 <= maxint))
216+assert(not (maxint + 0.5 <= maxint))
217+assert(not (maxint <= maxint - 1))
218+assert(not (maxint <= maxint - 0.5))
219+assert(minint < minint + 1)
220+assert(minint < minint + 0.5)
221+assert(minint <= minint + 0.5)
222+assert(minint - 1 < minint)
223+assert(minint - 1 <= minint)
224+assert(not (minint + 0 < minint))
225+assert(not (minint + 0.5 < minint))
226+assert(not (minint < minint + 0))
227+assert(minint + 0 <= minint)
228+assert(minint <= minint + 0)
229+assert(not (minint + 1 <= minint))
230+assert(not (minint + 0.5 <= minint))
231+assert(not (minint <= minint - 1))
232+end
233+local NaN <const> = 0 / 0
234+assert(not (NaN < 0))
235+assert(not (NaN > minint))
236+assert(not (NaN <= - 9))
237+assert(not (NaN <= maxint))
238+assert(not (NaN < maxint))
239+assert(not (minint <= NaN))
240+assert(not (minint < NaN))
241+assert(not (4 <= NaN))
242+assert(not (4 < NaN))
243+local function checkcompt
244+(msg,code)
245+checkerror(msg,assert(load(code)))
246+end
247+checkcompt("divide by zero","return 2 // 0")
248+checkcompt(msgf2i,"return 2.3 >> 0")
249+checkcompt(msgf2i,("return 2.0^%d & 1"):format(intbits - 1))
250+checkcompt("field 'huge'","return math.huge << 1")
251+checkcompt(msgf2i,("return 1 | 2.0^%d"):format(intbits - 1))
252+checkcompt(msgf2i,"return 2.3 ~ 0.0")
253+local function f2i
254+(x)
255+return x | x
256+end
257+checkerror(msgf2i,f2i,math.huge)
258+checkerror(msgf2i,f2i,- math.huge)
259+checkerror(msgf2i,f2i,0 / 0)
260+if floatbits < intbits then
261+assert(maxint + 1 == maxint + 0)
262+assert(minint - 1 == minint + 0)
263+checkerror(msgf2i,f2i,maxint + 0)
264+assert(f2i(2 ^ (intbits - 2)) == 1 << (intbits - 2))
265+assert(f2i(- 2 ^ (intbits - 2)) == - (1 << (intbits - 2)))
266+assert((2 ^ (floatbits - 1) + 1) // 1 == (1 << (floatbits - 1)) + 1)
267+local mf = maxint - (1 << (floatbits - intbits)) + 1
268+assert(f2i(mf + 0) == mf)
269+mf=mf + 1
270+assert(f2i(mf + 0) ~= mf)
271+else
272+assert(maxint + 1 > maxint)
273+assert(minint - 1 < minint)
274+assert(f2i(maxint + 0) == maxint)
275+checkerror("no integer rep",f2i,maxint + 1)
276+checkerror("no integer rep",f2i,minint - 1)
277+end
278+assert(f2i(minint + 0) == minint)
279+assert("2" + 1 == 3)
280+assert("2 " + 1 == 3)
281+assert(" -2 " + 1 == - 1)
282+assert(" -0xa " + 1 == - 9)
283+assert(eqT(tonumber(tostring(maxint)),maxint))
284+assert(eqT(tonumber(tostring(minint)),minint))
285+local function incd
286+(n)
287+local s = string.format("%d",n)
288+s=string.gsub(s,"%d$",(d)
289+assert(d ~= "9")
290+return string.char(string.byte(d) + 1)
291+end)
292+return s
293+end
294+assert(eqT(tonumber(incd(maxint)),maxint + 1))
295+assert(eqT(tonumber(incd(minint)),minint - 1))
296+assert(eqT(tonumber("1" .. string.rep("0",30)),1e30))
297+assert(eqT(tonumber("-1" .. string.rep("0",30)),- 1e30))
298+assert(eqT(tonumber("0x1" .. string.rep("0",30)),0))
299+assert(minint == load("return " .. minint)())
300+assert(eqT(maxint,load("return " .. maxint)()))
301+assert(eqT(1e22,1e22))
302+assert(eqT(- 1e22,- 1e22))
303+assert(tonumber(3.4) == 3.4)
304+assert(eqT(tonumber(3),3))
305+assert(eqT(tonumber(maxint),maxint) and eqT(tonumber(minint),minint))
306+assert(tonumber(1 / 0) == 1 / 0)
307+assert(tonumber("0") == 0)
308+assert(not tonumber(""))
309+assert(not tonumber(" "))
310+assert(not tonumber("-"))
311+assert(not tonumber(" -0x "))
312+assert(not tonumber({}))
313+assert(tonumber("+0.01") == 1 / 100 and tonumber("+.01") == 0.01 and tonumber(".01") == 0.01 and tonumber("-1.") == - 1 and tonumber("+1.") == 1)
314+assert(not tonumber("+ 0.01") and not tonumber("+.e1") and not tonumber("1e") and not tonumber("1.0e+") and not tonumber("."))
315+assert(tonumber("-012") == - 10 - 2)
316+assert(tonumber("-1.2e2") == - - - 120)
317+assert(tonumber("0xffffffffffff") == (1 << (4 * 12)) - 1)
318+assert(tonumber("0x" .. string.rep("f",(intbits // 4))) == - 1)
319+assert(tonumber("-0x" .. string.rep("f",(intbits // 4))) == 1)
320+assert(tonumber(" 001010 ",2) == 10)
321+assert(tonumber(" 001010 ",10) == 1010)
322+assert(tonumber(" -1010 ",2) == - 10)
323+assert(tonumber("10",36) == 36)
324+assert(tonumber(" -10 ",36) == - 36)
325+assert(tonumber(" +1Z ",36) == 36 + 35)
326+assert(tonumber(" -1z ",36) == - 36 + - 35)
327+assert(tonumber("-fFfa",16) == - (10 + (16 * (15 + (16 * (15 + (16 * 15)))))))
328+assert(tonumber(string.rep("1",(intbits - 2)),2) + 1 == 2 ^ (intbits - 2))
329+assert(tonumber("ffffFFFF",16) + 1 == (1 << 32))
330+assert(tonumber("0ffffFFFF",16) + 1 == (1 << 32))
331+assert(tonumber("-0ffffffFFFF",16) - 1 == - (1 << 40))
332+for i = 2, 36
333+do
334+local i2 = i * i
335+local i10 = i2 * i2 * i2 * i2 * i2
336+assert(tonumber(" 10000000000 ",i) == i10)
337+end
338+if not _soft then
339+assert(tonumber("0x" .. string.rep("f",13) .. ".0") == 2 ^ (4 * 13) - 1)
340+assert(tonumber("0x" .. string.rep("f",150) .. ".0") == 2 ^ (4 * 150) - 1)
341+assert(tonumber("0x" .. string.rep("f",300) .. ".0") == 2 ^ (4 * 300) - 1)
342+assert(tonumber("0x" .. string.rep("f",500) .. ".0") == 2 ^ (4 * 500) - 1)
343+assert(tonumber("0x3." .. string.rep("0",1e3)) == 3)
344+assert(tonumber("0x" .. string.rep("0",1e3) .. "a") == 10)
345+assert(tonumber("0x0." .. string.rep("0",13) .. "1") == 2 ^ (- 4 * 14))
346+assert(tonumber("0x0." .. string.rep("0",150) .. "1") == 2 ^ (- 4 * 151))
347+assert(tonumber("0x0." .. string.rep("0",300) .. "1") == 2 ^ (- 4 * 301))
348+assert(tonumber("0x0." .. string.rep("0",500) .. "1") == 2 ^ (- 4 * 501))
349+assert(tonumber("0xe03" .. string.rep("0",1e3) .. "p-4000") == 3587)
350+assert(tonumber("0x." .. string.rep("0",1e3) .. "74p4004") == 7.25)
351+end
352+local function f
353+(...)
354+if select("#",...) == 1 then
355+return (...)
356+else
357+return "***"
358+end
359+end
360+assert(not f(tonumber("fFfa",15)))
361+assert(not f(tonumber("099",8)))
362+assert(not f(tonumber("1",2)))
363+assert(not f(tonumber("",8)))
364+assert(not f(tonumber(" ",9)))
365+assert(not f(tonumber(" ",9)))
366+assert(not f(tonumber("0xf",10)))
367+assert(not f(tonumber("inf")))
368+assert(not f(tonumber(" INF ")))
369+assert(not f(tonumber("Nan")))
370+assert(not f(tonumber("nan")))
371+assert(not f(tonumber(" ")))
372+assert(not f(tonumber("")))
373+assert(not f(tonumber("1 a")))
374+assert(not f(tonumber("1 a",2)))
375+assert(not f(tonumber("1")))
376+assert(not f(tonumber("1 ")))
377+assert(not f(tonumber("1 ")))
378+assert(not f(tonumber("e1")))
379+assert(not f(tonumber("e 1")))
380+assert(not f(tonumber(" 3.4.5 ")))
381+assert(not tonumber("0x"))
382+assert(not tonumber("x"))
383+assert(not tonumber("x3"))
384+assert(not tonumber("0x3.3.3"))
385+assert(not tonumber("00x2"))
386+assert(not tonumber("0x 2"))
387+assert(not tonumber("0 x2"))
388+assert(not tonumber("23x"))
389+assert(not tonumber("- 0xaa"))
390+assert(not tonumber("-0xaaP "))
391+assert(not tonumber("0x0.51p"))
392+assert(not tonumber("0x5p+-2"))
393+assert(16 == 16 and 4095 == 2 ^ 12 - 1 and 251 == 251)
394+assert(0 == 0 and 0 == 0)
395+assert(4294967295 == (1 << 32) - 1)
396+assert(tonumber("+0x2") == 2)
397+assert(tonumber("-0xaA") == - 170)
398+assert(tonumber("-0xffFFFfff") == - (1 << 32) + 1)
399+assert(0 == 0 and 14 + 1 == 15 and 14 - 1 == 13)
400+assert(tonumber(" 0x2.5 ") == 37 / 16)
401+assert(tonumber(" -0x2.5 ") == - 37 / 16)
402+assert(tonumber(" +0x0.51p+8 ") == 81)
403+assert(0.9999999997671694 == 1 - "0x.00000001")
404+assert("0xA.a" + 0 == 10 + 10 / 16)
405+assert(170 == 170)
406+assert(1 == 1)
407+assert(1.0625 == "0x1." + "+0x.1")
408+assert(11259375 == 11259375)
409+assert(1.1 == 1 + 0.1)
410+assert(100 == 100 and 0.01 == 0.01)
411+assert(1111111111 - 1111111110 == 1)
412+assert(1.1 == "1." + ".1")
413+assert(tonumber("1111111111") - tonumber("1111111110") == tonumber(" +0.001e+3
414+ "))
415+assert(1e-31 > 9e-32 and 9e29 < 1e30)
416+assert(0.123456 > 0.123455)
417+assert(tonumber("+1.23E18") == 1.23 * 10 ^ 18)
418+assert(not (1 < 1) and (1 < 2) and not (2 < 1))
419+assert(not ("a" < "a") and ("a" < "b") and not ("b" < "a"))
420+assert((1 <= 1) and (1 <= 2) and not (2 <= 1))
421+assert(("a" <= "a") and ("a" <= "b") and not ("b" <= "a"))
422+assert(not (1 > 1) and not (1 > 2) and (2 > 1))
423+assert(not ("a" > "a") and not ("a" > "b") and ("b" > "a"))
424+assert((1 >= 1) and not (1 >= 2) and (2 >= 1))
425+assert(("a" >= "a") and not ("a" >= "b") and ("b" >= "a"))
426+assert(1.3 < 1.4 and 1.3 <= 1.4 and not (1.3 < 1.3) and 1.3 <= 1.3)
427+assert(eqT(- 4 % 3,2))
428+assert(eqT(4 % - 3,- 2))
429+assert(eqT(- 4 % 3,2))
430+assert(eqT(4 % - 3,- 2))
431+assert(eqT(4 % - 5,- 1))
432+assert(eqT(4 % - 5,- 1))
433+assert(eqT(4 % 5,4))
434+assert(eqT(4 % 5,4))
435+assert(eqT(- 4 % - 5,- 4))
436+assert(eqT(- 4 % - 5,- 4))
437+assert(eqT(- 4 % 5,1))
438+assert(eqT(- 4 % 5,1))
439+assert(eqT(4.25 % 4,0.25))
440+assert(eqT(10 % 2,0))
441+assert(eqT(- 10 % 2,0))
442+assert(eqT(- 10 % - 2,0))
443+assert(math.pi - math.pi % 1 == 3)
444+assert(math.pi - math.pi % 1e-3 == 3.141)
445+local i,j = 0,2e4
446+while i < j do
447+local m = (i + j) // 2
448+if 10 ^ - m > 0 then
449+i=m + 1
450+else
451+j=m
452+end
453+local b = 10 ^ - (i - (i // 10))
454+assert(b > 0 and b * b == 0)
455+local delta = b / 1e3
456+assert(eq((2.1 * b) % (2 * b),(0.1 * b),delta))
457+assert(eq((- 2.1 * b) % (2 * b),(2 * b) - (0.1 * b),delta))
458+assert(eq((2.1 * b) % (- 2 * b),(0.1 * b) - (2 * b),delta))
459+assert(eq((- 2.1 * b) % (- 2 * b),(- 0.1 * b),delta))
460+for i = - 10, 10
461+do
462+for j = - 10, 10
463+do
464+if j ~= 0 then
465+assert((i + 0) % j == i % j)
466+end
467+end
468+end
469+for i = 0, 10
470+do
471+for j = - 10, 10
472+do
473+if j ~= 0 then
474+assert((2 ^ i) % j == (1 << i) % j)
475+end
476+end
477+end
478+local i = 10
479+while (1 << i) > 0 do
480+assert((1 << i) % 3 == i % 2 + 1)
481+i=i + 1
482+i=10
483+while 2 ^ i < math.huge do
484+assert(2 ^ i % 3 == i % 2 + 1)
485+i=i + 1
486+assert(eqT(minint % minint,0))
487+assert(eqT(maxint % maxint,0))
488+assert((minint + 1) % minint == minint + 1)
489+assert((maxint - 1) % maxint == maxint - 1)
490+assert(minint % maxint == maxint - 1)
491+assert(minint % - 1 == 0)
492+assert(minint % - 2 == 0)
493+assert(maxint % - 2 == - 1)
494+if not _port then
495+local function anan
496+(x)
497+assert(isNaN(x))
498+end
499+anan(0 % 0)
500+anan(1.3 % 0)
501+anan(math.huge % 1)
502+anan(math.huge % 1e30)
503+anan(- math.huge % 1e30)
504+anan(- math.huge % - 1e30)
505+assert(1 % math.huge == 1)
506+assert(1e30 % math.huge == 1e30)
507+assert(1e30 % - math.huge == - math.huge)
508+assert(- 1 % math.huge == math.huge)
509+assert(- 1 % - math.huge == - 1)
510+end
511+assert(math.ult(3,4))
512+assert(not math.ult(4,4))
513+assert(math.ult(- 2,- 1))
514+assert(math.ult(2,- 1))
515+assert(not math.ult(- 2,- 2))
516+assert(math.ult(maxint,minint))
517+assert(not math.ult(minint,maxint))
518+assert(eq(math.sin(- 9.8) ^ 2 + math.cos(- 9.8) ^ 2,1))
519+assert(eq(math.tan(math.pi / 4),1))
520+assert(eq(math.sin(math.pi / 2),1) and eq(math.cos(math.pi / 2),0))
521+assert(eq(math.atan(1),math.pi / 4) and eq(math.acos(0),math.pi / 2) and eq(math.asin(1),math.pi / 2))
522+assert(eq(math.deg(math.pi / 2),90) and eq(math.rad(90),math.pi / 2))
523+assert(math.abs(- 10.43) == 10.43)
524+assert(eqT(math.abs(minint),minint))
525+assert(eqT(math.abs(maxint),maxint))
526+assert(eqT(math.abs(- maxint),maxint))
527+assert(eq(math.atan(1,0),math.pi / 2))
528+assert(math.fmod(10,3) == 1)
529+assert(eq(math.sqrt(10) ^ 2,10))
530+assert(eq(math.log(2,10),math.log(2) / math.log(10)))
531+assert(eq(math.log(2,2),1))
532+assert(eq(math.log(9,3),2))
533+assert(eq(math.exp(0),1))
534+assert(eq(math.sin(10),math.sin(10 % (2 * math.pi))))
535+assert(tonumber(" 1.3e-2 ") == 0.013)
536+assert(tonumber(" -1.00000000000001 ") == - 1.00000000000001)
537+assert(8388609 + - 8388609 == 0)
538+assert(8388608 + - 8388608 == 0)
539+assert(8388607 + - 8388607 == 0)
540+assert(eqT(math.floor(3.4),3))
541+assert(eqT(math.ceil(3.4),4))
542+assert(eqT(math.floor(- 3.4),- 4))
543+assert(eqT(math.ceil(- 3.4),- 3))
544+assert(eqT(math.floor(maxint),maxint))
545+assert(eqT(math.ceil(maxint),maxint))
546+assert(eqT(math.floor(minint),minint))
547+assert(eqT(math.floor(minint + 0),minint))
548+assert(eqT(math.ceil(minint),minint))
549+assert(eqT(math.ceil(minint + 0),minint))
550+assert(math.floor(1e50) == 1e50)
551+assert(math.ceil(1e50) == 1e50)
552+assert(math.floor(- 1e50) == - 1e50)
553+assert(math.ceil(- 1e50) == - 1e50)
554+for _,p in pairs({31,32,63,64})
555+do
556+assert(math.floor(2 ^ p) == 2 ^ p)
557+assert(math.floor(2 ^ p + 0.5) == 2 ^ p)
558+assert(math.ceil(2 ^ p) == 2 ^ p)
559+assert(math.ceil(2 ^ p - 0.5) == 2 ^ p)
560+end
561+checkerror("number expected",math.floor,{})
562+checkerror("number expected",math.ceil,print)
563+assert(eqT(math.tointeger(minint),minint))
564+assert(eqT(math.tointeger(minint .. ""),minint))
565+assert(eqT(math.tointeger(maxint),maxint))
566+assert(eqT(math.tointeger(maxint .. ""),maxint))
567+assert(eqT(math.tointeger(minint + 0),minint))
568+assert(not math.tointeger(0 - minint))
569+assert(not math.tointeger(math.pi))
570+assert(not math.tointeger(- math.pi))
571+assert(math.floor(math.huge) == math.huge)
572+assert(math.ceil(math.huge) == math.huge)
573+assert(not math.tointeger(math.huge))
574+assert(math.floor(- math.huge) == - math.huge)
575+assert(math.ceil(- math.huge) == - math.huge)
576+assert(not math.tointeger(- math.huge))
577+assert(math.tointeger("34.0") == 34)
578+assert(not math.tointeger("34.3"))
579+assert(not math.tointeger({}))
580+assert(not math.tointeger(0 / 0))
581+for i = - 6, 6
582+do
583+for j = - 6, 6
584+do
585+if j ~= 0 then
586+local mi = math.fmod(i,j)
587+local mf = math.fmod(i + 0,j)
588+assert(mi == mf)
589+assert(math.type(mi) == "integer" and math.type(mf) == "float")
590+if (i >= 0 and j >= 0) or (i <= 0 and j <= 0) or mi == 0 then
591+assert(eqT(mi,i % j))
592+end
593+end
594+end
595+end
596+assert(eqT(math.fmod(minint,minint),0))
597+assert(eqT(math.fmod(maxint,maxint),0))
598+assert(eqT(math.fmod(minint + 1,minint),minint + 1))
599+assert(eqT(math.fmod(maxint - 1,maxint),maxint - 1))
600+checkerror("zero",math.fmod,3,0)
601+checkerror("value expected",math.max)
602+checkerror("value expected",math.min)
603+assert(eqT(math.max(3),3))
604+assert(eqT(math.max(3,5,9,1),9))
605+assert(math.max(maxint,1e61) == 1e61)
606+assert(eqT(math.max(minint,minint + 1),minint + 1))
607+assert(eqT(math.min(3),3))
608+assert(eqT(math.min(3,5,9,1),1))
609+assert(math.min(3.2,5.9,- 9.2,1.1) == - 9.2)
610+assert(math.min(1.9,1.7,1.72) == 1.7)
611+assert(math.min(- 1e61,minint) == - 1e61)
612+assert(eqT(math.min(maxint,maxint - 1),maxint - 1))
613+assert(eqT(math.min(maxint - 2,maxint,maxint - 1),maxint - 2))
614+local a,b = "10","20"
615+assert(a * b == 200 and a + b == 30 and a - b == - 10 and a / b == 0.5 and - b == - 20)
616+assert(a == "10" and b == "20")
617+print("testing -0 and NaN")
618+local mz <const> = - 0
619+local z <const> = 0
620+assert(mz == z)
621+assert(1 / mz < 0 and 0 < 1 / z)
622+local a = {[mz] = 1}
623+assert(a[z] == 1 and a[mz] == 1)
624+a[z]=2
625+assert(a[z] == 2 and a[mz] == 2)
626+local inf = math.huge * 2 + 1
627+local mz <const> = - 1 / inf
628+local z <const> = 1 / inf
629+assert(mz == z)
630+assert(1 / mz < 0 and 0 < 1 / z)
631+local NaN <const> = inf - inf
632+assert(NaN ~= NaN)
633+assert(not (NaN < NaN))
634+assert(not (NaN <= NaN))
635+assert(not (NaN > NaN))
636+assert(not (NaN >= NaN))
637+assert(not (0 < NaN) and not (NaN < 0))
638+local NaN1 <const> = 0 / 0
639+assert(NaN ~= NaN1 and not (NaN <= NaN1) and not (NaN1 <= NaN))
640+local a = {}
641+assert(not pcall(rawset,a,NaN,1))
642+assert(a[NaN] == undef)
643+a[1]=1
644+assert(not pcall(rawset,a,NaN,1))
645+assert(a[NaN] == undef)
646+local a1,a2,a3,a4,a5 = 0,0,"",0,""
647+assert(a1 == a2 and a2 == a4 and a1 ~= a3)
648+assert(a3 == a5)
649+print("testing 'math.random'")
650+local random,max,min = math.random,math.max,math.min
651+local function testnear
652+(val,ref,tol)
653+return (math.abs(val - ref) < ref * tol)
654+end
655+local h <const> = 2054176933
656+local l <const> = 2737031638
657+math.randomseed(1007)
658+local res = (h << 32 | l) & ~ (~ 0 << intbits)
659+assert(random(0) == res)
660+math.randomseed(1007,0)
661+local res =
662+if floatbits <= 32 then
663+res=(h >> (32 - floatbits)) % 2 ^ 32
664+else
665+res=(h % 2 ^ 32) * 2 ^ (floatbits - 32) + ((l >> (64 - floatbits)) % 2 ^ 32)
666+end
667+local rand = random()
668+assert(eq(rand,0.4782753376376966,2 ^ - floatbits))
669+assert(rand * 2 ^ floatbits == res)
670+local x,y = math.randomseed()
671+local res = math.random(0)
672+x,y=math.randomseed(x,y)
673+assert(math.random(0) == res)
674+math.randomseed(x,y)
675+assert(math.random(0) == res)
676+print(string.format("random seeds: %d, %d",x,y))
677+local randbits = math.min(floatbits,64)
678+local mult = 2 ^ randbits
679+local counts = {}
680+for i = 1, randbits
681+do
682+counts[i]=0
683+end
684+local up = - math.huge
685+local low = math.huge
686+local rounds = 100 * randbits
687+local totalrounds = 0
688+::doagain::
689+for i = 0, rounds
690+do
691+local t = random()
692+assert(0 <= t and t < 1)
693+up=max(up,t)
694+low=min(low,t)
695+assert(t * mult % 1 == 0)
696+local bit = i % randbits
697+if (t * 2 ^ bit) % 1 >= 0.5 then
698+counts[bit + 1]=counts[bit + 1] + 1
699+end
700+end
701+totalrounds=totalrounds + rounds
702+if not (eq(up,1,1e-3) and eq(low,0,1e-3)) then
703+goto doagain
704+end
705+local expected = (totalrounds / randbits / 2)
706+for i = 1, randbits
707+do
708+if not testnear(counts[i],expected,0.1) then
709+goto doagain
710+end
711+end
712+print(string.format("float random range in %d calls: [%f, %f]",totalrounds,low,up))
713+local up = 0
714+local low = 0
715+local counts = {}
716+for i = 1, intbits
717+do
718+counts[i]=0
719+end
720+local rounds = 100 * intbits
721+local totalrounds = 0
722+::doagain::
723+for i = 0, rounds
724+do
725+local t = random(0)
726+up=max(up,t)
727+low=min(low,t)
728+local bit = i % intbits
729+counts[bit + 1]=counts[bit + 1] + ((t >> bit) & 1)
730+end
731+totalrounds=totalrounds + rounds
732+local lim = maxint >> 10
733+if not (maxint - up < lim and low - minint < lim) then
734+goto doagain
735+end
736+local expected = (totalrounds / intbits / 2)
737+for i = 1, intbits
738+do
739+if not testnear(counts[i],expected,0.1) then
740+goto doagain
741+end
742+end
743+print(string.format("integer random range in %d calls: [minint + %.0fppm, maxint - %.0fppm]",totalrounds,(minint - low) / minint * 1e6,(maxint - up) / maxint * 1e6))
744+local count = {0,0,0,0,0,0}
745+local rep = 200
746+local totalrep = 0
747+::doagain::
748+for i = 1, rep * 6
749+do
750+local r = random(6)
751+count[r]=count[r] + 1
752+end
753+totalrep=totalrep + rep
754+for i = 1, 6
755+do
756+if not testnear(count[i],totalrep,0.05) then
757+goto doagain
758+end
759+end
760+local function aux
761+(x1,x2)
762+local mark = {}
763+;
764+local count = 0
765+while true do
766+local t = random(x1,x2)
767+assert(x1 <= t and t <= x2)
768+if not mark[t] then
769+mark[t]=true
770+count=count + 1
771+if count == x2 - x1 + 1 then
772+goto ok
773+end
774+end
775+::ok::
776+end
777+aux(- 10,0)
778+aux(1,6)
779+aux(1,2)
780+aux(1,13)
781+aux(1,31)
782+aux(1,32)
783+aux(1,33)
784+aux(- 10,10)
785+aux(- 10,- 10)
786+aux(minint,minint)
787+aux(maxint,maxint)
788+aux(minint,minint + 9)
789+aux(maxint - 3,maxint)
790+local function aux
791+(p1,p2)
792+local max = minint
793+local min = maxint
794+local n = 100
795+local mark = {}
796+;
797+local count = 0
798+::doagain::
799+for _ = 1, n
800+do
801+local t = random(p1,p2)
802+if not mark[t] then
803+assert(p1 <= t and t <= p2)
804+max=math.max(max,t)
805+min=math.min(min,t)
806+mark[t]=true
807+count=count + 1
808+end
809+end
810+if not (count >= n * 0.8) then
811+goto doagain
812+end
813+local diff = (p2 - p1) >> 4
814+if not (min < p1 + diff and max > p2 - diff) then
815+goto doagain
816+end
817+end
818+aux(0,maxint)
819+aux(1,maxint)
820+aux(3,maxint // 3)
821+aux(minint,- 1)
822+aux(minint // 2,maxint // 2)
823+aux(minint,maxint)
824+aux(minint + 1,maxint)
825+aux(minint,maxint - 1)
826+aux(0,1 << (intbits - 5))
827+assert(not pcall(random,1,2,3))
828+assert(not pcall(random,minint + 1,minint))
829+assert(not pcall(random,maxint,maxint - 1))
830+assert(not pcall(random,maxint,minint))
831+print("OK")
zod/luau/res/lua/cycled/nextvar.luanew file+1024
@@ -0,0 +1,1024 @@
1+print("testing tables, next, and for")
2+local function checkerror
3+(msg,f, ...)
4+local s,err = pcall(f,...)
5+assert(not s and string.find(err,msg))
6+end
7+local function check
8+(t,na,nh)
9+if not T then
10+return
11+end
12+local a,h = T.querytab(t)
13+if a ~= na or h ~= nh then
14+print(na,nh,a,h)
15+assert(nil)
16+end
17+end
18+local a = {}
19+for i = 1, 100
20+do
21+a[i .. "+"]=true
22+end
23+for i = 1, 100
24+do
25+a[i .. "+"]=undef
26+end
27+for i = 1, 100
28+do
29+a[i]=true
30+assert(# a == i)
31+end
32+local a = {}
33+for i = 1, 100
34+do
35+a[i]=i
36+end
37+check(a,128,0)
38+for i = 5, 95
39+do
40+a[i]=nil
41+end
42+check(a,128,0)
43+a.x=1
44+check(a,4,8)
45+for i = 1, 4
46+do
47+assert(a[i] == i)
48+end
49+for i = 5, 95
50+do
51+assert(a[i] == nil)
52+end
53+for i = 96, 100
54+do
55+assert(a[i] == i)
56+end
57+assert(a.x == 1)
58+local x = 0
59+for k,v in ipairs({10,20,30,["x"] = 12})
60+do
61+x=x + 1
62+assert(k == x and v == x * 10)
63+end
64+for _ in ipairs({["x"] = 12,["y"] = 24})
65+do
66+assert(nil)
67+end
68+x=false
69+local i = 0
70+for k,v in ipairs({true,false,true,false})
71+do
72+i=i + 1
73+x=not x
74+assert(x == v)
75+end
76+assert(i == 4)
77+assert(type(ipairs({})) == "function" and ipairs({}) == ipairs({}))
78+local f = ipairs({})
79+local k,v = f({[math.mininteger] = 10},math.maxinteger)
80+assert(k == math.mininteger and v == 10)
81+k,v=f({[math.mininteger] = 10},k)
82+assert(k == nil)
83+if not T then
84+(Message or print)("
85+ >>> testC not active: skipping tests for table sizes <<<
86+")
87+else
88+local function mp2
89+(n)
90+local mp = 2 ^ math.ceil(math.log(n,2))
91+assert(n == 0 or (mp / 2 < n and n <= mp))
92+return mp
93+end
94+local s = 0
95+for _ in pairs(math)
96+do
97+s=s + 1
98+end
99+check(math,0,mp2(s))
100+local sizes = {0,1,2,3,4,5,7,8,9,15,16,17,30,31,32,33,34,254,255,256,500,1e3}
101+for _,sa in ipairs(sizes)
102+do
103+local arr = {"return {"}
104+for i = 1, sa
105+do
106+arr[1 + i]="1,"
107+end
108+for _,sh in ipairs(sizes)
109+do
110+for j = 1, sh
111+do
112+arr[1 + sa + j]=string.format("k%x=%d,",j,j)
113+end
114+arr[1 + sa + sh + 1]="}"
115+local prog = table.concat(arr)
116+local f = assert(load(prog))
117+collectgarbage("stop")
118+f()
119+if sa == 0 or sh == 0 then
120+T.alloccount(2)
121+;
122+else
123+T.alloccount(3)
124+;
125+end
126+local t = f()
127+T.alloccount()
128+;
129+collectgarbage("restart")
130+assert(# t == sa)
131+check(t,sa,mp2(sh))
132+end
133+end
134+local a = {}
135+for i = 1, sizes[# sizes]
136+do
137+a[i]=i
138+end
139+for k in ipairs(sizes)
140+do
141+local t = {table.unpack(a,1,k)}
142+assert(# t == k)
143+check(t,k,0)
144+t={1,2,3,table.unpack(a,1,k)}
145+check(t,k + 3,0)
146+assert(# t == k + 3)
147+end
148+local lim = 130
149+local a = {}
150+;
151+a[2]=1
152+;
153+check(a,0,1)
154+a={}
155+;
156+a[0]=1
157+;
158+check(a,0,1)
159+;
160+a[2]=1
161+;
162+check(a,0,2)
163+a={}
164+;
165+a[0]=1
166+;
167+a[1]=1
168+;
169+check(a,1,1)
170+a={}
171+for i = 1, lim
172+do
173+a[i]=1
174+assert(# a == i)
175+check(a,mp2(i),0)
176+end
177+a={}
178+for i = 1, lim
179+do
180+a["a" .. i]=1
181+assert(# a == 0)
182+check(a,0,mp2(i))
183+end
184+a={}
185+for i = 1, 16
186+do
187+a[i]=i
188+end
189+check(a,16,0)
190+for i = 1, 11
191+do
192+a[i]=undef
193+end
194+for i = 30, 50
195+do
196+a[i]=true
197+;
198+a[i]=undef
199+end
200+check(a,0,8)
201+a[10]=1
202+for i = 30, 50
203+do
204+a[i]=true
205+;
206+a[i]=undef
207+end
208+check(a,0,8)
209+for i = 1, 14
210+do
211+a[i]=true
212+;
213+a[i]=undef
214+end
215+for i = 18, 50
216+do
217+a[i]=true
218+;
219+a[i]=undef
220+end
221+check(a,0,4)
222+for i = 1, lim
223+do
224+local a = {}
225+for i = i, 1, - 1
226+do
227+a[i]=i
228+end
229+check(a,mp2(i),0)
230+end
231+lim=35
232+local function foo
233+(n, ...)
234+local arg = {...}
235+check(arg,n,0)
236+assert(select("#",...) == n)
237+arg[n + 1]=true
238+check(arg,mp2(n + 1),0)
239+arg.x=true
240+check(arg,mp2(n + 1),1)
241+end
242+local a = {}
243+for i = 1, lim
244+do
245+a[i]=true
246+;
247+foo(i,table.unpack(a))
248+end
249+local a = {}
250+for i = 1, 64
251+do
252+a[i]=true
253+end
254+for i = 1, 64
255+do
256+a[i]=nil
257+end
258+assert(T.querytab(a) == 64)
259+a[32]=true
260+;
261+a[48]=true
262+;
263+a[51]=true
264+assert(# a == 48)
265+assert(select(4,T.querytab(a)) == 48)
266+a[50]=true
267+assert(select(4,T.querytab(a)) == 50)
268+assert(# a == 51)
269+end
270+assert(# {} == 0)
271+assert(# {nil} == 0)
272+assert(# {nil,nil} == 0)
273+assert(# {nil,nil,nil} == 0)
274+assert(# {nil,nil,nil,nil} == 0)
275+assert(# {1,2,3,nil,nil} == 3)
276+print("+")
277+local nofind = {}
278+a,b,c=1,2,3
279+a,b,c=nil
280+assert(next({}) == next({}))
281+local function find
282+(name)
283+local n,v =
284+while 1 do
285+n,v=next(_G,n)
286+if not n then
287+return nofind
288+end
289+assert(_G[n] ~= undef)
290+if n == name then
291+return v
292+end
293+end
294+local function find1
295+(name)
296+for n,v in pairs(_G)
297+do
298+if n == name then
299+return v
300+end
301+end
302+return nil
303+end
304+assert(print == find("print") and print == find1("print"))
305+assert(_G["print"] == find("print"))
306+assert(assert == find1("assert"))
307+assert(nofind == find("return"))
308+assert(not find1("return"))
309+_G["ret" .. "urn"]=undef
310+assert(nofind == find("return"))
311+_G["xxx"]=1
312+assert(xxx == find("xxx"))
313+checkerror("invalid key",next,{10,20},3)
314+checkerror("bad argument",pairs)
315+checkerror("bad argument",ipairs)
316+print("+")
317+a={}
318+for i = 0, 1e4
319+do
320+if math.fmod(i,10) ~= 0 then
321+a["x" .. i]=i
322+end
323+end
324+n={["n"] = 0}
325+for i,v in pairs(a)
326+do
327+n.n=n.n + 1
328+assert(i and v and a[i] == v)
329+end
330+assert(n.n == 9e3)
331+a=nil
332+local a = {}
333+for n,v in pairs(_G)
334+do
335+a[n]=v
336+end
337+for n,v in pairs(a)
338+do
339+if not package.loaded[n] and type(v) ~= "function" and not string.find(n,"^[%u_]") then
340+_G[n]=undef
341+end
342+collectgarbage()
343+end
344+local function checknext
345+(a)
346+local b = {}
347+local k,v = next(a)
348+;
349+while k do
350+b[k]=v
351+;
352+k,v=next(a,k)
353+for k,v in pairs(b)
354+do
355+assert(a[k] == v)
356+end
357+for k,v in pairs(a)
358+do
359+assert(b[k] == v)
360+end
361+end
362+checknext({1,["x"] = 1,["y"] = 2,["z"] = 3})
363+checknext({1,2,["x"] = 1,["y"] = 2,["z"] = 3})
364+checknext({1,2,3,["x"] = 1,["y"] = 2,["z"] = 3})
365+checknext({1,2,3,4,["x"] = 1,["y"] = 2,["z"] = 3})
366+checknext({1,2,3,4,5,["x"] = 1,["y"] = 2,["z"] = 3})
367+assert(# {} == 0)
368+assert(# {[- 1] = 2} == 0)
369+for i = 0, 40
370+do
371+local a = {}
372+for j = 1, i
373+do
374+a[j]=j
375+end
376+assert(# a == i)
377+end
378+function table.maxn(t)
379+local max = 0
380+for k in pairs(t)
381+do
382+max=(type(k) == "number") and math.max(max,k) or max
383+end
384+return max
385+end
386+assert(table.maxn({}) == 0)
387+assert(table.maxn({["1000"] = true}) == 0)
388+assert(table.maxn({["1000"] = true,[24.5] = 3}) == 24.5)
389+assert(table.maxn({[1e3] = true}) == 1e3)
390+assert(table.maxn({[10] = true,[100 * math.pi] = print}) == 100 * math.pi)
391+table.maxn=nil
392+a={}
393+for i = 0, 50
394+do
395+a[2 ^ i]=true
396+end
397+assert(a[# a])
398+print("+")
399+local a = {[1] = 1,[1.1] = 2,["x"] = 3,[string.rep("x",1e3)] = 4,[print] = 5,[checkerror] = 6,[coroutine.running()] = 7,[true] = 8,[io.stdin] = 9,[{}] = 10}
400+local b = {}
401+;
402+for i = 1, 10
403+do
404+b[i]=true
405+end
406+for k,v in pairs(a)
407+do
408+assert(b[v])
409+;
410+b[v]=undef
411+end
412+assert(next(b) == nil)
413+local t = {[{1}] = 1,[{2}] = 2,[string.rep("x ",4)] = 3,[100.3] = 4,[4] = 5}
414+local n = 0
415+for k,v in pairs(t)
416+do
417+n=n + 1
418+assert(t[k] == v)
419+t[k]=undef
420+collectgarbage()
421+assert(t[k] == undef)
422+end
423+assert(n == 5)
424+print("testing next x GC of deleted keys")
425+local co = coroutine.wrap((t)
426+for k,v in pairs(t)
427+do
428+local k1 = next(t)
429+assert(k == k1)
430+t[k]=nil
431+local expected = (type(k) == "table" and k[1] or type(k) == "function" and k() or string.sub(k,1,1))
432+assert(expected == v)
433+coroutine.yield(v)
434+end
435+end)
436+local t = {}
437+t[{1}]=1
438+t[{2}]=2
439+t[string.rep("a",50)]="a"
440+t[string.rep("b",50)]="b"
441+t[{3}]=3
442+t[string.rep("c",10)]="c"
443+t[()
444+return 10
445+end]=10
446+local count = 7
447+while co(t) do
448+collectgarbage("collect")
449+count=count - 1
450+assert(count == 0 and next(t) == nil)
451+local function test
452+(a)
453+assert(not pcall(table.insert,a,2,20))
454+;
455+table.insert(a,10)
456+;
457+table.insert(a,2,20)
458+;
459+table.insert(a,1,- 1)
460+;
461+table.insert(a,40)
462+;
463+table.insert(a,# a + 1,50)
464+table.insert(a,2,- 2)
465+assert(a[2] ~= undef)
466+assert(a["2"] == undef)
467+assert(not pcall(table.insert,a,0,20))
468+;
469+assert(not pcall(table.insert,a,# a + 2,20))
470+;
471+assert(table.remove(a,1) == - 1)
472+assert(table.remove(a,1) == - 2)
473+assert(table.remove(a,1) == 10)
474+assert(table.remove(a,1) == 20)
475+assert(table.remove(a,1) == 40)
476+assert(table.remove(a,1) == 50)
477+assert(table.remove(a,1) == nil)
478+assert(table.remove(a) == nil)
479+assert(table.remove(a,# a) == nil)
480+end
481+a={["n"] = 0,[- 7] = "ban"}
482+test(a)
483+assert(a.n == 0 and a[- 7] == "ban")
484+a={[- 7] = "ban"}
485+;
486+test(a)
487+assert(a.n == nil and # a == 0 and a[- 7] == "ban")
488+a={[- 1] = "ban"}
489+test(a)
490+assert(# a == 0 and table.remove(a) == nil and a[- 1] == "ban")
491+a={[0] = "ban"}
492+assert(# a == 0 and table.remove(a) == "ban" and a[0] == undef)
493+table.insert(a,1,10)
494+;
495+table.insert(a,1,20)
496+;
497+table.insert(a,1,- 1)
498+assert(table.remove(a) == 10)
499+assert(table.remove(a) == 20)
500+assert(table.remove(a) == - 1)
501+assert(table.remove(a) == nil)
502+a={"c","d"}
503+table.insert(a,3,"a")
504+table.insert(a,"b")
505+assert(table.remove(a,1) == "c")
506+assert(table.remove(a,1) == "d")
507+assert(table.remove(a,1) == "a")
508+assert(table.remove(a,1) == "b")
509+assert(table.remove(a,1) == nil)
510+assert(# a == 0 and a.n == nil)
511+a={10,20,30,40}
512+assert(table.remove(a,# a + 1) == nil)
513+assert(not pcall(table.remove,a,0))
514+assert(a[# a] == 40)
515+assert(table.remove(a,# a) == 40)
516+assert(a[# a] == 30)
517+assert(table.remove(a,2) == 20)
518+assert(a[# a] == 30 and # a == 2)
519+local function test
520+(proxy,t)
521+for i = 1, 10
522+do
523+table.insert(proxy,1,i)
524+end
525+assert(# proxy == 10 and # t == 10 and proxy[1] ~= undef)
526+for i = 1, 10
527+do
528+assert(t[i] == 11 - i)
529+end
530+table.sort(proxy)
531+for i = 1, 10
532+do
533+assert(t[i] == i and proxy[i] == i)
534+end
535+assert(table.concat(proxy,",") == "1,2,3,4,5,6,7,8,9,10")
536+for i = 1, 8
537+do
538+assert(table.remove(proxy,1) == i)
539+end
540+assert(# proxy == 2 and # t == 2)
541+local a,b,c = table.unpack(proxy)
542+assert(a == 9 and b == 10 and c == nil)
543+end
544+local t = {}
545+local proxy = setmetatable({},{["__len"] = ()
546+return # t
547+end,["__index"] = t,["__newindex"] = t})
548+test(proxy,t)
549+local count = 0
550+t=setmetatable({},{["__newindex"] = (t,k,v)
551+count=count + 1
552+;
553+rawset(t,k,v)
554+end})
555+test(t,t)
556+assert(count == 10)
557+t=setmetatable({},{["__index"] = (_,k)
558+return k + 1
559+end,["__len"] = (_)
560+return 5
561+end})
562+assert(table.concat(t,";") == "2;3;4;5;6")
563+local t = setmetatable({},{["__len"] = ()
564+return math.maxinteger
565+end})
566+table.insert(t,20)
567+local k,v = next(t)
568+assert(k == math.mininteger and v == 20)
569+if not T then
570+(Message or print)("
571+ >>> testC not active: skipping tests for table library on non-tables <<<
572+")
573+else
574+local debug = require("debug")
575+local tab = {10,20,30}
576+local mt = {}
577+local u = T.newuserdata(0)
578+checkerror("table expected",table.insert,u,40)
579+checkerror("table expected",table.remove,u)
580+debug.setmetatable(u,mt)
581+checkerror("table expected",table.insert,u,40)
582+checkerror("table expected",table.remove,u)
583+mt.__index=tab
584+checkerror("table expected",table.insert,u,40)
585+checkerror("table expected",table.remove,u)
586+mt.__newindex=tab
587+checkerror("table expected",table.insert,u,40)
588+checkerror("table expected",table.remove,u)
589+mt.__len=()
590+return # tab
591+end
592+table.insert(u,40)
593+assert(# u == 4 and # tab == 4 and u[4] == 40 and tab[4] == 40)
594+assert(table.remove(u) == 40)
595+table.insert(u,1,50)
596+assert(# u == 4 and # tab == 4 and u[4] == 30 and tab[1] == 50)
597+mt.__newindex=nil
598+mt.__len=nil
599+local tab2 = {}
600+local u2 = T.newuserdata(0)
601+debug.setmetatable(u2,{["__newindex"] = (_,k,v)
602+tab2[k]=v
603+end})
604+table.move(u,1,4,1,u2)
605+assert(# tab2 == 4 and tab2[1] == tab[1] and tab2[4] == tab[4])
606+end
607+print("+")
608+a={}
609+for i = 1, 1e3
610+do
611+a[i]=i
612+;
613+a[i - 1]=undef
614+end
615+assert(next(a,nil) == 1e3 and next(a,1e3) == nil)
616+assert(next({}) == nil)
617+assert(next({},nil) == nil)
618+for a,b in pairs({})
619+do
620+error("not here")
621+end
622+for i = 1, 0
623+do
624+error("not here")
625+end
626+for i = 0, 1, - 1
627+do
628+error("not here")
629+end
630+a=nil
631+;
632+for i = 1, 1
633+do
634+assert(not a)
635+;
636+a=1
637+end
638+;
639+assert(a)
640+a=nil
641+;
642+for i = 1, 1, - 1
643+do
644+assert(not a)
645+;
646+a=1
647+end
648+;
649+assert(a)
650+print("testing floats in numeric for")
651+local a =
652+a=0
653+;
654+for i = 1, 1, 1
655+do
656+a=a + 1
657+end
658+;
659+assert(a == 1)
660+a=0
661+;
662+for i = 1e4, 1e4, - 1
663+do
664+a=a + 1
665+end
666+;
667+assert(a == 1)
668+a=0
669+;
670+for i = 1, 0.99999, 1
671+do
672+a=a + 1
673+end
674+;
675+assert(a == 0)
676+a=0
677+;
678+for i = 9999, 1e4, - 1
679+do
680+a=a + 1
681+end
682+;
683+assert(a == 0)
684+a=0
685+;
686+for i = 1, 0.99999, - 1
687+do
688+a=a + 1
689+end
690+;
691+assert(a == 1)
692+a=0
693+;
694+for i = 0, 0.999999999, 0.1
695+do
696+a=a + 1
697+end
698+;
699+assert(a == 10)
700+a=0
701+;
702+for i = 1, 1, 1
703+do
704+a=a + 1
705+end
706+;
707+assert(a == 1)
708+a=0
709+;
710+for i = - 1.5, - 1.5, 1
711+do
712+a=a + 1
713+end
714+;
715+assert(a == 1)
716+a=0
717+;
718+for i = 1e6, 1e6, - 1
719+do
720+a=a + 1
721+end
722+;
723+assert(a == 1)
724+a=0
725+;
726+for i = 1, 0.99999, 1
727+do
728+a=a + 1
729+end
730+;
731+assert(a == 0)
732+a=0
733+;
734+for i = 99999, 1e5, - 1
735+do
736+a=a + 1
737+end
738+;
739+assert(a == 0)
740+a=0
741+;
742+for i = 1, 0.99999, - 1
743+do
744+a=a + 1
745+end
746+;
747+assert(a == 1)
748+local a =
749+a=0
750+;
751+for i = 1, 10
752+do
753+a=a + 1
754+;
755+i="x"
756+end
757+;
758+assert(a == 10)
759+a=0
760+;
761+for i = 10, 1, - 1
762+do
763+a=a + 1
764+;
765+i="x"
766+end
767+;
768+assert(a == 10)
769+a=0
770+;
771+for i = "10", "1", "-2"
772+do
773+a=a + 1
774+end
775+;
776+assert(a == 5)
777+local c =
778+local function checkfloat
779+(i)
780+assert(math.type(i) == "float")
781+c=c + 1
782+end
783+c=0
784+;
785+for i = 1, 10
786+do
787+checkfloat(i)
788+end
789+assert(c == 10)
790+c=0
791+;
792+for i = - 1, - 10, - 1
793+do
794+checkfloat(i)
795+end
796+assert(c == 10)
797+local function checkint
798+(i)
799+assert(math.type(i) == "integer")
800+c=c + 1
801+end
802+local m = math.maxinteger
803+c=0
804+;
805+for i = m, m - 10, - 1
806+do
807+checkint(i)
808+end
809+assert(c == 11)
810+c=0
811+;
812+for i = 1, 10.9
813+do
814+checkint(i)
815+end
816+assert(c == 10)
817+c=0
818+;
819+for i = 10, 1e-3, - 1
820+do
821+checkint(i)
822+end
823+assert(c == 10)
824+c=0
825+;
826+for i = 1, "10.8"
827+do
828+checkint(i)
829+end
830+assert(c == 10)
831+c=0
832+;
833+for i = 9, "3.4", - 1
834+do
835+checkint(i)
836+end
837+assert(c == 6)
838+c=0
839+;
840+for i = 0, " -3.4 ", - 1
841+do
842+checkint(i)
843+end
844+assert(c == 4)
845+c=0
846+;
847+for i = 100, "96.3", - 2
848+do
849+checkint(i)
850+end
851+assert(c == 2)
852+c=0
853+;
854+for i = 1, math.huge
855+do
856+if i > 10 then
857+break
858+end
859+;
860+checkint(i)
861+end
862+assert(c == 10)
863+c=0
864+;
865+for i = - 1, - math.huge, - 1
866+do
867+if i < - 10 then
868+break
869+end
870+;
871+checkint(i)
872+end
873+assert(c == 10)
874+for i = math.mininteger, - 1e101
875+do
876+assert(false)
877+end
878+for i = math.maxinteger, 1e101, - 1
879+do
880+assert(false)
881+end
882+local function checkfor
883+(from,to,step,t)
884+local c = 0
885+for i = from, to, step
886+do
887+c=c + 1
888+assert(i == t[c])
889+end
890+assert(c == # t)
891+end
892+local maxi = math.maxinteger
893+local mini = math.mininteger
894+checkfor(mini,maxi,maxi,{mini,- 1,maxi - 1})
895+checkfor(mini,math.huge,maxi,{mini,- 1,maxi - 1})
896+checkfor(maxi,mini,mini,{maxi,- 1})
897+checkfor(maxi,mini,- maxi,{maxi,0,- maxi})
898+checkfor(maxi,- math.huge,mini,{maxi,- 1})
899+checkfor(maxi,mini,1,{})
900+checkfor(mini,maxi,- 1,{})
901+checkfor(maxi - 6,maxi,3,{maxi - 6,maxi - 3,maxi})
902+checkfor(mini + 4,mini,- 2,{mini + 4,mini + 2,mini})
903+local step = maxi // 10
904+local c = mini
905+for i = mini, maxi, step
906+do
907+assert(i == c)
908+c=c + step
909+end
910+c=maxi
911+for i = maxi, mini, - step
912+do
913+assert(i == c)
914+c=c - step
915+end
916+checkfor(maxi,maxi,maxi,{maxi})
917+checkfor(maxi,maxi,mini,{maxi})
918+checkfor(mini,mini,maxi,{mini})
919+checkfor(mini,mini,mini,{mini})
920+checkerror("'for' step is zero",()
921+for i = 1, 10, 0
922+do
923+
924+end
925+end)
926+checkerror("'for' step is zero",()
927+for i = 1, - 10, 0
928+do
929+
930+end
931+end)
932+checkerror("'for' step is zero",()
933+for i = 1, - 10, 0
934+do
935+
936+end
937+end)
938+collectgarbage()
939+local function f
940+(n,p)
941+local t = {}
942+;
943+for i = 1, p
944+do
945+t[i]=i * 10
946+end
947+return (_,n, ...)
948+assert(select("#",...) == 0)
949+if n > 0 then
950+n=n - 1
951+return n,table.unpack(t)
952+end
953+end,nil,n
954+end
955+local x = 0
956+for n,a,b,c,d in f(5,3)
957+do
958+x=x + 1
959+assert(a == 10 and b == 20 and c == 30 and d == nil)
960+end
961+assert(x == 5)
962+a={}
963+local x,y,z = pairs(a)
964+assert(type(x) == "function" and y == a and z == nil)
965+local function foo
966+(e,i)
967+assert(e == a)
968+if i <= 10 then
969+return i + 1,i + 2
970+end
971+end
972+local function foo1
973+(e,i)
974+i=i + 1
975+assert(e == a)
976+if i <= e.n then
977+return i,a[i]
978+end
979+end
980+setmetatable(a,{["__pairs"] = (x)
981+return foo,x,0
982+end})
983+local i = 0
984+for k,v in pairs(a)
985+do
986+i=i + 1
987+assert(k == i and v == k + 1)
988+end
989+a.n=5
990+a[3]=30
991+a={["n"] = 10}
992+setmetatable(a,{["__index"] = (t,k)
993+if k <= t.n then
994+return k * 10
995+end
996+end})
997+i=0
998+for k,v in ipairs(a)
999+do
1000+i=i + 1
1001+assert(k == i and v == i * 10)
1002+end
1003+assert(i == a.n)
1004+local t = setmetatable({10,20,30},{["__pairs"] = (t)
1005+local inc = coroutine.yield()
1006+return (t,i)
1007+if i > 1 then
1008+return i - inc,t[i - inc]
1009+else
1010+return nil
1011+end
1012+end,t,# t + 1
1013+end})
1014+local res = {}
1015+local co = coroutine.wrap(()
1016+for i,p in pairs(t)
1017+do
1018+res[# res + 1]=p
1019+end
1020+end)
1021+co()
1022+co(1)
1023+assert(res[1] == 30 and res[2] == 20 and res[3] == 10 and # res == 3)
1024+print("OK")
zod/luau/res/lua/cycled/pm.luanew file+406
@@ -0,0 +1,406 @@
1+print("testing pattern matching")
2+local function checkerror
3+(msg,f, ...)
4+local s,err = pcall(f,...)
5+assert(not s and string.find(err,msg))
6+end
7+local function f
8+(s,p)
9+local i,e = string.find(s,p)
10+if i then
11+return string.sub(s,i,e)
12+end
13+end
14+local a,b = string.find("","")
15+assert(a == 1 and b == 0)
16+;
17+a,b=string.find("alo","")
18+assert(a == 1 and b == 0)
19+a,b=string.find("ao ao ao","a",1)
20+assert(a == 1 and b == 1)
21+a,b=string.find("ao ao ao","ao",2)
22+assert(a == 5 and b == 7)
23+a,b=string.find("ao ao ao","ao",9)
24+assert(a == 9 and b == 11)
25+a,b=string.find("aaaaab","ab",2)
26+;
27+assert(a == 9 and b == 11)
28+;
29+a,b=string.find("aaaaab","b")
30+assert(a == 11 and b == 11)
31+assert(not string.find("aaaaab","b"))
32+assert(not string.find("",""))
33+assert(string.find("alo123alo","12") == 4)
34+assert(not string.find("alo123alo","^12"))
35+assert(string.match("aaab",".*b") == "aaab")
36+assert(string.match("aaa",".*a") == "aaa")
37+assert(string.match("b",".*b") == "b")
38+assert(string.match("aaab",".+b") == "aaab")
39+assert(string.match("aaa",".+a") == "aaa")
40+assert(not string.match("b",".+b"))
41+assert(string.match("aaab",".?b") == "ab")
42+assert(string.match("aaa",".?a") == "aa")
43+assert(string.match("b",".?b") == "b")
44+assert(f("aloALO","%l*") == "alo")
45+assert(f("aLo_ALO","%a*") == "aLo")
46+assert(f("
47+ *&
48+ xuxu
49+
50+","%g%g%g+") == "xuxu")
51+local function PU
52+(p)
53+p=string.gsub(p,"(" .. utf8.charpattern .. ")%?",(c)
54+return string.gsub(c,".","%0?")
55+end)
56+p=string.gsub(p,"%.",utf8.charpattern)
57+return p
58+end
59+assert(f("aaab","a*") == "aaa")
60+;
61+assert(f("aaa","^.*$") == "aaa")
62+;
63+assert(f("aaa","b*") == "")
64+;
65+assert(f("aaa","ab*a") == "aa")
66+assert(f("aba","ab*a") == "aba")
67+assert(f("aaab","a+") == "aaa")
68+assert(f("aaa","^.+$") == "aaa")
69+assert(not f("aaa","b+"))
70+assert(not f("aaa","ab+a"))
71+assert(f("aba","ab+a") == "aba")
72+assert(f("a$a",".$") == "a")
73+assert(f("a$a",".%$") == "a$")
74+assert(f("a$a",".$.") == "a$a")
75+assert(not f("a$a","$$"))
76+assert(not f("a$b","a$"))
77+assert(f("a$a","$") == "")
78+assert(f("","b*") == "")
79+assert(not f("aaa","bb*"))
80+assert(f("aaab","a-") == "")
81+assert(f("aaa","^.-$") == "aaa")
82+assert(f("aabaaabaaabaaaba","b.*b") == "baaabaaabaaab")
83+assert(f("aabaaabaaabaaaba","b.-b") == "baaab")
84+assert(f("alo xo",".o$") == "xo")
85+assert(f("
86+ isto é assim","%S%S*") == "isto")
87+assert(f("
88+ isto é assim","%S*$") == "assim")
89+assert(f("
90+ isto é assim","[a-z]*$") == "assim")
91+assert(f("um caracter ? extra","[^%sa-z]") == "?")
92+assert(f("","a?") == "")
93+assert(f("á",PU("á?")) == "á")
94+assert(f("ábl",PU("á?b?l?")) == "ábl")
95+assert(f(" ábl",PU("á?b?l?")) == "")
96+assert(f("aa","^aa?a?a") == "aa")
97+assert(f("]]]áb","[^]]+") == "áb")
98+assert(f("0alo alo","%x*") == "0a")
99+assert(f("alo alo","%C+") == "alo alo")
100+print("+")
101+local function f1
102+(s,p)
103+p=string.gsub(p,"%%([0-9])",(s)
104+return "%" .. (tonumber(s) + 1)
105+end)
106+p=string.gsub(p,"^(^?)","%1()",1)
107+p=string.gsub(p,"($?)$","()%1",1)
108+local t = {string.match(s,p)}
109+return string.sub(s,t[1],t[# t] - 1)
110+end
111+assert(f1("alo alx 123 bo bo","(..*) %1") == "bo bo")
112+assert(f1("axz123= 4= 4 34","(.+)=(.*)=%2 %1") == "3= 4= 4 3")
113+assert(f1("=======","^(=*)=%1$") == "=======")
114+assert(not string.match("==========","^([=]*)=%1$"))
115+local function range
116+(i,j)
117+if i <= j then
118+return i,range(i + 1,j)
119+end
120+end
121+local abc = string.char(range(0,127)) .. string.char(range(128,255))
122+;
123+assert(string.len(abc) == 256)
124+local function strset
125+(p)
126+local res = {["s"] = ""}
127+string.gsub(abc,p,(c)
128+res.s=res.s .. c
129+end)
130+return res.s
131+end
132+;
133+assert(string.len(strset("[�-�]")) == 11)
134+assert(strset("[a-z]") == "abcdefghijklmnopqrstuvwxyz")
135+assert(strset("[a-z%d]") == strset("[%da-uu-z]"))
136+assert(strset("[a-]") == "-a")
137+assert(strset("[^%W]") == strset("[%w]"))
138+assert(strset("[]%%]") == "%]")
139+assert(strset("[a%-z]") == "-az")
140+assert(strset("[%^%[%-a%]%-b]") == "-[]^ab")
141+assert(strset("%Z") == strset("[-�]"))
142+assert(strset(".") == strset("[-�%z]"))
143+print("+")
144+;
145+assert(string.match("alo xyzK","(%w+)K") == "xyz")
146+assert(string.match("254 K","(%d*)K") == "")
147+assert(string.match("alo ","(%w*)$") == "")
148+assert(not string.match("alo ","(%w+)$"))
149+assert(string.find("(álo)","%(á") == 1)
150+local a,b,c,d,e = string.match("âlo alo",PU("^(((.).). (%w*))$"))
151+assert(a == "âlo alo" and b == "âl" and c == "â" and d == "alo" and e == nil)
152+a,b,c,d=string.match("0123456789","(.+(.?)())")
153+assert(a == "0123456789" and b == "" and c == 11 and d == nil)
154+print("+")
155+assert(string.gsub("ülo ülo","ü","x") == "xlo xlo")
156+assert(string.gsub("alo úlo "," +$","") == "alo úlo")
157+assert(string.gsub(" alo alo ","^%s*(.-)%s*$","%1") == "alo alo")
158+assert(string.gsub("alo alo
159+ 123
160+ ","%s+"," ") == "alo alo 123 ")
161+local t = "abç d"
162+a,b=string.gsub(t,PU("(.)"),"%1@")
163+assert(a == "a@b@ç@ @d@" and b == 5)
164+a,b=string.gsub("abçd",PU("(.)"),"%0@",2)
165+assert(a == "a@b@çd" and b == 2)
166+assert(string.gsub("alo alo","()[al]","%1") == "12o 56o")
167+assert(string.gsub("abc=xyz","(%w*)(%p)(%w+)","%3%2%1-%0") == "xyz=abc-abc=xyz")
168+assert(string.gsub("abc","%w","%1%0") == "aabbcc")
169+assert(string.gsub("abc","%w+","%0%1") == "abcabc")
170+assert(string.gsub("áéí","$","óú") == "áéíóú")
171+assert(string.gsub("","^","r") == "r")
172+assert(string.gsub("","$","r") == "r")
173+print("+")
174+assert(string.gsub("a b cd"," *","-") == "-a-b-c-d-")
175+local res = ""
176+local sub = "a
177+bc d"
178+local i = 1
179+for p,e in string.gmatch(sub,"()%s*()")
180+do
181+res=res .. string.sub(sub,i,p - 1) .. "-"
182+i=e
183+end
184+assert(res == "-a-b-c-d-")
185+assert(string.gsub("um (dois) tres (quatro)","(%(%w+%))",string.upper) == "um (DOIS) tres (QUATRO)")
186+local function setglobal
187+(n,v)
188+rawset(_G,n,v)
189+end
190+string.gsub("a=roberto,roberto=a","(%w+)=(%w%w*)",setglobal)
191+assert(_G.a == "roberto" and _G.roberto == "a")
192+_G.a=nil
193+;
194+_G.roberto=nil
195+function f(a,b)
196+return string.gsub(a,".",b)
197+end
198+assert(string.gsub("trocar tudo em |teste|b| é |beleza|al|","|([^|]*)|([^|]*)|",f) == "trocar tudo em bbbbb é alalalalalal")
199+local function dostring
200+(s)
201+return load(s,"")() or ""
202+end
203+assert(string.gsub("alo $a='x'$ novamente $return a$","$([^$]*)%$",dostring) == "alo novamente x")
204+local x = string.gsub("$x=string.gsub('alo', '.', string.upper)$ assim vai para $return x$","$([^$]*)%$",dostring)
205+assert(x == " assim vai para ALO")
206+_G.a,_G.x=nil
207+local t = {}
208+local s = "a alo jose joao"
209+local r = string.gsub(s,"()(%w+)()",(a,w,b)
210+assert(string.len(w) == b - a)
211+;
212+t[a]=b - a
213+;
214+end)
215+assert(s == r and t[1] == 1 and t[3] == 3 and t[7] == 4 and t[13] == 4)
216+local function isbalanced
217+(s)
218+return not string.find(string.gsub(s,"%b()",""),"[()]")
219+end
220+assert(isbalanced("(9 ((8))() 7) a b ()(c)() a"))
221+assert(not isbalanced("(9 ((8) 7) a b ( c) a"))
222+assert(string.gsub("alo 'oi' alo","%b''",""") == "alo " alo")
223+local t = {"apple","orange","lime",["n"] = 0}
224+assert(string.gsub("x and x and x","x",()
225+t.n=t.n + 1
226+;
227+return t[t.n]
228+end) == "apple and orange and lime")
229+t={["n"] = 0}
230+string.gsub("first second word","%w%w*",(w)
231+t.n=t.n + 1
232+;
233+t[t.n]=w
234+end)
235+assert(t[1] == "first" and t[2] == "second" and t[3] == "word" and t.n == 3)
236+t={["n"] = 0}
237+assert(string.gsub("first second word","%w+",(w)
238+t.n=t.n + 1
239+;
240+t[t.n]=w
241+end,2) == "first second word")
242+assert(t[1] == "first" and t[2] == "second" and t[3] == undef)
243+checkerror("invalid replacement value %(a table%)",string.gsub,"alo",".",{["a"] = {}})
244+checkerror("invalid capture index %%2",string.gsub,"alo",".","%2")
245+checkerror("invalid capture index %%0",string.gsub,"alo","(%0)","a")
246+checkerror("invalid capture index %%1",string.gsub,"alo","(%1)","a")
247+checkerror("invalid use of '%%'",string.gsub,"alo",".","%x")
248+if not _soft then
249+print("big strings")
250+local a = string.rep("a",3e5)
251+assert(string.find(a,"^a*.?$"))
252+assert(not string.find(a,"^a*.?b$"))
253+assert(string.find(a,"^a-.?$"))
254+a=string.rep("a",1e4) .. string.rep("b",1e4)
255+assert(not pcall(string.gsub,a,"b"))
256+end
257+local function rev
258+(s)
259+return string.gsub(s,"(.)(.+)",(c,s1)
260+return rev(s1) .. c
261+end)
262+end
263+local x = "abcdef"
264+assert(rev(rev(x)) == x)
265+assert(string.gsub("alo alo",".",{}) == "alo alo")
266+assert(string.gsub("alo alo","(.)",{["a"] = "AA",["l"] = ""}) == "AAo AAo")
267+assert(string.gsub("alo alo","(.).",{["a"] = "AA",["l"] = "K"}) == "AAo AAo")
268+assert(string.gsub("alo alo","((.)(.?))",{["al"] = "AA",["o"] = false}) == "AAo AAo")
269+assert(string.gsub("alo alo","().",{"x","yy","zzz"}) == "xyyzzz alo")
270+t={}
271+;
272+setmetatable(t,{["__index"] = (t,s)
273+return string.upper(s)
274+end})
275+assert(string.gsub("a alo b hi","%w%w+",t) == "a ALO b HI")
276+local a = 0
277+for i in string.gmatch("abcde","()")
278+do
279+assert(i == a + 1)
280+;
281+a=i
282+end
283+assert(a == 6)
284+t={["n"] = 0}
285+for w in string.gmatch("first second word","%w+")
286+do
287+t.n=t.n + 1
288+;
289+t[t.n]=w
290+end
291+assert(t[1] == "first" and t[2] == "second" and t[3] == "word")
292+t={3,6,9}
293+for i in string.gmatch("xuxx uu ppar r","()(.)%2")
294+do
295+assert(i == table.remove(t,1))
296+end
297+assert(# t == 0)
298+t={}
299+for i,j in string.gmatch("13 14 10 = 11, 15= 16, 22=23","(%d+)%s*=%s*(%d+)")
300+do
301+t[tonumber(i)]=tonumber(j)
302+end
303+a=0
304+for k,v in pairs(t)
305+do
306+assert(k + 1 == v + 0)
307+;
308+a=a + 1
309+end
310+assert(a == 3)
311+local s = 0
312+for k in string.gmatch("10 20 30","%d+",3)
313+do
314+s=s + tonumber(k)
315+end
316+assert(s == 50)
317+s=0
318+for k in string.gmatch("11 21 31","%d+",- 4)
319+do
320+s=s + tonumber(k)
321+end
322+assert(s == 32)
323+s=0
324+for k in string.gmatch("11 21 31","%w*",9)
325+do
326+s=s + 1
327+end
328+assert(s == 1)
329+s=0
330+for k in string.gmatch("11 21 31","%w*",10)
331+do
332+s=s + 1
333+end
334+assert(s == 0)
335+assert(string.gsub("aaa aa a aaa a","%f[%w]a","x") == "xaa xa x xaa x")
336+assert(string.gsub("[[]] [][] [[[[","%f[[].","x") == "x[]] x]x] x[[[")
337+assert(string.gsub("01abc45de3","%f[%d]",".") == ".01abc.45de.3")
338+assert(string.gsub("01abc45 de3x","%f[%D]%w",".") == "01.bc45 de3.")
339+assert(string.gsub("function","%f[-�]%w",".") == ".unction")
340+assert(string.gsub("function","%f[^-�]",".") == "function.")
341+assert(string.find("a","%f[a]") == 1)
342+assert(string.find("a","%f[^%z]") == 1)
343+assert(string.find("a","%f[^%l]") == 2)
344+assert(string.find("aba","%f[a%z]") == 3)
345+assert(string.find("aba","%f[%z]") == 4)
346+assert(not string.find("aba","%f[%l%z]"))
347+assert(not string.find("aba","%f[^%l%z]"))
348+local i,e = string.find(" alo aalo allo","%f[%S].-%f[%s].-%f[%S]")
349+assert(i == 2 and e == 5)
350+local k = string.match(" alo aalo allo","%f[%S](.-%f[%s].-%f[%S])")
351+assert(k == "alo ")
352+local a = {1,5,9,14,17}
353+for k in string.gmatch("alo alo th02 is 1hat","()%f[%w%d]")
354+do
355+assert(table.remove(a,1) == k)
356+end
357+assert(# a == 0)
358+local function malform
359+(p,m)
360+m=m or "malformed"
361+local r,msg = pcall(string.find,"a",p)
362+assert(not r and string.find(msg,m))
363+end
364+malform("(.","unfinished capture")
365+malform(".)","invalid pattern capture")
366+malform("[a")
367+malform("[]")
368+malform("[^]")
369+malform("[a%]")
370+malform("[a%")
371+malform("%b")
372+malform("%ba")
373+malform("%")
374+malform("%f","missing")
375+assert(string.match("abc","[-]+") == "")
376+assert(string.match("abc","[-]+") == "")
377+assert(string.find("b$a","$?") == 2)
378+assert(string.find("abcefg","%") == 4)
379+assert(string.match("abcefgeg","%b") == "efge")
380+assert(string.match("abc","%+") == "")
381+assert(string.match("abc","%%?") == "")
382+assert(string.find("abc",".") == 4)
383+assert(string.find("abcxabcabc","xabca.") == 4)
384+local s = string.rep("a",100)
385+local r = string.gsub(s,"b","c")
386+assert(string.format("%p",s) == string.format("%p",r))
387+r=string.gsub(s,".",{["x"] = "y"})
388+assert(string.format("%p",s) == string.format("%p",r))
389+local count = 0
390+r=string.gsub(s,".",(x)
391+assert(x == "a")
392+count=count + 1
393+return nil
394+end)
395+r=string.gsub(r,".",{["b"] = "x"})
396+assert(count == 100)
397+assert(string.format("%p",s) == string.format("%p",r))
398+count=0
399+r=string.gsub(s,".",(x)
400+assert(x == "a")
401+count=count + 1
402+return x
403+end)
404+assert(count == 100)
405+assert(r == s and string.format("%p",s) ~= string.format("%p",r))
406+print("OK")
zod/luau/res/lua/cycled/sort.luanew file+301
@@ -0,0 +1,301 @@
1+print("testing (parts of) table library")
2+print("testing unpack")
3+local unpack = table.unpack
4+local maxI = math.maxinteger
5+local minI = math.mininteger
6+local function checkerror
7+(msg,f, ...)
8+local s,err = pcall(f,...)
9+assert(not s and string.find(err,msg))
10+end
11+checkerror("wrong number of arguments",table.insert,{},2,3,4)
12+local x,y,z,a,n =
13+a={}
14+;
15+local lim = _soft and 200 or 2e3
16+for i = 1, lim
17+do
18+a[i]=i
19+end
20+assert(select(lim,unpack(a)) == lim and select("#",unpack(a)) == lim)
21+x=unpack(a)
22+assert(x == 1)
23+x={unpack(a)}
24+assert(# x == lim and x[1] == 1 and x[lim] == lim)
25+x={unpack(a,lim - 2)}
26+assert(# x == 3 and x[1] == lim - 2 and x[3] == lim)
27+x={unpack(a,10,6)}
28+assert(next(x) == nil)
29+x={unpack(a,11,10)}
30+assert(next(x) == nil)
31+x,y=unpack(a,10,10)
32+assert(x == 10 and y == nil)
33+x,y,z=unpack(a,10,11)
34+assert(x == 10 and y == 11 and z == nil)
35+a,x=unpack({1})
36+assert(a == 1 and x == nil)
37+a,x=unpack({1,2},1,1)
38+assert(a == 1 and x == nil)
39+local maxi = (1 << 31) - 1
40+local mini = - (1 << 31)
41+checkerror("too many results",unpack,{},0,maxi)
42+checkerror("too many results",unpack,{},1,maxi)
43+checkerror("too many results",unpack,{},0,maxI)
44+checkerror("too many results",unpack,{},1,maxI)
45+checkerror("too many results",unpack,{},mini,maxi)
46+checkerror("too many results",unpack,{},- maxi,maxi)
47+checkerror("too many results",unpack,{},minI,maxI)
48+unpack({},maxi,0)
49+unpack({},maxi,1)
50+unpack({},maxI,minI)
51+pcall(unpack,{},1,maxi + 1)
52+local a,b = unpack({[maxi] = 20},maxi,maxi)
53+assert(a == 20 and b == nil)
54+a,b=unpack({[maxi] = 20},maxi - 1,maxi)
55+assert(a == nil and b == 20)
56+local t = {[maxI - 1] = 12,[maxI] = 23}
57+a,b=unpack(t,maxI - 1,maxI)
58+;
59+assert(a == 12 and b == 23)
60+a,b=unpack(t,maxI,maxI)
61+;
62+assert(a == 23 and b == nil)
63+a,b=unpack(t,maxI,maxI - 1)
64+;
65+assert(a == nil and b == nil)
66+t={[minI] = 12.3,[minI + 1] = 23.5}
67+a,b=unpack(t,minI,minI + 1)
68+;
69+assert(a == 12.3 and b == 23.5)
70+a,b=unpack(t,minI,minI)
71+;
72+assert(a == 12.3 and b == nil)
73+a,b=unpack(t,minI + 1,minI)
74+;
75+assert(a == nil and b == nil)
76+local t = setmetatable({},{["__len"] = ()
77+return "abc"
78+end})
79+assert(# t == "abc")
80+checkerror("object length is not an integer",table.insert,t,1)
81+print("testing pack")
82+a=table.pack()
83+assert(a[1] == undef and a.n == 0)
84+a=table.pack(table)
85+assert(a[1] == table and a.n == 1)
86+a=table.pack(nil,nil,nil,nil)
87+assert(a[1] == nil and a.n == 4)
88+checkerror("table expected",table.move,1,2,3,4)
89+local function eqT
90+(a,b)
91+for k,v in pairs(a)
92+do
93+assert(b[k] == v)
94+end
95+for k,v in pairs(b)
96+do
97+assert(a[k] == v)
98+end
99+end
100+local a = table.move({10,20,30},1,3,2)
101+eqT(a,{10,10,20,30})
102+a=table.move({10,20,30},1,3,3)
103+eqT(a,{10,20,10,20,30})
104+a={10,20,30,40}
105+table.move(a,1,4,2,a)
106+eqT(a,{10,10,20,30,40})
107+a=table.move({10,20,30},2,3,1)
108+eqT(a,{20,30,30})
109+a={}
110+assert(table.move({10,20,30},1,3,1,a) == a)
111+eqT(a,{10,20,30})
112+a={}
113+assert(table.move({10,20,30},1,0,3,a) == a)
114+eqT(a,{})
115+a=table.move({10,20,30},1,10,1)
116+eqT(a,{10,20,30})
117+a=table.move({[maxI - 2] = 1,[maxI - 1] = 2,[maxI] = 3},maxI - 2,maxI,- 10,{})
118+eqT(a,{[- 10] = 1,[- 9] = 2,[- 8] = 3})
119+a=table.move({[minI] = 1,[minI + 1] = 2,[minI + 2] = 3},minI,minI + 2,- 10,{})
120+eqT(a,{[- 10] = 1,[- 9] = 2,[- 8] = 3})
121+a=table.move({45},1,1,maxI)
122+eqT(a,{45,[maxI] = 45})
123+a=table.move({[maxI] = 100},maxI,maxI,minI)
124+eqT(a,{[minI] = 100,[maxI] = 100})
125+a=table.move({[minI] = 100},minI,minI,maxI)
126+eqT(a,{[minI] = 100,[maxI] = 100})
127+a=setmetatable({},{["__index"] = (_,k)
128+return k * 10
129+end,["__newindex"] = error})
130+local b = table.move(a,1,10,3,{})
131+eqT(a,{})
132+eqT(b,{nil,nil,10,20,30,40,50,60,70,80,90,100})
133+b=setmetatable({""},{["__index"] = error,["__newindex"] = (t,k,v)
134+t[1]=string.format("%s(%d,%d)",t[1],k,v)
135+end})
136+table.move(a,10,13,3,b)
137+assert(b[1] == "(3,100)(4,110)(5,120)(6,130)")
138+local stat,msg = pcall(table.move,b,10,13,3,b)
139+assert(not stat and msg == b)
140+local function checkmove
141+(f,e,t,x,y)
142+local pos1,pos2 =
143+local a = setmetatable({},{["__index"] = (_,k)
144+pos1=k
145+end,["__newindex"] = (_,k)
146+pos2=k
147+;
148+error()
149+end})
150+local st,msg = pcall(table.move,a,f,e,t)
151+assert(not st and not msg and pos1 == x and pos2 == y)
152+end
153+checkmove(1,maxI,0,1,0)
154+checkmove(0,maxI - 1,1,maxI - 1,maxI)
155+checkmove(minI,- 2,- 5,- 2,maxI - 6)
156+checkmove(minI + 1,- 1,- 2,- 1,maxI - 3)
157+checkmove(minI,- 2,0,minI,0)
158+checkmove(minI + 1,- 1,1,minI + 1,1)
159+checkerror("too many",table.move,{},0,maxI,1)
160+checkerror("too many",table.move,{},- 1,maxI - 1,1)
161+checkerror("too many",table.move,{},minI,- 1,1)
162+checkerror("too many",table.move,{},minI,maxI,1)
163+checkerror("wrap around",table.move,{},1,maxI,2)
164+checkerror("wrap around",table.move,{},1,2,maxI)
165+checkerror("wrap around",table.move,{},minI,- 2,2)
166+print("testing sort")
167+local a = setmetatable({},{["__len"] = ()
168+return - 1
169+end})
170+assert(# a == - 1)
171+table.sort(a,error)
172+a=setmetatable({},{["__len"] = ()
173+return maxI
174+end})
175+checkerror("too big",table.sort,a)
176+local function check
177+(t)
178+local function f
179+(a,b)
180+assert(a and b)
181+;
182+return true
183+end
184+checkerror("invalid order function",table.sort,t,f)
185+end
186+check({1,2,3,4})
187+check({1,2,3,4,5})
188+check({1,2,3,4,5,6})
189+function check(a,f)
190+f=f or (x,y)
191+return x < y
192+end
193+;
194+for n = # a, 2, - 1
195+do
196+assert(not f(a[n],a[n - 1]))
197+end
198+end
199+a={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}
200+table.sort(a)
201+check(a)
202+local function perm
203+(s,n)
204+n=n or # s
205+if n == 1 then
206+local t = {unpack(s)}
207+table.sort(t)
208+check(t)
209+else
210+for i = 1, n
211+do
212+s[i],s[n]=s[n],s[i]
213+perm(s,n - 1)
214+s[i],s[n]=s[n],s[i]
215+end
216+end
217+end
218+perm({})
219+perm({1})
220+perm({1,2})
221+perm({1,2,3})
222+perm({1,2,3,4})
223+perm({2,2,3,4})
224+perm({1,2,3,4,5})
225+perm({1,2,3,3,5})
226+perm({1,2,3,4,5,6})
227+perm({2,2,3,3,5,6})
228+local function timesort
229+(a,n,func,msg,pre)
230+local x = os.clock()
231+table.sort(a,func)
232+x=(os.clock() - x) * 1e3
233+pre=pre or ""
234+print(string.format("%ssorting %d %s elements in %.2f msec.",pre,n,msg,x))
235+check(a,func)
236+end
237+local limit = 5e4
238+if _soft then
239+limit=5e3
240+end
241+a={}
242+for i = 1, limit
243+do
244+a[i]=math.random()
245+end
246+timesort(a,limit,nil,"random")
247+timesort(a,limit,nil,"sorted","re-")
248+a={}
249+for i = 1, limit
250+do
251+a[i]=math.random()
252+end
253+local x = os.clock()
254+;
255+local i = 0
256+table.sort(a,(x,y)
257+i=i + 1
258+;
259+return y < x
260+end)
261+x=(os.clock() - x) * 1e3
262+print(string.format("Invert-sorting other %d elements in %.2f msec., with %i comparisons",limit,x,i))
263+check(a,(x,y)
264+return y < x
265+end)
266+table.sort({})
267+for i = 1, limit
268+do
269+a[i]=false
270+end
271+timesort(a,limit,(x,y)
272+return nil
273+end,"equal")
274+for i,v in pairs(a)
275+do
276+assert(v == false)
277+end
278+AA={"�lo","first :-)","alo","then this one","45","and a new"}
279+table.sort(AA)
280+check(AA)
281+table.sort(AA,(x,y)
282+load(string.format("AA[%q] = ''",x),"")()
283+collectgarbage()
284+return x < y
285+end)
286+_G.AA=nil
287+local tt = {["__lt"] = (a,b)
288+return a.val < b.val
289+end}
290+a={}
291+for i = 1, 10
292+do
293+a[i]={["val"] = math.random(100)}
294+;
295+setmetatable(a[i],tt)
296+;
297+end
298+table.sort(a)
299+check(a,tt.__lt)
300+check(a)
301+print("OK")
zod/luau/res/lua/cycled/strings.luanew file+434
@@ -0,0 +1,434 @@
1+print("testing strings and string library")
2+local maxi <const> = math.maxinteger
3+local mini <const> = math.mininteger
4+local function checkerror
5+(msg,f, ...)
6+local s,err = pcall(f,...)
7+assert(not s and string.find(err,msg))
8+end
9+assert("alo" < "alo1")
10+assert("" < "a")
11+assert("aloalo" < "alob")
12+assert("aloalo" > "aloalo")
13+assert("alo" < "alo")
14+assert("alo" > "alo")
15+assert("" < "")
16+assert("" < "")
17+assert("aa" <= "aa")
18+assert(not ("ab" <= "aa"))
19+assert("" < "")
20+assert(not ("" < ""))
21+assert("" <= "")
22+assert(not ("" <= ""))
23+assert("" <= "")
24+assert("" >= "")
25+assert(not ("b" < "a"))
26+assert(string.sub("123456789",2,4) == "234")
27+assert(string.sub("123456789",7) == "789")
28+assert(string.sub("123456789",7,6) == "")
29+assert(string.sub("123456789",7,7) == "7")
30+assert(string.sub("123456789",0,0) == "")
31+assert(string.sub("123456789",- 10,10) == "123456789")
32+assert(string.sub("123456789",1,9) == "123456789")
33+assert(string.sub("123456789",- 10,- 20) == "")
34+assert(string.sub("123456789",- 1) == "9")
35+assert(string.sub("123456789",- 4) == "6789")
36+assert(string.sub("123456789",- 6,- 4) == "456")
37+assert(string.sub("123456789",mini,- 4) == "123456")
38+assert(string.sub("123456789",mini,maxi) == "123456789")
39+assert(string.sub("123456789",mini,mini) == "")
40+assert(string.sub("123456789",3,5) == "234")
41+assert(("123456789"):sub(8) == "789")
42+assert(string.find("123456789","345") == 3)
43+local a,b = string.find("123456789","345")
44+assert(string.sub("123456789",a,b) == "345")
45+assert(string.find("1234567890123456789","345",3) == 3)
46+assert(string.find("1234567890123456789","345",4) == 13)
47+assert(not string.find("1234567890123456789","346",4))
48+assert(string.find("1234567890123456789",".45",- 9) == 13)
49+assert(not string.find("abcdefg","",5,1))
50+assert(string.find("","") == 1)
51+assert(string.find("","",1) == 1)
52+assert(not string.find("","",2))
53+assert(not string.find("","aaa",1))
54+assert(("alo(.)alo"):find("(.)",1,1) == 4)
55+assert(string.len("") == 0)
56+assert(string.len("") == 3)
57+assert(string.len("1234567890") == 10)
58+assert(# "" == 0)
59+assert(# "" == 3)
60+assert(# "1234567890" == 10)
61+assert(string.byte("a") == 97)
62+assert(string.byte("�") > 127)
63+assert(string.byte(string.char(255)) == 255)
64+assert(string.byte(string.char(0)) == 0)
65+assert(string.byte("") == 0)
66+assert(string.byte("alox",- 1) == string.byte("x"))
67+assert(string.byte("ba",2) == 97)
68+assert(string.byte("
69+
70+",2,- 1) == 10)
71+assert(string.byte("
72+
73+",2,2) == 10)
74+assert(string.byte("") == nil)
75+assert(string.byte("hi",- 3) == nil)
76+assert(string.byte("hi",3) == nil)
77+assert(string.byte("hi",9,10) == nil)
78+assert(string.byte("hi",2,1) == nil)
79+assert(string.char() == "")
80+assert(string.char(0,255,0) == "�")
81+assert(string.char(0,string.byte("�"),0) == "�")
82+assert(string.char(string.byte("�l�u",1,- 1)) == "�l�u")
83+assert(string.char(string.byte("�l�u",1,0)) == "")
84+assert(string.char(string.byte("�l�u",- 10,100)) == "�l�u")
85+checkerror("out of range",string.char,256)
86+checkerror("out of range",string.char,- 1)
87+checkerror("out of range",string.char,math.maxinteger)
88+checkerror("out of range",string.char,math.mininteger)
89+assert(string.upper("abc") == "ABC")
90+assert(string.lower("ABCc%$") == "abcc%$")
91+assert(string.rep("teste",0) == "")
92+assert(string.rep("t�st�",2) == "t�st�t�st�")
93+assert(string.rep("",10) == "")
94+if string.packsize("i") == 4 then
95+checkerror("too large",string.rep,"aa",(1 << 30))
96+checkerror("too large",string.rep,"a",(1 << 30),",")
97+end
98+assert(string.rep("teste",0,"xuxu") == "")
99+assert(string.rep("teste",1,"xuxu") == "teste")
100+assert(string.rep("",2,"") == "")
101+assert(string.rep("",10,".") == string.rep(".",9))
102+assert(not pcall(string.rep,"aa",maxi // 2 + 10))
103+assert(not pcall(string.rep,"",maxi // 2 + 10,"aa"))
104+assert(string.reverse("") == "")
105+assert(string.reverse("") == "")
106+assert(string.reverse("1234") == "4321")
107+for i = 0, 30
108+do
109+assert(string.len(string.rep("a",i)) == i)
110+end
111+assert(type(tostring(nil)) == "string")
112+assert(type(tostring(12)) == "string")
113+assert(string.find(tostring({}),"table:"))
114+assert(string.find(tostring(print),"function:"))
115+assert(# tostring("") == 1)
116+assert(tostring(true) == "true")
117+assert(tostring(false) == "false")
118+assert(tostring(- 1203) == "-1203")
119+assert(tostring(1203.125) == "1203.125")
120+assert(tostring(- 0.5) == "-0.5")
121+assert(tostring(- 32767) == "-32767")
122+if math.tointeger(2147483647) then
123+assert(tostring(- 2147483647) == "-2147483647")
124+end
125+if math.tointeger(4.611686018427388e18) then
126+assert(tostring(4.611686018427388e18) == "4611686018427387904")
127+assert(tostring(- 4.611686018427388e18) == "-4611686018427387904")
128+end
129+if tostring(0) == "0.0" then
130+assert("" .. 12 == "12" and 12 .. "" == "12.0")
131+assert(tostring(- 1203 + 0) == "-1203.0")
132+else
133+assert(tostring(0) == "0")
134+assert("" .. 12 == "12" and 12 .. "" == "12")
135+assert(tostring(- 1203 + 0) == "-1203")
136+end
137+local null = "(null)"
138+assert(string.format("%p",4) == null)
139+assert(string.format("%p",true) == null)
140+assert(string.format("%p",nil) == null)
141+assert(string.format("%p",{}) ~= null)
142+assert(string.format("%p",print) ~= null)
143+assert(string.format("%p",coroutine.running()) ~= null)
144+assert(string.format("%p",io.stdin) ~= null)
145+assert(string.format("%p",io.stdin) == string.format("%p",io.stdin))
146+assert(string.format("%p",print) == string.format("%p",print))
147+assert(string.format("%p",print) ~= string.format("%p",assert))
148+assert(# string.format("%90p",{}) == 90)
149+assert(# string.format("%-60p",{}) == 60)
150+assert(string.format("%10p",false) == string.rep(" ",10 - # null) .. null)
151+assert(string.format("%-12p",1.5) == null .. string.rep(" ",12 - # null))
152+local t1 = {}
153+;
154+local t2 = {}
155+assert(string.format("%p",t1) ~= string.format("%p",t2))
156+local s1 = string.rep("a",10)
157+local s2 = string.rep("aa",5)
158+assert(string.format("%p",s1) == string.format("%p",s2))
159+local s1 = string.rep("a",300)
160+;
161+local s2 = string.rep("a",300)
162+assert(string.format("%p",s1) ~= string.format("%p",s2))
163+local x = ""�lo"
164+\"
165+assert(string.format("%q%s",x,x) == ""\"�lo\"\
166+\\""�lo"
167+\")
168+assert(string.format("%q","") == ""\0"")
169+assert(load(string.format("return %q",x))() == x)
170+x="39"
171+assert(load(string.format("return %q",x))() == x)
172+assert(string.format("%c%c%x",string.byte("�"),string.byte("b"),140) == "�b8c")
173+assert(string.format("") == "")
174+assert(string.format("%c",34) .. string.format("%c",48) .. string.format("%c",90) .. string.format("%c",100) == string.format("%1c%-c%-1c%c",34,48,90,100))
175+assert(string.format("%s is not %s","not be","be") == "not be is not be")
176+assert(string.format("%%%d %010d",10,23) == "%10 0000000023")
177+assert(tonumber(string.format("%f",10.3)) == 10.3)
178+assert(string.format(""%-50s"","a") == ""a" .. string.rep(" ",49) .. """)
179+assert(string.format("-%.20s.20s",string.rep("%",2e3)) == "-" .. string.rep("%",20) .. ".20s")
180+assert(string.format(""-%20s.20s"",string.rep("%",2e3)) == string.format("%q","-" .. string.rep("%",2e3) .. ".20s"))
181+local function checkQ
182+(v)
183+local s = string.format("%q",v)
184+local nv = load("return " .. s)()
185+assert(v == nv and math.type(v) == math.type(nv))
186+end
187+checkQ("�4")
188+checkQ(math.maxinteger)
189+checkQ(math.mininteger)
190+checkQ(math.pi)
191+checkQ(0.1)
192+checkQ(true)
193+checkQ(nil)
194+checkQ(false)
195+checkQ(math.huge)
196+checkQ(- math.huge)
197+assert(string.format("%q",0 / 0) == "(0/0)")
198+checkerror("no literal",string.format,"%q",{})
199+assert(string.format("%s","") == "")
200+checkerror("contains zeros",string.format,"%10s","")
201+assert(string.format("%s %s",nil,true) == "nil true")
202+assert(string.format("%s %.4s",false,true) == "false true")
203+assert(string.format("%.3s %.3s",false,true) == "fal tru")
204+local m = setmetatable({},{["__tostring"] = ()
205+return "hello"
206+end,["__name"] = "hi"})
207+assert(string.format("%s %.10s",m,m) == "hello hello")
208+getmetatable(m).__tostring=nil
209+assert(string.format("%.4s",m) == "hi: ")
210+getmetatable(m).__tostring=()
211+return {}
212+end
213+checkerror("'__tostring' must return a string",tostring,m)
214+assert(string.format("%x",0) == "0")
215+assert(string.format("%02x",0) == "00")
216+assert(string.format("%08X",4294967295) == "FFFFFFFF")
217+assert(string.format("%+08d",31501) == "+0031501")
218+assert(string.format("%+08d",- 30927) == "-0030927")
219+local i = 1
220+local j = 1e4
221+while i + 1 < j do
222+local m = (i + j) // 2
223+if 10 ^ m < math.huge then
224+i=m
225+else
226+j=m
227+end
228+assert(10 ^ i < math.huge and 10 ^ j == math.huge)
229+local s = string.format("%.99f",- (10 ^ i))
230+assert(string.len(s) >= i + 101)
231+assert(tonumber(s) == - (10 ^ i))
232+assert(10 ^ 38 < math.huge)
233+local s = string.format("%.99f",- (10 ^ 38))
234+assert(string.len(s) >= 38 + 101)
235+assert(tonumber(s) == - (10 ^ 38))
236+local max,min = 2147483647,- 2147483648
237+assert(string.sub(string.format("%8x",- 1),- 8) == "ffffffff")
238+assert(string.format("%x",max) == "7fffffff")
239+assert(string.sub(string.format("%x",min),- 8) == "80000000")
240+assert(string.format("%d",max) == "2147483647")
241+assert(string.format("%d",min) == "-2147483648")
242+assert(string.format("%u",4294967295) == "4294967295")
243+assert(string.format("%o",43981) == "125715")
244+max,min=9223372036854775807,- 9223372036854775808
245+if max > 2 ^ 53 then
246+assert(string.format("%x",(2 ^ 52 | 0) - 1) == "fffffffffffff")
247+assert(string.format("0x%8X",2399141891) == "0x8F000003")
248+assert(string.format("%d",2 ^ 53) == "9007199254740992")
249+assert(string.format("%i",- 2 ^ 53) == "-9007199254740992")
250+assert(string.format("%x",max) == "7fffffffffffffff")
251+assert(string.format("%x",min) == "8000000000000000")
252+assert(string.format("%d",max) == "9223372036854775807")
253+assert(string.format("%d",min) == "-9223372036854775808")
254+assert(string.format("%u",~ (- 1 << 64)) == "18446744073709551615")
255+assert(tostring(1234567890123) == "1234567890123")
256+end
257+print("testing 'format %a %A'")
258+local function matchhexa
259+(n)
260+local s = string.format("%a",n)
261+assert(string.find(s,"^%-?0x[1-9a-f]%.?[0-9a-f]*p[-+]?%d+$"))
262+assert(tonumber(s) == n)
263+s=string.format("%A",n)
264+assert(string.find(s,"^%-?0X[1-9A-F]%.?[0-9A-F]*P[-+]?%d+$"))
265+assert(tonumber(s) == n)
266+end
267+for _,n in ipairs({0.1,- 0.1,1 / 3,- 1 / 3,1e30,- 1e30,- 45 / 247,1,- 1,2,- 2,3e-20,- 3e-20})
268+do
269+matchhexa(n)
270+end
271+assert(string.find(string.format("%A",0),"^0X0%.?0*P%+?0$"))
272+assert(string.find(string.format("%a",- 0),"^%-0x0%.?0*p%+?0$"))
273+if not _port then
274+assert(string.find(string.format("%a",1 / 0),"^inf"))
275+assert(string.find(string.format("%A",- 1 / 0),"^%-INF"))
276+assert(string.find(string.format("%a",0 / 0),"^%-?nan"))
277+assert(string.find(string.format("%a",- 0),"^%-0x0"))
278+end
279+if not pcall(string.format,"%.3a",0) then
280+(Message or print)("
281+ >>> modifiers for format '%a' not available <<<
282+")
283+else
284+assert(string.find(string.format("%+.2A",12),"^%+0X%x%.%x0P%+?%d$"))
285+assert(string.find(string.format("%.4A",- 12),"^%-0X%x%.%x000P%+?%d$"))
286+end
287+assert(string.format("%#12o",10) == " 012")
288+assert(string.format("%#10x",100) == " 0x64")
289+assert(string.format("%#-17X",100) == "0X64 ")
290+assert(string.format("%013i",- 100) == "-000000000100")
291+assert(string.format("%2.5d",- 100) == "-00100")
292+assert(string.format("%.u",0) == "")
293+assert(string.format("%+#014.0f",100) == "+000000000100.")
294+assert(string.format("%-16c",97) == "a ")
295+assert(string.format("%+.3G",1.5) == "+1.5")
296+assert(string.format("%.0s","alo") == "")
297+assert(string.format("%.s","alo") == "")
298+assert(string.match(string.format("% 1.0E",100),"^ 1E%+0+2$"))
299+assert(string.match(string.format("% .1g",2 ^ 10),"^ 1e%+0+3$"))
300+local function check
301+(fmt,msg)
302+checkerror(msg,string.format,fmt,10)
303+end
304+local aux = string.rep("0",600)
305+check("%100.3d","invalid conversion")
306+check("%1" .. aux .. ".3d","too long")
307+check("%1.100d","invalid conversion")
308+check("%10.1" .. aux .. "004d","too long")
309+check("%t","invalid conversion")
310+check("%" .. aux .. "d","too long")
311+check("%d %d","no value")
312+check("%010c","invalid conversion")
313+check("%.10c","invalid conversion")
314+check("%0.34s","invalid conversion")
315+check("%#i","invalid conversion")
316+check("%3.1p","invalid conversion")
317+check("%0.s","invalid conversion")
318+check("%10q","cannot have modifiers")
319+check("%F","invalid conversion")
320+assert(load("return 1
321+--comment without ending EOL")() == 1)
322+checkerror("table expected",table.concat,3)
323+checkerror("at index " .. maxi,table.concat,{}," ",maxi,maxi)
324+checkerror("at index %" .. mini,table.concat,{}," ",mini,mini)
325+assert(table.concat({}) == "")
326+assert(table.concat({},"x") == "")
327+assert(table.concat({"","",""},"..") == "....")
328+local a = {}
329+;
330+for i = 1, 300
331+do
332+a[i]="xuxu"
333+end
334+assert(table.concat(a,"123") .. "123" == string.rep("xuxu123",300))
335+assert(table.concat(a,"b",20,20) == "xuxu")
336+assert(table.concat(a,"",20,21) == "xuxuxuxu")
337+assert(table.concat(a,"x",22,21) == "")
338+assert(table.concat(a,"3",299) == "xuxu3xuxu")
339+assert(table.concat({},"x",maxi,maxi - 1) == "")
340+assert(table.concat({},"x",mini + 1,mini) == "")
341+assert(table.concat({},"x",maxi,mini) == "")
342+assert(table.concat({[maxi] = "alo"},"x",maxi,maxi) == "alo")
343+assert(table.concat({[maxi] = "alo",[maxi - 1] = "y"},"-",maxi - 1,maxi) == "y-alo")
344+assert(not pcall(table.concat,{"a","b",{}}))
345+a={"a","b","c"}
346+assert(table.concat(a,",",1,0) == "")
347+assert(table.concat(a,",",1,1) == "a")
348+assert(table.concat(a,",",1,2) == "a,b")
349+assert(table.concat(a,",",2) == "b,c")
350+assert(table.concat(a,",",3) == "c")
351+assert(table.concat(a,",",4) == "")
352+if not _port then
353+local locales = {"ptb","pt_BR.iso88591","ISO-8859-1"}
354+local function trylocale
355+(w)
356+for i = 1, # locales
357+do
358+if os.setlocale(locales[i],w) then
359+print(string.format("'%s' locale set to '%s'",w,locales[i]))
360+return locales[i]
361+end
362+end
363+print(string.format("'%s' locale not found",w))
364+return false
365+end
366+if trylocale("collate") then
367+assert("alo" < "�lo" and "�lo" < "amo")
368+end
369+if trylocale("ctype") then
370+assert(string.gsub("�����","%a","x") == "xxxxx")
371+assert(string.gsub("����","%l","x") == "x�x�")
372+assert(string.gsub("����","%u","x") == "�x�x")
373+assert(string.upper("���{xuxu}��o") == "���{XUXU}��O")
374+end
375+os.setlocale("C")
376+assert(os.setlocale() == "C")
377+assert(os.setlocale(nil,"numeric") == "C")
378+end
379+local f = string.gmatch("1 2 3 4 5","%d+")
380+assert(f() == "1")
381+local co = coroutine.wrap(f)
382+assert(co() == "2")
383+if T == nil then
384+(Message or print)("
385+ >>> testC not active: skipping 'pushfstring' tests <<<
386+")
387+else
388+print("testing 'pushfstring'")
389+local blen = 200
390+local function callpfs
391+(op,fmt,n)
392+local x = {T.testC("pushfstring" .. op .. "; return *",fmt,n)}
393+assert(# x == 4)
394+return x[4]
395+end
396+local function testpfs
397+(op,fmt,n)
398+assert(callpfs(op,fmt,n) == string.format(fmt,n))
399+end
400+testpfs("I","",0)
401+testpfs("I",string.rep("a",blen - 1),0)
402+testpfs("I",string.rep("a",blen),0)
403+testpfs("I",string.rep("a",blen + 1),0)
404+local str = string.rep("ab",blen) .. "%d" .. string.rep("d",blen / 2)
405+testpfs("I",str,2 ^ 14)
406+testpfs("I",str,- 2 ^ 15)
407+str="%d" .. string.rep("cd",blen)
408+testpfs("I",str,2 ^ 14)
409+testpfs("I",str,- 2 ^ 15)
410+str=string.rep("c",blen - 2) .. "%d"
411+testpfs("I",str,2 ^ 14)
412+testpfs("I",str,- 2 ^ 15)
413+for l = 12, 14
414+do
415+local str1 = string.rep("a",l)
416+for i = 0, 500, 13
417+do
418+for j = 0, 500, 13
419+do
420+str=string.rep("a",i) .. "%s" .. string.rep("d",j)
421+testpfs("S",str,str1)
422+testpfs("S",str,str)
423+end
424+end
425+end
426+str="abc %c def"
427+testpfs("I",str,string.byte("A"))
428+testpfs("I",str,255)
429+str=string.rep("a",blen - 1) .. "%p" .. string.rep("cd",blen)
430+testpfs("P",str,{})
431+str=string.rep("%%",3 * blen) .. "%p" .. string.rep("%%",2 * blen)
432+testpfs("P",str,{})
433+end
434+print("OK")
zod/luau/res/lua/cycled/tpack.luanew file+245
@@ -0,0 +1,245 @@
1+local pack = string.pack
2+local packsize = string.packsize
3+local unpack = string.unpack
4+print("testing pack/unpack")
5+local NB = 16
6+local sizeshort = packsize("h")
7+local sizeint = packsize("i")
8+local sizelong = packsize("l")
9+local sizesize_t = packsize("T")
10+local sizeLI = packsize("j")
11+local sizefloat = packsize("f")
12+local sizedouble = packsize("d")
13+local sizenumber = packsize("n")
14+local little = (pack("i2",1) == "")
15+local align = packsize("!xXi16")
16+assert(1 <= sizeshort and sizeshort <= sizeint and sizeint <= sizelong and sizefloat <= sizedouble)
17+print("platform:")
18+print(string.format(" short %d, int %d, long %d, size_t %d, float %d, double %d,
19+ lua Integer %d, lua Number %d",sizeshort,sizeint,sizelong,sizesize_t,sizefloat,sizedouble,sizeLI,sizenumber))
20+print(" " .. (little and "little" or "big") .. " endian")
21+print(" alignment: " .. align)
22+local function checkerror
23+(msg,f, ...)
24+local status,err = pcall(f,...)
25+assert(not status and string.find(err,msg))
26+end
27+assert(unpack("B",pack("B",255)) == 255)
28+assert(unpack("b",pack("b",127)) == 127)
29+assert(unpack("b",pack("b",- 128)) == - 128)
30+assert(unpack("H",pack("H",65535)) == 65535)
31+assert(unpack("h",pack("h",32767)) == 32767)
32+assert(unpack("h",pack("h",- 32768)) == - 32768)
33+assert(unpack("L",pack("L",4294967295)) == 4294967295)
34+assert(unpack("l",pack("l",2147483647)) == 2147483647)
35+assert(unpack("l",pack("l",- 2147483648)) == - 2147483648)
36+for i = 1, NB
37+do
38+local s = string.rep("�",i)
39+assert(pack("i" .. i,- 1) == s)
40+assert(packsize("i" .. i) == # s)
41+assert(unpack("i" .. i,s) == - 1)
42+s="�" .. string.rep("",i - 1)
43+assert(pack("<I" .. i,170) == s)
44+assert(unpack("<I" .. i,s) == 170)
45+assert(pack(">I" .. i,170) == s:reverse())
46+assert(unpack(">I" .. i,s:reverse()) == 170)
47+end
48+local lnum = 1510926445411202934483812811265
49+local s = pack("<j",lnum)
50+assert(unpack("<j",s) == lnum)
51+assert(unpack("<i" .. sizeLI + 1,s .. "") == lnum)
52+assert(unpack("<i" .. sizeLI + 1,s .. "") == lnum)
53+for i = sizeLI + 1, NB
54+do
55+local s = pack("<j",- lnum)
56+assert(unpack("<j",s) == - lnum)
57+assert(unpack("<i" .. i,s .. ("�"):rep(i - sizeLI)) == - lnum)
58+assert(unpack(">i" .. i,("�"):rep(i - sizeLI) .. s:reverse()) == - lnum)
59+assert(unpack("<I" .. i,s .. (""):rep(i - sizeLI)) == - lnum)
60+checkerror("does not fit",unpack,"<I" .. i,(""):rep(i - 1) .. "")
61+checkerror("does not fit",unpack,">i" .. i,"" .. (""):rep(i - 1))
62+end
63+for i = 1, sizeLI
64+do
65+local lstr = "
66+ "
67+local lnum = 1510926445411202934483812811265
68+local n = lnum & (~ (- 1 << (i * 8)))
69+local s = string.sub(lstr,1,i)
70+assert(pack("<i" .. i,n) == s)
71+assert(pack(">i" .. i,n) == s:reverse())
72+assert(unpack(">i" .. i,s:reverse()) == n)
73+end
74+local u = 240
75+for i = 1, sizeLI - 1
76+do
77+assert(unpack("<i" .. i,"�" .. ("�"):rep(i - 1)) == - 16)
78+assert(unpack(">I" .. i,"�" .. ("�"):rep(i - 1)) == u)
79+u=u * 256 + 255
80+end
81+assert(pack(">i2 <i2",10,20) == "
82+")
83+local a,b = unpack("<i2 >i2","
84+")
85+assert(a == 10 and b == 20)
86+assert(pack("=i4",2001) == pack("i4",2001))
87+print("testing invalid formats")
88+checkerror("out of limits",pack,"i0",0)
89+checkerror("out of limits",pack,"i" .. NB + 1,0)
90+checkerror("out of limits",pack,"!" .. NB + 1,0)
91+checkerror("%(17%) out of limits %[1,16%]",pack,"Xi" .. NB + 1)
92+checkerror("invalid format option 'r'",pack,"i3r",0)
93+checkerror("16%-byte integer",unpack,"i16",string.rep("",16))
94+checkerror("not power of 2",pack,"!4i3",0)
95+;
96+checkerror("missing size",pack,"c","")
97+checkerror("variable%-length format",packsize,"s")
98+checkerror("variable%-length format",packsize,"z")
99+checkerror("invalid format",packsize,"c1" .. string.rep("0",40))
100+if packsize("i") == 4 then
101+local s = string.rep("c268435456",2 ^ 3)
102+checkerror("too large",packsize,s)
103+s=string.rep("c268435456",2 ^ 3 - 1) .. "c268435455"
104+assert(packsize(s) == 2147483647)
105+end
106+for i = 1, sizeLI - 1
107+do
108+local umax = (1 << (i * 8)) - 1
109+local max = umax >> 1
110+local min = ~ max
111+checkerror("overflow",pack,"<I" .. i,- 1)
112+checkerror("overflow",pack,"<I" .. i,min)
113+checkerror("overflow",pack,">I" .. i,umax + 1)
114+checkerror("overflow",pack,">i" .. i,umax)
115+checkerror("overflow",pack,">i" .. i,max + 1)
116+checkerror("overflow",pack,"<i" .. i,min - 1)
117+assert(unpack(">i" .. i,pack(">i" .. i,max)) == max)
118+assert(unpack("<i" .. i,pack("<i" .. i,min)) == min)
119+assert(unpack(">I" .. i,pack(">I" .. i,umax)) == umax)
120+end
121+assert(unpack(">j",pack(">j",math.maxinteger)) == math.maxinteger)
122+assert(unpack("<j",pack("<j",math.mininteger)) == math.mininteger)
123+assert(unpack("<J",pack("<j",- 1)) == - 1)
124+if little then
125+assert(pack("f",24) == pack("<f",24))
126+else
127+assert(pack("f",24) == pack(">f",24))
128+end
129+print("testing pack/unpack of floating-point numbers")
130+for _,n in ipairs({0,- 1.1,1.9,1 / 0,- 1 / 0,1e20,- 1e20,0.1,2000.7})
131+do
132+assert(unpack("n",pack("n",n)) == n)
133+assert(unpack("<n",pack("<n",n)) == n)
134+assert(unpack(">n",pack(">n",n)) == n)
135+assert(pack("<f",n) == pack(">f",n):reverse())
136+assert(pack(">d",n) == pack("<d",n):reverse())
137+end
138+for _,n in ipairs({0,- 1.5,1 / 0,- 1 / 0,1e10,- 1e9,0.5,2000.25})
139+do
140+assert(unpack("<f",pack("<f",n)) == n)
141+assert(unpack(">f",pack(">f",n)) == n)
142+assert(unpack("<d",pack("<d",n)) == n)
143+assert(unpack(">d",pack(">d",n)) == n)
144+end
145+print("testing pack/unpack of strings")
146+local s = string.rep("abc",1e3)
147+assert(pack("zB",s,247) == s .. "�")
148+local s1,b = unpack("zB",s .. "�")
149+assert(b == 249 and s1 == s)
150+s1=pack("s",s)
151+assert(unpack("s",s1) == s)
152+checkerror("does not fit",pack,"s1",s)
153+checkerror("contains zeros",pack,"z","alo")
154+;
155+checkerror("unfinished string",unpack,"zc10000000","alo")
156+for i = 2, NB
157+do
158+local s1 = pack("s" .. i,s)
159+assert(unpack("s" .. i,s1) == s and # s1 == # s + i)
160+end
161+local x = pack("s","alo")
162+checkerror("too short",unpack,"s",x:sub(1,- 2))
163+checkerror("too short",unpack,"c5","abcd")
164+checkerror("out of limits",pack,"s100","alo")
165+assert(pack("c0","") == "")
166+assert(packsize("c0") == 0)
167+assert(unpack("c0","") == "")
168+assert(pack("<! c3","abc") == "abc")
169+assert(packsize("<! c3") == 3)
170+assert(pack(">!4 c6","abcdef") == "abcdef")
171+assert(pack("c3","123") == "123")
172+assert(pack("c0","") == "")
173+assert(pack("c8","123456") == "123456")
174+assert(pack("c88","") == string.rep("",88))
175+assert(pack("c188","ab") == "ab" .. string.rep("",188 - 2))
176+local a,b,c = unpack("!4 z c3","abcdefghixyz")
177+assert(a == "abcdefghi" and b == "xyz" and c == 14)
178+checkerror("longer than",pack,"c3","1234")
179+local x = pack("<b h b f d f n i",1,2,3,4,5,6,7,8)
180+assert(# x == packsize("<b h b f d f n i"))
181+local a,b,c,d,e,f,g,h = unpack("<b h b f d f n i",x)
182+assert(a == 1 and b == 2 and c == 3 and d == 4 and e == 5 and f == 6 and g == 7 and h == 8)
183+print("testing alignment")
184+assert(pack(" < i1 i2 ",2,3) == "")
185+local x = pack(">!8 b Xh i4 i8 c1 Xi8",- 12,100,200,"�")
186+assert(# x == packsize(">!8 b Xh i4 i8 c1 Xi8"))
187+assert(x == "�" .. "" .. "d" .. "�" .. "�" .. "")
188+local a,b,c,d,pos = unpack(">!8 c1 Xh i4 i8 b Xi8 XI XH",x)
189+assert(a == "�" and b == 100 and c == 200 and d == - 20 and (pos - 1) == # x)
190+x=pack(">!4 c3 c4 c2 z i4 c5 c2 Xi4","abc","abcd","xz","hello",5,"world","xy")
191+assert(x == "abcabcdxzhelloworldxy")
192+local a,b,c,d,e,f,g,pos = unpack(">!4 c3 c4 c2 z i4 c5 c2 Xh Xi4",x)
193+assert(a == "abc" and b == "abcd" and c == "xz" and d == "hello" and e == 5 and f == "world" and g == "xy" and (pos - 1) % 4 == 0)
194+x=pack(" b b Xd b Xb x",1,2,3)
195+assert(packsize(" b b Xd b Xb x") == 4)
196+assert(x == "")
197+a,b,c,pos=unpack("bbXdb",x)
198+assert(a == 1 and b == 2 and c == 3 and pos == # x)
199+assert(packsize("!8 xXi8") == 8)
200+local pos = unpack("!8 xXi8","0123456701234567")
201+;
202+assert(pos == 9)
203+assert(packsize("!8 xXi2") == 2)
204+local pos = unpack("!8 xXi2","0123456701234567")
205+;
206+assert(pos == 3)
207+assert(packsize("!2 xXi2") == 2)
208+local pos = unpack("!2 xXi2","0123456701234567")
209+;
210+assert(pos == 3)
211+assert(packsize("!2 xXi8") == 2)
212+local pos = unpack("!2 xXi8","0123456701234567")
213+;
214+assert(pos == 3)
215+assert(packsize("!16 xXi16") == 16)
216+local pos = unpack("!16 xXi16","0123456701234567")
217+;
218+assert(pos == 17)
219+checkerror("invalid next option",pack,"X")
220+checkerror("invalid next option",unpack,"XXi","")
221+checkerror("invalid next option",unpack,"X i","")
222+checkerror("invalid next option",pack,"Xc1")
223+local x = pack("i4i4i4i4",1,2,3,4)
224+for pos = 1, 16, 4
225+do
226+local i,p = unpack("i4",x,pos)
227+assert(i == pos // 4 + 1 and p == pos + 4)
228+end
229+for pos = 0, 12
230+do
231+local i,p = unpack("!4 i4",x,pos + 1)
232+assert(i == (pos + 3) // 4 + 1 and p == i * 4 + 1)
233+end
234+local i,p = unpack("!4 i4",x,- 4)
235+assert(i == 4 and p == 17)
236+local i,p = unpack("!4 i4",x,- 7)
237+assert(i == 4 and p == 17)
238+local i,p = unpack("!4 i4",x,- # x)
239+assert(i == 1 and p == 5)
240+for i = 1, # x + 1
241+do
242+assert(unpack("c0",x,i) == "")
243+end
244+checkerror("out of string",unpack,"c0",x,# x + 2)
245+print("OK")
zod/luau/res/lua/cycled/tracegc.luanew file+24
@@ -0,0 +1,24 @@
1+local M = {}
2+local setmetatable,stderr,collectgarbage = setmetatable,io.stderr,collectgarbage
3+_ENV=nil
4+local active = false
5+local mt = {}
6+function mt.__gc(o)
7+stderr:write(".")
8+if active then
9+setmetatable(o,mt)
10+end
11+end
12+function M.start()
13+if not active then
14+active=true
15+setmetatable({},mt)
16+end
17+end
18+function M.stop()
19+if active then
20+active=false
21+collectgarbage()
22+end
23+end
24+return M
zod/luau/res/lua/cycled/utf8.luanew file+195
@@ -0,0 +1,195 @@
1+print("testing UTF-8 library")
2+local utf8 = require("utf8")
3+local function checkerror
4+(msg,f, ...)
5+local s,err = pcall(f,...)
6+assert(not s and string.find(err,msg))
7+end
8+local function len
9+(s)
10+return # string.gsub(s,"[�-�]","")
11+end
12+local justone = "^" .. utf8.charpattern .. "$"
13+local function checksyntax
14+(s,t)
15+local ts = {"return '"}
16+for i = 1, # t
17+do
18+ts[i + 1]=string.format("\u{%x}",t[i])
19+end
20+ts[# t + 2]="'"
21+ts=table.concat(ts)
22+assert(assert(load(ts))() == s)
23+end
24+assert(not utf8.offset("alo",5))
25+assert(not utf8.offset("alo",- 4))
26+local function check
27+(s,t,nonstrict)
28+local l = utf8.len(s,1,- 1,nonstrict)
29+assert(# t == l and len(s) == l)
30+assert(utf8.char(table.unpack(t)) == s)
31+assert(utf8.offset(s,0) == 1)
32+checksyntax(s,t)
33+local t1 = {utf8.codepoint(s,1,- 1,nonstrict)}
34+assert(# t == # t1)
35+for i = 1, # t
36+do
37+assert(t[i] == t1[i])
38+end
39+for i = 1, l
40+do
41+local pi = utf8.offset(s,i)
42+local pi1 = utf8.offset(s,2,pi)
43+assert(string.find(string.sub(s,pi,pi1 - 1),justone))
44+assert(utf8.offset(s,- 1,pi1) == pi)
45+assert(utf8.offset(s,i - l - 1) == pi)
46+assert(pi1 - pi == # utf8.char(utf8.codepoint(s,pi,pi,nonstrict)))
47+for j = pi, pi1 - 1
48+do
49+assert(utf8.offset(s,0,j) == pi)
50+end
51+for j = pi + 1, pi1 - 1
52+do
53+assert(not utf8.len(s,j))
54+end
55+assert(utf8.len(s,pi,pi,nonstrict) == 1)
56+assert(utf8.len(s,pi,pi1 - 1,nonstrict) == 1)
57+assert(utf8.len(s,pi,- 1,nonstrict) == l - i + 1)
58+assert(utf8.len(s,pi1,- 1,nonstrict) == l - i)
59+assert(utf8.len(s,1,pi,nonstrict) == i)
60+end
61+local i = 0
62+for p,c in utf8.codes(s,nonstrict)
63+do
64+i=i + 1
65+assert(c == t[i] and p == utf8.offset(s,i))
66+assert(utf8.codepoint(s,p,p,nonstrict) == c)
67+end
68+assert(i == # t)
69+i=0
70+for c in string.gmatch(s,utf8.charpattern)
71+do
72+i=i + 1
73+assert(c == utf8.char(t[i]))
74+end
75+assert(i == # t)
76+for i = 1, l
77+do
78+assert(utf8.offset(s,i) == utf8.offset(s,i - l - 1,# s + 1))
79+end
80+end
81+local function check
82+(s,p)
83+local a,b = utf8.len(s)
84+assert(not a and b == p)
85+end
86+check("abc�def",4)
87+check("���",1)
88+check("����",1)
89+check("汉字�",# ("汉字") + 1)
90+check("�hello",1)
91+check("hel�lo",4)
92+check("汉字�",# ("汉字") + 1)
93+check("�hello",1)
94+check("hel�lo",4)
95+local function errorcodes
96+(s)
97+checkerror("invalid UTF%-8 code",()
98+for c in utf8.codes(s)
99+do
100+assert(c)
101+end
102+end)
103+end
104+errorcodes("ab�")
105+errorcodes("")
106+errorcodes("in�valid")
107+errorcodes("�invalid")
108+errorcodes("αλφ�α")
109+local f = utf8.codes("")
110+assert(f("",2) == nil)
111+assert(f("",- 1) == nil)
112+assert(f("",math.mininteger) == nil)
113+checkerror("position out of bounds",utf8.offset,"abc",1,5)
114+checkerror("position out of bounds",utf8.offset,"abc",1,- 4)
115+checkerror("position out of bounds",utf8.offset,"",1,2)
116+checkerror("position out of bounds",utf8.offset,"",1,- 1)
117+checkerror("continuation byte",utf8.offset,"𦧺",1,2)
118+checkerror("continuation byte",utf8.offset,"𦧺",1,2)
119+checkerror("continuation byte",utf8.offset,"�",1)
120+checkerror("out of bounds",utf8.len,"abc",0,2)
121+checkerror("out of bounds",utf8.len,"abc",1,4)
122+local s = "hello World"
123+local t = {string.byte(s,1,- 1)}
124+for i = 1, utf8.len(s)
125+do
126+assert(t[i] == string.byte(s,i))
127+end
128+check(s,t)
129+check("汉字/漢字",{27721,23383,47,28450,23383})
130+local s = "áéí�"
131+local t = {utf8.codepoint(s,1,# s - 1)}
132+assert(# t == 3 and t[1] == 225 and t[2] == 233 and t[3] == 237)
133+checkerror("invalid UTF%-8 code",utf8.codepoint,s,1,# s)
134+checkerror("out of bounds",utf8.codepoint,s,# s + 1)
135+t={utf8.codepoint(s,4,3)}
136+assert(# t == 0)
137+checkerror("out of bounds",utf8.codepoint,s,- (# s + 1),1)
138+checkerror("out of bounds",utf8.codepoint,s,1,# s + 1)
139+assert(utf8.codepoint("��") == 55296 - 1)
140+assert(utf8.codepoint("�") == 57343 + 1)
141+assert(utf8.codepoint("�",1,1,true) == 55296)
142+assert(utf8.codepoint("��",1,1,true) == 57343)
143+assert(utf8.codepoint("���",1,1,true) == 2147483647)
144+assert(utf8.char() == "")
145+assert(utf8.char(0,97,98,99,1) == "abc")
146+assert(utf8.codepoint(utf8.char(1114111)) == 1114111)
147+assert(utf8.codepoint(utf8.char(2147483647),1,1,true) == (1 << 31) - 1)
148+checkerror("value out of range",utf8.char,2147483647 + 1)
149+checkerror("value out of range",utf8.char,- 1)
150+local function invalid
151+(s)
152+checkerror("invalid UTF%-8 code",utf8.codepoint,s)
153+assert(not utf8.len(s))
154+end
155+invalid("����")
156+invalid("�")
157+invalid("��")
158+invalid("��")
159+invalid("��")
160+invalid("���")
161+invalid("����")
162+invalid("�")
163+invalid("�")
164+invalid("�")
165+invalid("�")
166+check("",{})
167+s=" € ߿ࠀ ￿𐀀 􏿿"
168+s=string.gsub(s," ","")
169+check(s,{0,127,128,2047,2048,65535,65536,1114111})
170+local s = "���"
171+assert(# s == 12)
172+check(s,{67108864,2147483647},true)
173+s=" ���"
174+assert(# s == 10)
175+check(s,{2097152,67108863},true)
176+s="��"
177+assert(# s == 8)
178+check(s,{65536,2097151},true)
179+local x = "日本語a-4éó"
180+check(x,{26085,26412,35486,97,45,52,0,233,243})
181+check("𣲷𠜎𠱓𡁻𠵼ab𠺢",{146615,132878,134227,135291,134524,97,98,134818})
182+check("𨳊𩶘𦧺𨳒𥄫𤓓􏿿",{167114,171416,158202,167122,151851,148691,1114111})
183+local i = 0
184+for p,c in string.gmatch(x,"()(" .. utf8.charpattern .. ")")
185+do
186+i=i + 1
187+assert(utf8.offset(x,i) == p)
188+assert(utf8.len(x,p) == utf8.len(x) - i + 1)
189+assert(utf8.len(c) == 1)
190+for j = 1, # c - 1
191+do
192+assert(utf8.offset(x,0,p + j - 1) == p)
193+end
194+end
195+print("ok")
zod/luau/res/lua/cycled/vararg.luanew file+137
@@ -0,0 +1,137 @@
1+print("testing vararg")
2+local function f
3+(a, ...)
4+local x = {["n"] = select("#",...),...}
5+for i = 1, x.n
6+do
7+assert(a[i] == x[i])
8+end
9+return x.n
10+end
11+local function c12
12+(...)
13+assert(arg == _G.arg)
14+local x = {...}
15+;
16+x.n=# x
17+local res = (x.n == 2 and x[1] == 1 and x[2] == 2)
18+if res then
19+res=55
20+end
21+return res,2
22+end
23+local function vararg
24+(...)
25+return {["n"] = select("#",...),...}
26+end
27+local call = (f,args)
28+return f(table.unpack(args,1,args.n))
29+end
30+assert(f() == 0)
31+assert(f({1,2,3},1,2,3) == 3)
32+assert(f({"alo",nil,45,f,nil},"alo",nil,45,f,nil) == 5)
33+assert(vararg().n == 0)
34+assert(vararg(nil,nil).n == 2)
35+assert(c12(1,2) == 55)
36+local a,b = assert(call(c12,{1,2}))
37+assert(a == 55 and b == 2)
38+a=call(c12,{1,2,["n"] = 2})
39+assert(a == 55 and b == 2)
40+a=call(c12,{1,2,["n"] = 1})
41+assert(not a)
42+assert(c12(1,2,3) == false)
43+local a = vararg(call(next,{_G,nil,["n"] = 2}))
44+local b,c = next(_G)
45+assert(a[1] == b and a[2] == c and a.n == 2)
46+a=vararg(call(call,{c12,{1,2}}))
47+assert(a.n == 2 and a[1] == 55 and a[2] == 2)
48+a=call(print,{"+"})
49+assert(a == nil)
50+local t = {1,10}
51+function t:f(...)
52+local arg = {...}
53+;
54+return self[...] + # arg
55+end
56+assert(t:f(1,4) == 3 and t:f(2) == 11)
57+print("+")
58+local lim = 20
59+local i,a = 1,{}
60+while i <= lim do
61+a[i]=i + 0.3
62+;
63+i=i + 1
64+function f(a,b,c,d, ...)
65+local more = {...}
66+assert(a == 1.3 and more[1] == 5.3 and more[lim - 4] == lim + 0.3 and not more[lim - 3])
67+end
68+local function g
69+(a,b,c)
70+assert(a == 1.3 and b == 2.3 and c == 3.3)
71+end
72+call(f,a)
73+call(g,a)
74+a={}
75+i=1
76+while i <= lim do
77+a[i]=i
78+;
79+i=i + 1
80+assert(call(math.max,a) == lim)
81+print("+")
82+local function oneless
83+(a, ...)
84+return ...
85+end
86+function f(n,a, ...)
87+local b =
88+assert(arg == _G.arg)
89+if n == 0 then
90+local b,c,d = ...
91+return a,b,c,d,oneless(oneless(oneless(...)))
92+else
93+n,b,a=n - 1,...,a
94+assert(b == ...)
95+return f(n,a,...)
96+end
97+end
98+a,b,c,d,e=assert(f(10,5,4,3,2,1))
99+assert(a == 5 and b == 4 and c == 3 and d == 2 and e == 1)
100+a,b,c,d,e=f(4)
101+assert(a == nil and b == nil and c == nil and d == nil and e == nil)
102+local f = load(" return {...} ")
103+local x = f(2,3)
104+assert(x[1] == 2 and x[2] == 3 and x[3] == undef)
105+f=load(" local x = {...}
106+ for i=1,select('#', ...) do assert(x[i] == select(i, ...)) end
107+ assert(x[select('#', ...)+1] == undef)
108+ return true
109+")
110+assert(f("a","b",nil,{},assert))
111+assert(f())
112+a={select(3,table.unpack({10,20,30,40}))}
113+assert(# a == 2 and a[1] == 30 and a[2] == 40)
114+a={select(1)}
115+assert(next(a) == nil)
116+a={select(- 1,3,5,7)}
117+assert(a[1] == 7 and a[2] == undef)
118+a={select(- 2,3,5,7)}
119+assert(a[1] == 5 and a[2] == 7 and a[3] == undef)
120+pcall(select,1e4)
121+pcall(select,- 1e4)
122+function f(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p48,p49,p50, ...)
123+local a1,a2,a3,a4,a5,a6,a7 =
124+local a8,a9,a10,a11,a12,a13,a14 =
125+end
126+f()
127+local function f
128+(a,b,c)
129+return c,b
130+end
131+local function g
132+()
133+return f(1,2)
134+end
135+local a,b = g()
136+assert(a == nil and b == 2)
137+print("OK")
zod/luau/res/lua/cycled/verybig.luanew file+120
@@ -0,0 +1,120 @@
1+print("testing RK")
2+local function foo
3+()
4+local dummy = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256}
5+assert(24.5 + 0.6 == 25.1)
6+local t = {["foo"] = (self,x)
7+return x + self.x
8+end,["x"] = 10}
9+t.t=t
10+assert(t:foo(1.5) == 11.5)
11+assert(t.t:foo(0.5) == 10.5)
12+assert(24.3 == 24.3)
13+assert((()
14+return t.x
15+end)() == 10)
16+end
17+foo()
18+foo=nil
19+if _soft then
20+return 10
21+end
22+print("testing large programs (>64k)")
23+local prog = "$
24+
25+local a,b
26+
27+b = {$1$
28+ b30009 = 65534,
29+ b30010 = 65535,
30+ b30011 = 65536,
31+ b30012 = 65537,
32+ b30013 = 16777214,
33+ b30014 = 16777215,
34+ b30015 = 16777216,
35+ b30016 = 16777217,
36+ b30017 = 0x7fffff,
37+ b30018 = -0x7fffff,
38+ b30019 = 0x1ffffff,
39+ b30020 = -0x1ffffd,
40+ b30021 = -65534,
41+ b30022 = -65535,
42+ b30023 = -65536,
43+ b30024 = -0xffffff,
44+ b30025 = 15012.5,
45+ $2$
46+};
47+
48+assert(b.a50008 == 25004 and b["a11"] == -5.5)
49+assert(b.a33007 == -16503.5 and b.a50009 == -25004.5)
50+assert(b["b"..30024] == -0xffffff)
51+
52+function b:xxx (a,b) return a+b end
53+assert(b:xxx(10, 12) == 22) -- pushself with non-constant index
54+b["xxx"] = undef
55+
56+local s = 0; local n=0
57+for a,b in pairs(b) do s=s+b; n=n+1 end
58+-- with 32-bit floats, exact value of 's' depends on summation order
59+assert(81800000.0 < s and s < 81860000 and n == 70001)
60+
61+a = nil; b = nil
62+print'+'
63+
64+local function f(x) b=x end
65+
66+a = f{$3$} or 10
67+
68+assert(a==10)
69+assert(b[1] == "a10" and b[2] == 5 and b[#b-1] == "a50009")
70+
71+
72+function xxxx (x) return b[x] end
73+
74+assert(xxxx(3) == "a11")
75+
76+a = nil; b=nil
77+xxxx = nil
78+
79+return 10
80+
81+"
82+local function sig
83+(x)
84+return (x % 2 == 0) and "" or "-"
85+end
86+local F = {()
87+for i = 10, 50009
88+do
89+io.write("a",i," = ",sig(i),5 + ((i - 10) / 2),",
90+")
91+end
92+end,()
93+for i = 30026, 50009
94+do
95+io.write("b",i," = ",sig(i),15013 + ((i - 30026) / 2),",
96+")
97+end
98+end,()
99+for i = 10, 50009
100+do
101+io.write(""a",i,"", ",sig(i),5 + ((i - 10) / 2),",
102+")
103+end
104+end}
105+local file = os.tmpname()
106+io.output(file)
107+for s in string.gmatch(prog,"$([^$]+)")
108+do
109+local n = tonumber(s)
110+if not n then
111+io.write(s)
112+else
113+F[n]()
114+end
115+end
116+io.close()
117+local result = dofile(file)
118+assert(os.remove(file))
119+print("OK")
120+return result
zod/luau/ted/test-lua.hoon+27−3
@@ -1,6 +1,7 @@
11/- spider
22/+ *strandio
33/+ lua-parser
4+/+ lua-printer
45=<
56=/ m (strand:spider ,vase)
67^- thread:spider
@@ -8,20 +9,41 @@
89^- form:m
910;< bek=beak bind:m get-beak
1011;< lua-files=(list path) bind:m (list-tree [bek /res/lua])
12+=/ lua-files %+ skim lua-files
13+ |= =path
14+ ^- ?
15+ .=(4 (lent path))
1116;< results=(list test-result) bind:m
1217 =/ m (strand:spider ,(list test-result))
1318 =/ res=(list test-result) ~
1419 |-
1520 ?~ lua-files (pure:m res)
16− =/ current-file i.lua-files
21+ =/ current-file=path i.lua-files
1722 ~& current-file
1823 ;< =cage bind:m (read-file [bek current-file])
1924 =/ lua-code=@t (of-wain:format !<(wain +.cage))
2025 ~& %parsing
21− =/ parse-result ?~ (rush lua-code lua-parser) %err %ok
26+ =/ ast-unit (rush lua-code lua-parser)
27+ ;< parse-result=test-result bind:m
28+ =/ m (strand:spider ,test-result)
29+ ?~ ast-unit (pure:m %err)
30+ =/ ast u.ast-unit
31+ ~& %printing
32+ =/ printed (lua-printer ast)
33+ ;< * bind:m %- send-raw-card
34+ :*
35+ %pass ~ %arvo %c %info %luau
36+ %& [(into current-file 2 ~.cycled) %ins %lua !>((to-wain:format (crip printed)))]~
37+ ==
38+ ~& %parsing-printed
39+ =/ cycled-ast-unit (rust printed lua-parser)
40+ ?~ cycled-ast-unit (pure:m %err)
41+ ~& %comparing-asts
42+ ?. =(ast u.cycled-ast-unit) (pure:m %err)
43+ (pure:m %ok)
2244 ~& parse-result
2345 $(lua-files t.lua-files, res [parse-result res])
24−%- pure:m
46+%- pure:m
2547 !>
2648 :*
2749 passed=(lent (skim results |=(=test-result =(%ok test-result))))
@@ -29,4 +51,6 @@
2951 ==
3052|%
3153+$ test-result $?(%ok %err)
54+:: ++ rename-file
55+
3256--