141 lines
3.7 KiB
VimL
141 lines
3.7 KiB
VimL
" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim])
|
|
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
|
|
" @Revision: 124
|
|
|
|
|
|
function! tlib#bitwise#Num2Bits(num) "{{{3
|
|
if type(a:num) <= 1 || type(a:num) == 5
|
|
let bits = reverse(tlib#number#ConvertBase(a:num, 2, 'list'))
|
|
elseif type(a:num) == 3
|
|
let bits = copy(a:num)
|
|
else
|
|
throw "tlib#bitwise#Num2Bits: Must be number of list: ". string(a:num)
|
|
endif
|
|
return bits
|
|
endf
|
|
|
|
|
|
function! tlib#bitwise#Bits2Num(bits, ...) "{{{3
|
|
let base = a:0 >= 1 ? a:1 : 10
|
|
" TLogVAR a:bits
|
|
let num = 0.0
|
|
for i in range(len(a:bits))
|
|
if get(a:bits, i, 0)
|
|
let num += pow(2, i)
|
|
endif
|
|
endfor
|
|
" TLogVAR num
|
|
if base == 10
|
|
if type(base) == 5
|
|
return num
|
|
else
|
|
return float2nr(num)
|
|
endif
|
|
else
|
|
return tlib#number#ConvertBase(num, base)
|
|
endif
|
|
endf
|
|
|
|
|
|
function! tlib#bitwise#AND(num1, num2, ...) "{{{3
|
|
let rtype = a:0 >= 1 ? a:1 : 'num'
|
|
return s:BitwiseComparison(a:num1, a:num2, rtype,
|
|
\ 'get(bits1, v:val) && get(bits2, v:val)')
|
|
endf
|
|
|
|
|
|
function! tlib#bitwise#OR(num1, num2, ...) "{{{3
|
|
let rtype = a:0 >= 1 ? a:1 : 'num'
|
|
return s:BitwiseComparison(a:num1, a:num2, rtype,
|
|
\ 'get(bits1, v:val) || get(bits2, v:val)')
|
|
endf
|
|
|
|
|
|
function! tlib#bitwise#XOR(num1, num2, ...) "{{{3
|
|
let rtype = a:0 >= 1 ? a:1 : 'num'
|
|
return s:BitwiseComparison(a:num1, a:num2, rtype,
|
|
\ 'get(bits1, v:val) ? !get(bits2, v:val) : get(bits2, v:val)')
|
|
endf
|
|
|
|
|
|
function! s:BitwiseComparison(num1, num2, rtype, expr) "{{{3
|
|
let bits1 = tlib#bitwise#Num2Bits(a:num1)
|
|
let bits2 = tlib#bitwise#Num2Bits(a:num2)
|
|
let range = range(max([len(bits1), len(bits2)]))
|
|
let bits = map(range, a:expr)
|
|
if a:rtype == 'num' || (a:rtype == 'auto' && type(a:num1) <= 1)
|
|
return tlib#bitwise#Bits2Num(bits)
|
|
else
|
|
return bits
|
|
endif
|
|
endf
|
|
|
|
|
|
function! tlib#bitwise#ShiftRight(bits, n) "{{{3
|
|
let bits = a:bits[a:n : -1]
|
|
if empty(bits)
|
|
let bits = [0]
|
|
endif
|
|
return bits
|
|
endf
|
|
|
|
|
|
function! tlib#bitwise#ShiftLeft(bits, n) "{{{3
|
|
let bits = repeat([0], a:n) + a:bits
|
|
return bits
|
|
endf
|
|
|
|
|
|
function! tlib#bitwise#Add(num1, num2, ...) "{{{3
|
|
let rtype = a:0 >= 1 ? a:1 : 'num'
|
|
let bits1 = tlib#bitwise#Num2Bits(a:num1)
|
|
let bits2 = tlib#bitwise#Num2Bits(a:num2)
|
|
let range = range(max([len(bits1), len(bits2)]))
|
|
" TLogVAR bits1, bits2, range
|
|
let carry = 0
|
|
let bits = []
|
|
for i in range
|
|
let sum = get(bits1, i) + get(bits2, i) + carry
|
|
if sum == 3
|
|
let bit = 1
|
|
let carry = 1
|
|
elseif sum == 2
|
|
let bit = 0
|
|
let carry = 1
|
|
elseif sum == 1
|
|
let bit = 1
|
|
let carry = 0
|
|
elseif sum == 0
|
|
let bit = 0
|
|
let carry = 0
|
|
endif
|
|
call add(bits, bit)
|
|
" TLogVAR i, bits, bit
|
|
endfor
|
|
if carry == 1
|
|
call add(bits, carry)
|
|
endif
|
|
if rtype == 'num' || (rtype == 'auto' && type(a:num1) <= 1)
|
|
return tlib#bitwise#Bits2Num(bits)
|
|
else
|
|
return bits
|
|
endif
|
|
endf
|
|
|
|
|
|
function! tlib#bitwise#Sub(num1, num2, ...) "{{{3
|
|
let rtype = a:0 >= 1 ? a:1 : 'num'
|
|
let bits1 = tlib#bitwise#Num2Bits(a:num1)
|
|
let bits2 = tlib#bitwise#Num2Bits(a:num2)
|
|
let range = range(max([len(bits1), len(bits2)]))
|
|
let bits2 = map(range, '!get(bits2, v:val)')
|
|
let bits2 = tlib#bitwise#Add(bits2, [1], 'bits')
|
|
let bits3 = tlib#bitwise#Add(bits1, bits2, 'bits')
|
|
let bits = bits3[0 : -2]
|
|
if rtype == 'num' || (rtype == 'auto' && type(a:num1) <= 1)
|
|
return tlib#bitwise#Bits2Num(bits)
|
|
else
|
|
return bits
|
|
endif
|
|
endf
|
|
|