on master help sign in
.
bee08e8iko
zod/luau/lib/lua/parser.hoon+3−3
@@ -179,8 +179,8 @@ apex
179 (cold %add (jest '+'))
179 (cold %add (jest '+'))
180 (cold %sub (jest '-'))
180 (cold %sub (jest '-'))
181 (cold %mul (jest '*'))
181 (cold %mul (jest '*'))
182− (cold %div (jest '/'))
183 (cold %int-div (jest '//'))
182 (cold %int-div (jest '//'))
183+ (cold %div (jest '/'))
184 (cold %pow (jest '^'))
184 (cold %pow (jest '^'))
185 (cold %mod (jest '%'))
185 (cold %mod (jest '%'))
186 (cold %band (jest '&'))
186 (cold %band (jest '&'))
@@ -809,8 +809,8 @@ apex
809 |* [=term gar=mold sef=rule]
809 |* [=term gar=mold sef=rule]
810 |= tub=nail
810 |= tub=nail
811 ^- (like gar)
811 ^- (like gar)
812− =/ trace &
812+ =/ trace |
813− ~? trace [term `tape`(scag 30 q.tub)]
813+ ~? trace [p.p.tub term `tape`(scag 30 q.tub)]
814 =/ res (sef tub)
814 =/ res (sef tub)
815 ?. trace res
815 ?. trace res
816 ?~ q.res
816 ?~ q.res
zod/luau/tests/attrib.luanew file+527
@@ -0,0 +1,527 @@
1+-- $Id: testes/attrib.lua $
2+-- See Copyright Notice in file all.lua
3+
4+print "testing require"
5+
6+assert(require"string" == string)
7+assert(require"math" == math)
8+assert(require"table" == table)
9+assert(require"io" == io)
10+assert(require"os" == os)
11+assert(require"coroutine" == coroutine)
12+
13+assert(type(package.path) == "string")
14+assert(type(package.cpath) == "string")
15+assert(type(package.loaded) == "table")
16+assert(type(package.preload) == "table")
17+
18+assert(type(package.config) == "string")
19+print("package config: "..string.gsub(package.config, "\n", "|"))
20+
21+do
22+ -- create a path with 'max' templates,
23+ -- each with 1-10 repetitions of '?'
24+ local max = _soft and 100 or 2000
25+ local t = {}
26+ for i = 1,max do t[i] = string.rep("?", i%10 + 1) end
27+ t[#t + 1] = ";" -- empty template
28+ local path = table.concat(t, ";")
29+ -- use that path in a search
30+ local s, err = package.searchpath("xuxu", path)
31+ -- search fails; check that message has an occurrence of
32+ -- '??????????' with ? replaced by xuxu and at least 'max' lines
33+ assert(not s and
34+ string.find(err, string.rep("xuxu", 10)) and
35+ #string.gsub(err, "[^\n]", "") >= max)
36+ -- path with one very long template
37+ local path = string.rep("?", max)
38+ local s, err = package.searchpath("xuxu", path)
39+ assert(not s and string.find(err, string.rep('xuxu', max)))
40+end
41+
42+do
43+ local oldpath = package.path
44+ package.path = {}
45+ local s, err = pcall(require, "no-such-file")
46+ assert(not s and string.find(err, "package.path"))
47+ package.path = oldpath
48+end
49+
50+
51+do print"testing 'require' message"
52+ local oldpath = package.path
53+ local oldcpath = package.cpath
54+
55+ package.path = "?.lua;?/?"
56+ package.cpath = "?.so;?/init"
57+
58+ local st, msg = pcall(require, 'XXX')
59+
60+ local expected = [[module 'XXX' not found:
61+ no field package.preload['XXX']
62+ no file 'XXX.lua'
63+ no file 'XXX/XXX'
64+ no file 'XXX.so'
65+ no file 'XXX/init']]
66+
67+ assert(msg == expected)
68+
69+ package.path = oldpath
70+ package.cpath = oldcpath
71+end
72+
73+print('+')
74+
75+
76+-- The next tests for 'require' assume some specific directories and
77+-- libraries.
78+
79+if not _port then --[
80+
81+local dirsep = string.match(package.config, "^([^\n]+)\n")
82+
83+-- auxiliary directory with C modules and temporary files
84+local DIR = "libs" .. dirsep
85+
86+-- prepend DIR to a name and correct directory separators
87+local function D (x)
88+ local x = string.gsub(x, "/", dirsep)
89+ return DIR .. x
90+end
91+
92+-- prepend DIR and pospend proper C lib. extension to a name
93+local function DC (x)
94+ local ext = (dirsep == '\\') and ".dll" or ".so"
95+ return D(x .. ext)
96+end
97+
98+
99+local function createfiles (files, preextras, posextras)
100+ for n,c in pairs(files) do
101+ io.output(D(n))
102+ io.write(string.format(preextras, n))
103+ io.write(c)
104+ io.write(string.format(posextras, n))
105+ io.close(io.output())
106+ end
107+end
108+
109+local function removefiles (files)
110+ for n in pairs(files) do
111+ os.remove(D(n))
112+ end
113+end
114+
115+local files = {
116+ ["names.lua"] = "do return {...} end\n",
117+ ["err.lua"] = "B = 15; a = a + 1;",
118+ ["synerr.lua"] = "B =",
119+ ["A.lua"] = "",
120+ ["B.lua"] = "assert(...=='B');require 'A'",
121+ ["A.lc"] = "",
122+ ["A"] = "",
123+ ["L"] = "",
124+ ["XXxX"] = "",
125+ ["C.lua"] = "package.loaded[...] = 25; require'C'",
126+}
127+
128+AA = nil
129+local extras = [[
130+NAME = '%s'
131+REQUIRED = ...
132+return AA]]
133+
134+createfiles(files, "", extras)
135+
136+-- testing explicit "dir" separator in 'searchpath'
137+assert(package.searchpath("C.lua", D"?", "", "") == D"C.lua")
138+assert(package.searchpath("C.lua", D"?", ".", ".") == D"C.lua")
139+assert(package.searchpath("--x-", D"?", "-", "X") == D"XXxX")
140+assert(package.searchpath("---xX", D"?", "---", "XX") == D"XXxX")
141+assert(package.searchpath(D"C.lua", "?", dirsep) == D"C.lua")
142+assert(package.searchpath(".\\C.lua", D"?", "\\") == D"./C.lua")
143+
144+local oldpath = package.path
145+
146+package.path = string.gsub("D/?.lua;D/?.lc;D/?;D/??x?;D/L", "D/", DIR)
147+
148+local try = function (p, n, r, ext)
149+ NAME = nil
150+ local rr, x = require(p)
151+ assert(NAME == n)
152+ assert(REQUIRED == p)
153+ assert(rr == r)
154+ assert(ext == x)
155+end
156+
157+local a = require"names"
158+assert(a[1] == "names" and a[2] == D"names.lua")
159+
160+local st, msg = pcall(require, "err")
161+assert(not st and string.find(msg, "arithmetic") and B == 15)
162+st, msg = pcall(require, "synerr")
163+assert(not st and string.find(msg, "error loading module"))
164+
165+assert(package.searchpath("C", package.path) == D"C.lua")
166+assert(require"C" == 25)
167+assert(require"C" == 25)
168+AA = nil
169+try('B', 'B.lua', true, "libs/B.lua")
170+assert(package.loaded.B)
171+assert(require"B" == true)
172+assert(package.loaded.A)
173+assert(require"C" == 25)
174+package.loaded.A = nil
175+try('B', nil, true, nil) -- should not reload package
176+try('A', 'A.lua', true, "libs/A.lua")
177+package.loaded.A = nil
178+os.remove(D'A.lua')
179+AA = {}
180+try('A', 'A.lc', AA, "libs/A.lc") -- now must find second option
181+assert(package.searchpath("A", package.path) == D"A.lc")
182+assert(require("A") == AA)
183+AA = false
184+try('K', 'L', false, "libs/L") -- default option
185+try('K', 'L', false, "libs/L") -- default option (should reload it)
186+assert(rawget(_G, "_REQUIREDNAME") == nil)
187+
188+AA = "x"
189+try("X", "XXxX", AA, "libs/XXxX")
190+
191+
192+removefiles(files)
193+NAME, REQUIRED, AA, B = nil
194+
195+
196+-- testing require of sub-packages
197+
198+local _G = _G
199+
200+package.path = string.gsub("D/?.lua;D/?/init.lua", "D/", DIR)
201+
202+files = {
203+ ["P1/init.lua"] = "AA = 10",
204+ ["P1/xuxu.lua"] = "AA = 20",
205+}
206+
207+createfiles(files, "_ENV = {}\n", "\nreturn _ENV\n")
208+AA = 0
209+
210+local m, ext = assert(require"P1")
211+assert(ext == "libs/P1/init.lua")
212+assert(AA == 0 and m.AA == 10)
213+assert(require"P1" == m)
214+assert(require"P1" == m)
215+
216+assert(package.searchpath("P1.xuxu", package.path) == D"P1/xuxu.lua")
217+m.xuxu, ext = assert(require"P1.xuxu")
218+assert(AA == 0 and m.xuxu.AA == 20)
219+assert(ext == "libs/P1/xuxu.lua")
220+assert(require"P1.xuxu" == m.xuxu)
221+assert(require"P1.xuxu" == m.xuxu)
222+assert(require"P1" == m and m.AA == 10)
223+
224+
225+removefiles(files)
226+AA = nil
227+
228+package.path = ""
229+assert(not pcall(require, "file_does_not_exist"))
230+package.path = "??\0?"
231+assert(not pcall(require, "file_does_not_exist1"))
232+
233+package.path = oldpath
234+
235+-- check 'require' error message
236+local fname = "file_does_not_exist2"
237+local m, err = pcall(require, fname)
238+for t in string.gmatch(package.path..";"..package.cpath, "[^;]+") do
239+ t = string.gsub(t, "?", fname)
240+ assert(string.find(err, t, 1, true))
241+end
242+
243+do -- testing 'package.searchers' not being a table
244+ local searchers = package.searchers
245+ package.searchers = 3
246+ local st, msg = pcall(require, 'a')
247+ assert(not st and string.find(msg, "must be a table"))
248+ package.searchers = searchers
249+end
250+
251+local function import(...)
252+ local f = {...}
253+ return function (m)
254+ for i=1, #f do m[f[i]] = _G[f[i]] end
255+ end
256+end
257+
258+-- cannot change environment of a C function
259+assert(not pcall(module, 'XUXU'))
260+
261+
262+
263+-- testing require of C libraries
264+
265+
266+local p = "" -- On Mac OS X, redefine this to "_"
267+
268+-- check whether loadlib works in this system
269+local st, err, when = package.loadlib(DC"lib1", "*")
270+if not st then
271+ local f, err, when = package.loadlib("donotexist", p.."xuxu")
272+ assert(not f and type(err) == "string" and when == "absent")
273+ ;(Message or print)('\n >>> cannot load dynamic library <<<\n')
274+ print(err, when)
275+else
276+ -- tests for loadlib
277+ local f = assert(package.loadlib(DC"lib1", p.."onefunction"))
278+ local a, b = f(15, 25)
279+ assert(a == 25 and b == 15)
280+
281+ f = assert(package.loadlib(DC"lib1", p.."anotherfunc"))
282+ assert(f(10, 20) == "10%20\n")
283+
284+ -- check error messages
285+ local f, err, when = package.loadlib(DC"lib1", p.."xuxu")
286+ assert(not f and type(err) == "string" and when == "init")
287+ f, err, when = package.loadlib("donotexist", p.."xuxu")
288+ assert(not f and type(err) == "string" and when == "open")
289+
290+ -- symbols from 'lib1' must be visible to other libraries
291+ f = assert(package.loadlib(DC"lib11", p.."luaopen_lib11"))
292+ assert(f() == "exported")
293+
294+ -- test C modules with prefixes in names
295+ package.cpath = DC"?"
296+ local lib2, ext = require"lib2-v2"
297+ assert(string.find(ext, "libs/lib2-v2", 1, true))
298+ -- check correct access to global environment and correct
299+ -- parameters
300+ assert(_ENV.x == "lib2-v2" and _ENV.y == DC"lib2-v2")
301+ assert(lib2.id("x") == true) -- a different "id" implementation
302+
303+ -- test C submodules
304+ local fs, ext = require"lib1.sub"
305+ assert(_ENV.x == "lib1.sub" and _ENV.y == DC"lib1")
306+ assert(string.find(ext, "libs/lib1", 1, true))
307+ assert(fs.id(45) == 45)
308+ _ENV.x, _ENV.y = nil
309+end
310+
311+_ENV = _G
312+
313+
314+-- testing preload
315+
316+do
317+ local p = package
318+ package = {}
319+ p.preload.pl = function (...)
320+ local _ENV = {...}
321+ function xuxu (x) return x+20 end
322+ return _ENV
323+ end
324+
325+ local pl, ext = require"pl"
326+ assert(require"pl" == pl)
327+ assert(pl.xuxu(10) == 30)
328+ assert(pl[1] == "pl" and pl[2] == ":preload:" and ext == ":preload:")
329+
330+ package = p
331+ assert(type(package.path) == "string")
332+end
333+
334+print('+')
335+
336+end --]
337+
338+print("testing assignments, logical operators, and constructors")
339+
340+local res, res2 = 27
341+
342+local a, b = 1, 2+3
343+assert(a==1 and b==5)
344+a={}
345+local function f() return 10, 11, 12 end
346+a.x, b, a[1] = 1, 2, f()
347+assert(a.x==1 and b==2 and a[1]==10)
348+a[f()], b, a[f()+3] = f(), a, 'x'
349+assert(a[10] == 10 and b == a and a[13] == 'x')
350+
351+do
352+ local f = function (n) local x = {}; for i=1,n do x[i]=i end;
353+ return table.unpack(x) end;
354+ local a,b,c
355+ a,b = 0, f(1)
356+ assert(a == 0 and b == 1)
357+ a,b = 0, f(1)
358+ assert(a == 0 and b == 1)
359+ a,b,c = 0,5,f(4)
360+ assert(a==0 and b==5 and c==1)
361+ a,b,c = 0,5,f(0)
362+ assert(a==0 and b==5 and c==nil)
363+end
364+
365+local a, b, c, d = 1 and nil, 1 or nil, (1 and (nil or 1)), 6
366+assert(not a and b and c and d==6)
367+
368+d = 20
369+a, b, c, d = f()
370+assert(a==10 and b==11 and c==12 and d==nil)
371+a,b = f(), 1, 2, 3, f()
372+assert(a==10 and b==1)
373+
374+assert(a<b == false and a>b == true)
375+assert((10 and 2) == 2)
376+assert((10 or 2) == 10)
377+assert((10 or assert(nil)) == 10)
378+assert(not (nil and assert(nil)))
379+assert((nil or "alo") == "alo")
380+assert((nil and 10) == nil)
381+assert((false and 10) == false)
382+assert((true or 10) == true)
383+assert((false or 10) == 10)
384+assert(false ~= nil)
385+assert(nil ~= false)
386+assert(not nil == true)
387+assert(not not nil == false)
388+assert(not not 1 == true)
389+assert(not not a == true)
390+assert(not not (6 or nil) == true)
391+assert(not not (nil and 56) == false)
392+assert(not not (nil and true) == false)
393+assert(not 10 == false)
394+assert(not {} == false)
395+assert(not 0.5 == false)
396+assert(not "x" == false)
397+
398+assert({} ~= {})
399+print('+')
400+
401+a = {}
402+a[true] = 20
403+a[false] = 10
404+assert(a[1<2] == 20 and a[1>2] == 10)
405+
406+function f(a) return a end
407+
408+local a = {}
409+for i=3000,-3000,-1 do a[i + 0.0] = i; end
410+a[10e30] = "alo"; a[true] = 10; a[false] = 20
411+assert(a[10e30] == 'alo' and a[not 1] == 20 and a[10<20] == 10)
412+for i=3000,-3000,-1 do assert(a[i] == i); end
413+a[print] = assert
414+a[f] = print
415+a[a] = a
416+assert(a[a][a][a][a][print] == assert)
417+a[print](a[a[f]] == a[print])
418+assert(not pcall(function () local a = {}; a[nil] = 10 end))
419+assert(not pcall(function () local a = {[nil] = 10} end))
420+assert(a[nil] == undef)
421+a = nil
422+
423+local a, b, c
424+a = {10,9,8,7,6,5,4,3,2; [-3]='a', [f]=print, a='a', b='ab'}
425+a, a.x, a.y = a, a[-3]
426+assert(a[1]==10 and a[-3]==a.a and a[f]==print and a.x=='a' and not a.y)
427+a[1], f(a)[2], b, c = {['alo']=assert}, 10, a[1], a[f], 6, 10, 23, f(a), 2
428+a[1].alo(a[2]==10 and b==10 and c==print)
429+
430+a.aVeryLongName012345678901234567890123456789012345678901234567890123456789 = 10
431+local function foo ()
432+ return a.aVeryLongName012345678901234567890123456789012345678901234567890123456789
433+end
434+assert(foo() == 10 and
435+a.aVeryLongName012345678901234567890123456789012345678901234567890123456789 ==
436+10)
437+
438+
439+do
440+ -- _ENV constant
441+ local function foo ()
442+ local _ENV <const> = 11
443+ X = "hi"
444+ end
445+ local st, msg = pcall(foo)
446+ assert(not st and string.find(msg, "number"))
447+end
448+
449+
450+-- test of large float/integer indices
451+
452+-- compute maximum integer where all bits fit in a float
453+local maxint = math.maxinteger
454+
455+-- trim (if needed) to fit in a float
456+while maxint ~= (maxint + 0.0) or (maxint - 1) ~= (maxint - 1.0) do
457+ maxint = maxint // 2
458+end
459+
460+local maxintF = maxint + 0.0 -- float version
461+
462+assert(maxintF == maxint and math.type(maxintF) == "float" and
463+ maxintF >= 2.0^14)
464+
465+-- floats and integers must index the same places
466+a[maxintF] = 10; a[maxintF - 1.0] = 11;
467+a[-maxintF] = 12; a[-maxintF + 1.0] = 13;
468+
469+assert(a[maxint] == 10 and a[maxint - 1] == 11 and
470+ a[-maxint] == 12 and a[-maxint + 1] == 13)
471+
472+a[maxint] = 20
473+a[-maxint] = 22
474+
475+assert(a[maxintF] == 20 and a[maxintF - 1.0] == 11 and
476+ a[-maxintF] == 22 and a[-maxintF + 1.0] == 13)
477+
478+a = nil
479+
480+
481+-- test conflicts in multiple assignment
482+do
483+ local a,i,j,b
484+ a = {'a', 'b'}; i=1; j=2; b=a
485+ i, a[i], a, j, a[j], a[i+j] = j, i, i, b, j, i
486+ assert(i == 2 and b[1] == 1 and a == 1 and j == b and b[2] == 2 and
487+ b[3] == 1)
488+ a = {}
489+ local function foo () -- assigining to upvalues
490+ b, a.x, a = a, 10, 20
491+ end
492+ foo()
493+ assert(a == 20 and b.x == 10)
494+end
495+
496+-- repeat test with upvalues
497+do
498+ local a,i,j,b
499+ a = {'a', 'b'}; i=1; j=2; b=a
500+ local function foo ()
501+ i, a[i], a, j, a[j], a[i+j] = j, i, i, b, j, i
502+ end
503+ foo()
504+ assert(i == 2 and b[1] == 1 and a == 1 and j == b and b[2] == 2 and
505+ b[3] == 1)
506+ local t = {}
507+ (function (a) t[a], a = 10, 20 end)(1);
508+ assert(t[1] == 10)
509+end
510+
511+-- bug in 5.2 beta
512+local function foo ()
513+ local a
514+ return function ()
515+ local b
516+ a, b = 3, 14 -- local and upvalue have same index
517+ return a, b
518+ end
519+end
520+
521+local a, b = foo()()
522+assert(a == 3 and b == 14)
523+
524+print('OK')
525+
526+return res
527+
zod/luau/tests/big.luanew file+82
@@ -0,0 +1,82 @@
1+-- $Id: testes/big.lua $
2+-- See Copyright Notice in file all.lua
3+
4+if _soft then
5+ return 'a'
6+end
7+
8+print "testing large tables"
9+
10+local debug = require"debug"
11+
12+local lim = 2^18 + 1000
13+local prog = { "local y = {0" }
14+for i = 1, lim do prog[#prog + 1] = i end
15+prog[#prog + 1] = "}\n"
16+prog[#prog + 1] = "X = y\n"
17+prog[#prog + 1] = ("assert(X[%d] == %d)"):format(lim - 1, lim - 2)
18+prog[#prog + 1] = "return 0"
19+prog = table.concat(prog, ";")
20+
21+local env = {string = string, assert = assert}
22+local f = assert(load(prog, nil, nil, env))
23+
24+f()
25+assert(env.X[lim] == lim - 1 and env.X[lim + 1] == lim)
26+for k in pairs(env) do env[k] = undef end
27+
28+-- yields during accesses larger than K (in RK)
29+setmetatable(env, {
30+ __index = function (t, n) coroutine.yield('g'); return _G[n] end,
31+ __newindex = function (t, n, v) coroutine.yield('s'); _G[n] = v end,
32+})
33+
34+X = nil
35+local co = coroutine.wrap(f)
36+assert(co() == 's')
37+assert(co() == 'g')
38+assert(co() == 'g')
39+assert(co() == 0)
40+
41+assert(X[lim] == lim - 1 and X[lim + 1] == lim)
42+
43+-- errors in accesses larger than K (in RK)
44+getmetatable(env).__index = function () end
45+getmetatable(env).__newindex = function () end
46+local e, m = pcall(f)
47+assert(not e and m:find("global 'X'"))
48+
49+-- errors in metamethods
50+getmetatable(env).__newindex = function () error("hi") end
51+local e, m = xpcall(f, debug.traceback)
52+assert(not e and m:find("'newindex'"))
53+
54+f, X = nil
55+
56+coroutine.yield'b'
57+
58+if 2^32 == 0 then -- (small integers) {
59+
60+print "testing string length overflow"
61+
62+local repstrings = 192 -- number of strings to be concatenated
63+local ssize = math.ceil(2.0^32 / repstrings) + 1 -- size of each string
64+
65+assert(repstrings * ssize > 2.0^32) -- it should be larger than maximum size
66+
67+local longs = string.rep("\0", ssize) -- create one long string
68+
69+-- create function to concatenate 'repstrings' copies of its argument
70+local rep = assert(load(
71+ "local a = ...; return " .. string.rep("a", repstrings, "..")))
72+
73+local a, b = pcall(rep, longs) -- call that function
74+
75+-- it should fail without creating string (result would be too large)
76+assert(not a and string.find(b, "overflow"))
77+
78+end -- }
79+
80+print'OK'
81+
82+return 'a'
zod/luau/tests/bitwise.luanew file+363
@@ -0,0 +1,363 @@
1+-- $Id: testes/bitwise.lua $
2+-- See Copyright Notice in file all.lua
3+
4+print("testing bitwise operations")
5+
6+require "bwcoercion"
7+
8+local numbits = string.packsize('j') * 8
9+
10+assert(~0 == -1)
11+
12+assert((1 << (numbits - 1)) == math.mininteger)
13+
14+-- basic tests for bitwise operators;
15+-- use variables to avoid constant folding
16+local a, b, c, d
17+a = 0xFFFFFFFFFFFFFFFF
18+assert(a == -1 and a & -1 == a and a & 35 == 35)
19+a = 0xF0F0F0F0F0F0F0F0
20+assert(a | -1 == -1)
21+assert(a ~ a == 0 and a ~ 0 == a and a ~ ~a == -1)
22+assert(a >> 4 == ~a)
23+a = 0xF0; b = 0xCC; c = 0xAA; d = 0xFD
24+assert(a | b ~ c & d == 0xF4)
25+
26+a = 0xF0.0; b = 0xCC.0; c = "0xAA.0"; d = "0xFD.0"
27+assert(a | b ~ c & d == 0xF4)
28+
29+a = 0xF0000000; b = 0xCC000000;
30+c = 0xAA000000; d = 0xFD000000
31+assert(a | b ~ c & d == 0xF4000000)
32+assert(~~a == a and ~a == -1 ~ a and -d == ~d + 1)
33+
34+a = a << 32
35+b = b << 32
36+c = c << 32
37+d = d << 32
38+assert(a | b ~ c & d == 0xF4000000 << 32)
39+assert(~~a == a and ~a == -1 ~ a and -d == ~d + 1)
40+
41+
42+do -- constant folding
43+ local code = string.format("return -1 >> %d", math.maxinteger)
44+ assert(load(code)() == 0)
45+ local code = string.format("return -1 >> %d", math.mininteger)
46+ assert(load(code)() == 0)
47+ local code = string.format("return -1 << %d", math.maxinteger)
48+ assert(load(code)() == 0)
49+ local code = string.format("return -1 << %d", math.mininteger)
50+ assert(load(code)() == 0)
51+end
52+
53+assert(-1 >> 1 == (1 << (numbits - 1)) - 1 and 1 << 31 == 0x80000000)
54+assert(-1 >> (numbits - 1) == 1)
55+assert(-1 >> numbits == 0 and
56+ -1 >> -numbits == 0 and
57+ -1 << numbits == 0 and
58+ -1 << -numbits == 0)
59+
60+assert(1 >> math.mininteger == 0)
61+assert(1 >> math.maxinteger == 0)
62+assert(1 << math.mininteger == 0)
63+assert(1 << math.maxinteger == 0)
64+
65+assert((2^30 - 1) << 2^30 == 0)
66+assert((2^30 - 1) >> 2^30 == 0)
67+
68+assert(1 >> -3 == 1 << 3 and 1000 >> 5 == 1000 << -5)
69+
70+
71+-- coercion from strings to integers
72+assert("0xffffffffffffffff" | 0 == -1)
73+assert("0xfffffffffffffffe" & "-1" == -2)
74+assert(" \t-0xfffffffffffffffe\n\t" & "-1" == 2)
75+assert(" \n -45 \t " >> " -2 " == -45 * 4)
76+assert("1234.0" << "5.0" == 1234 * 32)
77+assert("0xffff.0" ~ "0xAAAA" == 0x5555)
78+assert(~"0x0.000p4" == -1)
79+
80+assert(("7" .. 3) << 1 == 146)
81+assert(0xffffffff >> (1 .. "9") == 0x1fff)
82+assert(10 | (1 .. "9") == 27)
83+
84+do
85+ local st, msg = pcall(function () return 4 & "a" end)
86+ assert(string.find(msg, "'band'"))
87+
88+ local st, msg = pcall(function () return ~"a" end)
89+ assert(string.find(msg, "'bnot'"))
90+end
91+
92+
93+-- out of range number
94+assert(not pcall(function () return "0xffffffffffffffff.0" | 0 end))
95+
96+-- embedded zeros
97+assert(not pcall(function () return "0xffffffffffffffff\0" | 0 end))
98+
99+print'+'
100+
101+
102+package.preload.bit32 = function () --{
103+
104+-- no built-in 'bit32' library: implement it using bitwise operators
105+
106+local bit = {}
107+
108+function bit.bnot (a)
109+ return ~a & 0xFFFFFFFF
110+end
111+
112+
113+--
114+-- in all vararg functions, avoid creating 'arg' table when there are
115+-- only 2 (or less) parameters, as 2 parameters is the common case
116+--
117+
118+function bit.band (x, y, z, ...)
119+ if not z then
120+ return ((x or -1) & (y or -1)) & 0xFFFFFFFF
121+ else
122+ local arg = {...}
123+ local res = x & y & z
124+ for i = 1, #arg do res = res & arg[i] end
125+ return res & 0xFFFFFFFF
126+ end
127+end
128+
129+function bit.bor (x, y, z, ...)
130+ if not z then
131+ return ((x or 0) | (y or 0)) & 0xFFFFFFFF
132+ else
133+ local arg = {...}
134+ local res = x | y | z
135+ for i = 1, #arg do res = res | arg[i] end
136+ return res & 0xFFFFFFFF
137+ end
138+end
139+
140+function bit.bxor (x, y, z, ...)
141+ if not z then
142+ return ((x or 0) ~ (y or 0)) & 0xFFFFFFFF
143+ else
144+ local arg = {...}
145+ local res = x ~ y ~ z
146+ for i = 1, #arg do res = res ~ arg[i] end
147+ return res & 0xFFFFFFFF
148+ end
149+end
150+
151+function bit.btest (...)
152+ return bit.band(...) ~= 0
153+end
154+
155+function bit.lshift (a, b)
156+ return ((a & 0xFFFFFFFF) << b) & 0xFFFFFFFF
157+end
158+
159+function bit.rshift (a, b)
160+ return ((a & 0xFFFFFFFF) >> b) & 0xFFFFFFFF
161+end
162+
163+function bit.arshift (a, b)
164+ a = a & 0xFFFFFFFF
165+ if b <= 0 or (a & 0x80000000) == 0 then
166+ return (a >> b) & 0xFFFFFFFF
167+ else
168+ return ((a >> b) | ~(0xFFFFFFFF >> b)) & 0xFFFFFFFF
169+ end
170+end
171+
172+function bit.lrotate (a ,b)
173+ b = b & 31
174+ a = a & 0xFFFFFFFF
175+ a = (a << b) | (a >> (32 - b))
176+ return a & 0xFFFFFFFF
177+end
178+
179+function bit.rrotate (a, b)
180+ return bit.lrotate(a, -b)
181+end
182+
183+local function checkfield (f, w)
184+ w = w or 1
185+ assert(f >= 0, "field cannot be negative")
186+ assert(w > 0, "width must be positive")
187+ assert(f + w <= 32, "trying to access non-existent bits")
188+ return f, ~(-1 << w)
189+end
190+
191+function bit.extract (a, f, w)
192+ local f, mask = checkfield(f, w)
193+ return (a >> f) & mask
194+end
195+
196+function bit.replace (a, v, f, w)
197+ local f, mask = checkfield(f, w)
198+ v = v & mask
199+ a = (a & ~(mask << f)) | (v << f)
200+ return a & 0xFFFFFFFF
201+end
202+
203+return bit
204+
205+end --}
206+
207+
208+print("testing bitwise library")
209+
210+local bit32 = require'bit32'
211+
212+assert(bit32.band() == bit32.bnot(0))
213+assert(bit32.btest() == true)
214+assert(bit32.bor() == 0)
215+assert(bit32.bxor() == 0)
216+
217+assert(bit32.band() == bit32.band(0xffffffff))
218+assert(bit32.band(1,2) == 0)
219+
220+
221+-- out-of-range numbers
222+assert(bit32.band(-1) == 0xffffffff)
223+assert(bit32.band((1 << 33) - 1) == 0xffffffff)
224+assert(bit32.band(-(1 << 33) - 1) == 0xffffffff)
225+assert(bit32.band((1 << 33) + 1) == 1)
226+assert(bit32.band(-(1 << 33) + 1) == 1)
227+assert(bit32.band(-(1 << 40)) == 0)
228+assert(bit32.band(1 << 40) == 0)
229+assert(bit32.band(-(1 << 40) - 2) == 0xfffffffe)
230+assert(bit32.band((1 << 40) - 4) == 0xfffffffc)
231+
232+assert(bit32.lrotate(0, -1) == 0)
233+assert(bit32.lrotate(0, 7) == 0)
234+assert(bit32.lrotate(0x12345678, 0) == 0x12345678)
235+assert(bit32.lrotate(0x12345678, 32) == 0x12345678)
236+assert(bit32.lrotate(0x12345678, 4) == 0x23456781)
237+assert(bit32.rrotate(0x12345678, -4) == 0x23456781)
238+assert(bit32.lrotate(0x12345678, -8) == 0x78123456)
239+assert(bit32.rrotate(0x12345678, 8) == 0x78123456)
240+assert(bit32.lrotate(0xaaaaaaaa, 2) == 0xaaaaaaaa)
241+assert(bit32.lrotate(0xaaaaaaaa, -2) == 0xaaaaaaaa)
242+for i = -50, 50 do
243+ assert(bit32.lrotate(0x89abcdef, i) == bit32.lrotate(0x89abcdef, i%32))
244+end
245+
246+assert(bit32.lshift(0x12345678, 4) == 0x23456780)
247+assert(bit32.lshift(0x12345678, 8) == 0x34567800)
248+assert(bit32.lshift(0x12345678, -4) == 0x01234567)
249+assert(bit32.lshift(0x12345678, -8) == 0x00123456)
250+assert(bit32.lshift(0x12345678, 32) == 0)
251+assert(bit32.lshift(0x12345678, -32) == 0)
252+assert(bit32.rshift(0x12345678, 4) == 0x01234567)
253+assert(bit32.rshift(0x12345678, 8) == 0x00123456)
254+assert(bit32.rshift(0x12345678, 32) == 0)
255+assert(bit32.rshift(0x12345678, -32) == 0)
256+assert(bit32.arshift(0x12345678, 0) == 0x12345678)
257+assert(bit32.arshift(0x12345678, 1) == 0x12345678 // 2)
258+assert(bit32.arshift(0x12345678, -1) == 0x12345678 * 2)
259+assert(bit32.arshift(-1, 1) == 0xffffffff)
260+assert(bit32.arshift(-1, 24) == 0xffffffff)
261+assert(bit32.arshift(-1, 32) == 0xffffffff)
262+assert(bit32.arshift(-1, -1) == bit32.band(-1 * 2, 0xffffffff))
263+
264+assert(0x12345678 << 4 == 0x123456780)
265+assert(0x12345678 << 8 == 0x1234567800)
266+assert(0x12345678 << -4 == 0x01234567)
267+assert(0x12345678 << -8 == 0x00123456)
268+assert(0x12345678 << 32 == 0x1234567800000000)
269+assert(0x12345678 << -32 == 0)
270+assert(0x12345678 >> 4 == 0x01234567)
271+assert(0x12345678 >> 8 == 0x00123456)
272+assert(0x12345678 >> 32 == 0)
273+assert(0x12345678 >> -32 == 0x1234567800000000)
274+
275+print("+")
276+-- some special cases
277+local c = {0, 1, 2, 3, 10, 0x80000000, 0xaaaaaaaa, 0x55555555,
278+ 0xffffffff, 0x7fffffff}
279+
280+for _, b in pairs(c) do
281+ assert(bit32.band(b) == b)
282+ assert(bit32.band(b, b) == b)
283+ assert(bit32.band(b, b, b, b) == b)
284+ assert(bit32.btest(b, b) == (b ~= 0))
285+ assert(bit32.band(b, b, b) == b)
286+ assert(bit32.band(b, b, b, ~b) == 0)
287+ assert(bit32.btest(b, b, b) == (b ~= 0))
288+ assert(bit32.band(b, bit32.bnot(b)) == 0)
289+ assert(bit32.bor(b, bit32.bnot(b)) == bit32.bnot(0))
290+ assert(bit32.bor(b) == b)
291+ assert(bit32.bor(b, b) == b)
292+ assert(bit32.bor(b, b, b) == b)
293+ assert(bit32.bor(b, b, 0, ~b) == 0xffffffff)
294+ assert(bit32.bxor(b) == b)
295+ assert(bit32.bxor(b, b) == 0)
296+ assert(bit32.bxor(b, b, b) == b)
297+ assert(bit32.bxor(b, b, b, b) == 0)
298+ assert(bit32.bxor(b, 0) == b)
299+ assert(bit32.bnot(b) ~= b)
300+ assert(bit32.bnot(bit32.bnot(b)) == b)
301+ assert(bit32.bnot(b) == (1 << 32) - 1 - b)
302+ assert(bit32.lrotate(b, 32) == b)
303+ assert(bit32.rrotate(b, 32) == b)
304+ assert(bit32.lshift(bit32.lshift(b, -4), 4) == bit32.band(b, bit32.bnot(0xf)))
305+ assert(bit32.rshift(bit32.rshift(b, 4), -4) == bit32.band(b, bit32.bnot(0xf)))
306+end
307+
308+-- for this test, use at most 24 bits (mantissa of a single float)
309+c = {0, 1, 2, 3, 10, 0x800000, 0xaaaaaa, 0x555555, 0xffffff, 0x7fffff}
310+for _, b in pairs(c) do
311+ for i = -40, 40 do
312+ local x = bit32.lshift(b, i)
313+ local y = math.floor(math.fmod(b * 2.0^i, 2.0^32))
314+ assert(math.fmod(x - y, 2.0^32) == 0)
315+ end
316+end
317+
318+assert(not pcall(bit32.band, {}))
319+assert(not pcall(bit32.bnot, "a"))
320+assert(not pcall(bit32.lshift, 45))
321+assert(not pcall(bit32.lshift, 45, print))
322+assert(not pcall(bit32.rshift, 45, print))
323+
324+print("+")
325+
326+
327+-- testing extract/replace
328+
329+assert(bit32.extract(0x12345678, 0, 4) == 8)
330+assert(bit32.extract(0x12345678, 4, 4) == 7)
331+assert(bit32.extract(0xa0001111, 28, 4) == 0xa)
332+assert(bit32.extract(0xa0001111, 31, 1) == 1)
333+assert(bit32.extract(0x50000111, 31, 1) == 0)
334+assert(bit32.extract(0xf2345679, 0, 32) == 0xf2345679)
335+
336+assert(not pcall(bit32.extract, 0, -1))
337+assert(not pcall(bit32.extract, 0, 32))
338+assert(not pcall(bit32.extract, 0, 0, 33))
339+assert(not pcall(bit32.extract, 0, 31, 2))
340+
341+assert(bit32.replace(0x12345678, 5, 28, 4) == 0x52345678)
342+assert(bit32.replace(0x12345678, 0x87654321, 0, 32) == 0x87654321)
343+assert(bit32.replace(0, 1, 2) == 2^2)
344+assert(bit32.replace(0, -1, 4) == 2^4)
345+assert(bit32.replace(-1, 0, 31) == (1 << 31) - 1)
346+assert(bit32.replace(-1, 0, 1, 2) == (1 << 32) - 7)
347+
348+
349+-- testing conversion of floats
350+
351+assert(bit32.bor(3.0) == 3)
352+assert(bit32.bor(-4.0) == 0xfffffffc)
353+
354+-- large floats and large-enough integers?
355+if 2.0^50 < 2.0^50 + 1.0 and 2.0^50 < (-1 >> 1) then
356+ assert(bit32.bor(2.0^32 - 5.0) == 0xfffffffb)
357+ assert(bit32.bor(-2.0^32 - 6.0) == 0xfffffffa)
358+ assert(bit32.bor(2.0^48 - 5.0) == 0xfffffffb)
359+ assert(bit32.bor(-2.0^48 - 6.0) == 0xfffffffa)
360+end
361+
362+print'OK'
363+