-- -- BITLIB_WRAP.LUA -- local m= {} Gluahost( 'bitlib_module', m ) ----- -- uint= hex'' ('str' contains 0..9,a..f,A..F, may start with '0x' -- -- Note: This is NOT optimal implementation. Use C if speed is critical. -- function m.hex( str ) -- local org_str= str local v= 0 local b0,ba,bs= string.byte("0"), string.byte("a"), string.byte(" ") local b str= string.lower(str) if (string.find( str, "^0x" )) then -- remove possible prefix str= string.sub( str,3 ) end if (not string.find( str, "^[0-9 a-f]+$" )) then -- allow internal spaces error( "Bad hex string: '".. org_str .."'!" ) end for i=1, string.len(str) do -- b= string.byte(str,i) if (b ~= bs) then -- b= (b>=ba) and (b-ba +10) or (b-b0) v= v*16 + b end end return v end ----- -- uint= bin'' ('str' contains 0..1) -- -- Note: This is NOT optimal implementation. Use C if speed is critical. -- function m.bin( str ) -- local org_str= str local v= 0 local c str= string.lower(str) if (not string.find( str, "^[0-1 ]+$" )) then -- allow internal spaces error( "Bad bin string: '".. org_str .."'!" ) end for i=1, string.len(str) do -- c= string.sub(str,i,i) if (c ~= ' ') then v= v*2 + ((c=='1') and 1 or 0) end end return v end ----- -- div_int, mod_int= idiv( a_int, b_int ) -- function m.idiv( a, b ) -- local div, mod ASSUME( math.floor(a) == a ) -- only for integers! ASSUME( math.floor(b) == b ) mod= math.mod( a, b ) div= (a-mod) / b; -- This is the invariant used: -- ASSUME( (div*b) + mod == a ) return div, mod end ----- -- str= hexstr( val_uint [,width_uint] ) -- function m.hexstr( val, width ) -- local ret ret= string.format( '%x', val ) if (width) then ret= string.rep("0", width-string.len(ret)) .. ret end return ret end ----- -- uint= bfield( val_uint, hi_uint [,lo_uint] ) -- -- Returns the numeric value of a bitfield from within an integer, taking -- care of both masking the other bits out _and_ shifting to 0..2^x-1 range. -- function m.bfield( val, hi, lo ) -- lo= lo or hi -- default: just one bit ASSUME( hi >= lo ) -- assume higher bit first (could also swap them!) return m.band( m.rshift(val,lo), 2^(hi-lo+1)-1 ) -- Also this would work, and does not need bitlib functions: -- --return math.floor( (val- math.floor(val/2^(hi+1))*2^(hi+1)) / 2^lo ) end ----- -- uint= bmap{ ..., [ {...} ] } -- -- Bitmap constructor, which returns an integer ('bor' of all the param bits) -- but looks like an object constructor. -- -- In the future, we could do a proper 'bmap' object thing (with bor, band -- operators in +,*) from this? -- function m.bmap( tbl ) -- if type(tbl)~="table" then return tbl end -- nil & numbers pass through local ret= 0 for _,v in tbl do -- bor() all values found in table & subtables.. -- if type(v)=="table" then ret= m.bor( ret,m.bmap(v) ) -- recursive elseif type(v)=="number" then ret= m.bor( ret,v ) else -- Catch 'nil' etc. within a bmap() table - may be due to a -- mistyped variable name? -- ASSUME(false) end end return ret end local raw_bor= m.bor -- the C module implementation function m.bor( ... ) -- if type(arg[1])=='table' then -- this one's for 'bmap'.. return m.bmap( arg ) else return raw_bor( unpack(arg) ) -- faster, directly to C. end end ----- -- uint= bset( flags_uint, ... ) -- uint= bclr( flags_uint, ... ) -- -- Setting and clearing a bitfield's bits. -- m.bset= ASSUME( m.bor ) function m.bclr( val, ... ) -- local mask=0 arg= arg or {} for _,v in arg do mask= m.bor( mask, v ) end return m.band( val, m.bnot(mask) ) -- clear the mask bits end return m