mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-15 08:52:00 +00:00
Lunatic: 'bitar': rewrite ops for colon syntax, serialization, set ops.
git-svn-id: https://svn.eduke32.com/eduke32@2862 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
569f0dbe7c
commit
f4c7e3f77e
5 changed files with 138 additions and 28 deletions
|
@ -170,7 +170,8 @@ ifneq (0,$(LUNATIC))
|
||||||
$(OBJ)/luaJIT_BC_lunacon.$o \
|
$(OBJ)/luaJIT_BC_lunacon.$o \
|
||||||
$(OBJ)/luaJIT_BC_geom.$o \
|
$(OBJ)/luaJIT_BC_geom.$o \
|
||||||
$(OBJ)/luaJIT_BC_randgen.$o \
|
$(OBJ)/luaJIT_BC_randgen.$o \
|
||||||
$(OBJ)/luaJIT_BC_stat.$o
|
$(OBJ)/luaJIT_BC_stat.$o \
|
||||||
|
$(OBJ)/luaJIT_BC_bitar.$o
|
||||||
|
|
||||||
# now, take care of having the necessary symbols (sector, wall, etc.) in the
|
# now, take care of having the necessary symbols (sector, wall, etc.) in the
|
||||||
# executable no matter what the debugging level
|
# executable no matter what the debugging level
|
||||||
|
|
|
@ -1,33 +1,18 @@
|
||||||
|
|
||||||
-- "Bit array" module based on LuaJIT's BitOp.
|
-- "Bit array" module based on LuaJIT's BitOp.
|
||||||
|
|
||||||
|
local ffi = require "ffi"
|
||||||
local bit = require "bit"
|
local bit = require "bit"
|
||||||
|
|
||||||
local error = error
|
local error = error
|
||||||
|
local assert = assert
|
||||||
local type = type
|
local type = type
|
||||||
|
|
||||||
|
local setmetatable=setmetatable
|
||||||
|
|
||||||
|
|
||||||
module(...)
|
module(...)
|
||||||
|
|
||||||
-- Create new bit array.
|
|
||||||
-- Returns a table p in which entries p[0] through p[floor((size+31)/32)]
|
|
||||||
-- are set to an initialization value: 0 if 0 has been passed, -1 if 1
|
|
||||||
-- has been passed.
|
|
||||||
function new(size, initval)
|
|
||||||
if (type(size) ~= "number" or size < 0) then
|
|
||||||
error("bad argument #1 to newarray (must be a nonnegative number)", 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
if (initval ~= 0 and initval ~= 1) then
|
|
||||||
error("bad argument #2 to newarray (must be either 0 or 1)", 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
local p = {}
|
|
||||||
for i=0,(size+31)/32 do
|
|
||||||
p[i] = -initval
|
|
||||||
end
|
|
||||||
|
|
||||||
return p
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Is bit i set in bit array ar?
|
-- Is bit i set in bit array ar?
|
||||||
function isset(ar, i)
|
function isset(ar, i)
|
||||||
|
@ -45,3 +30,109 @@ function set1(ar, j)
|
||||||
local jx = bit.rshift(j, 5)
|
local jx = bit.rshift(j, 5)
|
||||||
ar[jx] = bit.bor(ar[jx], bit.rol(0x00000001, j))
|
ar[jx] = bit.bor(ar[jx], bit.rol(0x00000001, j))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local ops = { isset=isset, set0=set0, set1=set1 }
|
||||||
|
local mt
|
||||||
|
mt = {
|
||||||
|
__index=ops,
|
||||||
|
|
||||||
|
-- set ops disguised as arithmetic ones...
|
||||||
|
|
||||||
|
__mul = function(ar1, ar2) -- set intersection
|
||||||
|
assert(#ar1 == #ar2)
|
||||||
|
local p = {}
|
||||||
|
for i=0,#ar1 do
|
||||||
|
p[i] = bit.band(ar1[i], ar2[i])
|
||||||
|
end
|
||||||
|
return setmetatable(p, mt)
|
||||||
|
end,
|
||||||
|
|
||||||
|
__add = function(ar1, ar2) -- set union
|
||||||
|
assert(#ar1 == #ar2)
|
||||||
|
local p = {}
|
||||||
|
for i=0,#ar1 do
|
||||||
|
p[i] = bit.bor(ar1[i], ar2[i])
|
||||||
|
end
|
||||||
|
return setmetatable(p, mt)
|
||||||
|
end,
|
||||||
|
|
||||||
|
__sub = function(ar1, ar2) -- set difference
|
||||||
|
assert(#ar1 == #ar2)
|
||||||
|
local p = {}
|
||||||
|
for i=0,#ar1 do
|
||||||
|
p[i] = bit.band(ar1[i], bit.bnot(ar2[i]))
|
||||||
|
end
|
||||||
|
return setmetatable(p, mt)
|
||||||
|
end,
|
||||||
|
|
||||||
|
-- serialization
|
||||||
|
__tostring = function(ar)
|
||||||
|
local maxidx=#ar
|
||||||
|
local size=maxidx+1
|
||||||
|
|
||||||
|
local hdr = "bitar.new('"
|
||||||
|
local ofs = #hdr
|
||||||
|
local totalstrlen = ofs+8*size+2
|
||||||
|
local str = ffi.new("char [?]", totalstrlen)
|
||||||
|
|
||||||
|
ffi.copy(str, hdr, ofs)
|
||||||
|
|
||||||
|
for i=0,maxidx do
|
||||||
|
-- 'a' is ASCII 97
|
||||||
|
for nib=0,7 do
|
||||||
|
str[ofs + 8*i + nib] = 97 + bit.band(bit.rshift(ar[i], 4*nib), 0x0000000f)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ffi.copy(str+totalstrlen-2, "')", 2)
|
||||||
|
|
||||||
|
return ffi.string(str, totalstrlen)
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Create new bit array.
|
||||||
|
-- Returns a table p in which entries p[0] through p[floor((maxbidx+31)/32)]
|
||||||
|
-- are set to an initialization value: 0 if 0 has been passed, -1 if 1
|
||||||
|
-- has been passed.
|
||||||
|
-- Storage: 4 bits/bit + O(1)? (per 32 bits: 64 bits key, 64 bits value)
|
||||||
|
function new(maxbidx, initval)
|
||||||
|
local p = {}
|
||||||
|
|
||||||
|
if (type(maxbidx)=="string") then
|
||||||
|
-- string containing hex digits (a..p) given, internal
|
||||||
|
local lstr = maxbidx
|
||||||
|
|
||||||
|
local numnibs = #lstr
|
||||||
|
assert(numnibs%8 == 0)
|
||||||
|
|
||||||
|
local size = numnibs/8
|
||||||
|
local maxidx = size-1
|
||||||
|
|
||||||
|
local str = ffi.new("char [?]", numnibs)
|
||||||
|
ffi.copy(str, lstr, numnibs)
|
||||||
|
|
||||||
|
for i=0,maxidx do
|
||||||
|
p[i] = 0
|
||||||
|
|
||||||
|
for nib=0,7 do
|
||||||
|
local hexdig = str[8*i + nib]
|
||||||
|
assert(hexdig >= 97 and hexdig < 97+16)
|
||||||
|
p[i] = bit.bor(p[i], bit.lshift(hexdig-97, 4*nib))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if (type(maxbidx) ~= "number" or not (maxbidx >= 0)) then
|
||||||
|
error("bad argument #1 to newarray (must be a nonnegative number)", 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
if (initval ~= 0 and initval ~= 1) then
|
||||||
|
error("bad argument #2 to newarray (must be either 0 or 1)", 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
for i=0,maxbidx/32 do
|
||||||
|
p[i] = -initval
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return setmetatable(p, mt)
|
||||||
|
end
|
||||||
|
|
|
@ -4,14 +4,14 @@
|
||||||
|
|
||||||
local string = require "string"
|
local string = require "string"
|
||||||
|
|
||||||
local getticks
|
|
||||||
|
|
||||||
local bit = require("bit")
|
local bit = require("bit")
|
||||||
local bitar = require "bitar"
|
local bitar = require "bitar"
|
||||||
|
|
||||||
local print = print
|
local print = print
|
||||||
local tonumber = tonumber
|
local tonumber = tonumber
|
||||||
|
|
||||||
|
local getticks
|
||||||
|
|
||||||
if (string.dump) then
|
if (string.dump) then
|
||||||
-- stand-alone
|
-- stand-alone
|
||||||
local os = require "os"
|
local os = require "os"
|
||||||
|
@ -27,8 +27,6 @@ end
|
||||||
|
|
||||||
-- based on example from http://bitop.luajit.org/api.html
|
-- based on example from http://bitop.luajit.org/api.html
|
||||||
|
|
||||||
local isset, set0 = bitar.isset, bitar.set0
|
|
||||||
|
|
||||||
local m = string.dump and tonumber(arg[1]) or 1e7
|
local m = string.dump and tonumber(arg[1]) or 1e7
|
||||||
|
|
||||||
local ffiar_p, boundchk_p = false, false
|
local ffiar_p, boundchk_p = false, false
|
||||||
|
@ -82,17 +80,35 @@ function sieve()
|
||||||
local t = getticks()
|
local t = getticks()
|
||||||
|
|
||||||
for i=2,m do
|
for i=2,m do
|
||||||
if (isset(p, i)) then
|
if (p:isset(i)) then
|
||||||
count = count + 1
|
count = count + 1
|
||||||
for j=i+i,m,i do set0(p, j); end
|
for j=i+i,m,i do p:set0(j); end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
print(string.format("[%s] Found %d primes up to %d (%.02f ms)",
|
print(string.format("[%s] Found %d primes up to %d (%.02f ms)",
|
||||||
ffiar_p and "ffi-ar"..(boundchk_p and ", bchk" or "") or "tab-ar",
|
ffiar_p and "ffi-ar"..(boundchk_p and ", bchk" or "") or "tab-ar",
|
||||||
count, m, getticks()-t))
|
count, m, getticks()-t))
|
||||||
|
|
||||||
|
return p
|
||||||
end
|
end
|
||||||
|
|
||||||
if (string.dump) then
|
if (string.dump) then
|
||||||
sieve()
|
local p = sieve()
|
||||||
|
local t = getticks()
|
||||||
|
|
||||||
|
-- test serialization
|
||||||
|
local p2 = bitar.new(string.match(tostring(p), "'(.*)'"))
|
||||||
|
print(getticks()-t)
|
||||||
|
|
||||||
|
for i=0,#p do
|
||||||
|
assert(p[i]==p2[i])
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 3,#p do
|
||||||
|
p[i] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
print(p)
|
||||||
|
print(p-p) -- test set difference
|
||||||
end
|
end
|
||||||
|
|
|
@ -548,6 +548,7 @@ local allowed_modules = {
|
||||||
randgen = require("randgen"),
|
randgen = require("randgen"),
|
||||||
geom = require("geom"),
|
geom = require("geom"),
|
||||||
stat = require("stat"),
|
stat = require("stat"),
|
||||||
|
bitar = require("bitar"),
|
||||||
}
|
}
|
||||||
|
|
||||||
local package_loaded = {}
|
local package_loaded = {}
|
||||||
|
|
|
@ -43,6 +43,7 @@ luaJIT_BC_con_lang;
|
||||||
luaJIT_BC_geom;
|
luaJIT_BC_geom;
|
||||||
luaJIT_BC_randgen;
|
luaJIT_BC_randgen;
|
||||||
luaJIT_BC_stat;
|
luaJIT_BC_stat;
|
||||||
|
luaJIT_BC_bitar;
|
||||||
|
|
||||||
rand_jkiss_u32;
|
rand_jkiss_u32;
|
||||||
rand_jkiss_dbl;
|
rand_jkiss_dbl;
|
||||||
|
|
Loading…
Reference in a new issue