" ___vital___ " NOTE: lines between '" ___vital___' is generated by :Vitalize. " Do not modify the code nor insert new lines before '" ___vital___' function! s:_SID() abort return matchstr(expand(''), '\zs\d\+\ze__SID$') endfunction execute join(['function! vital#_gina#Bitwise#import() abort', printf("return map({'uint8': '', 'rotate16l': '', 'uint16': '', 'rotate8l': '', 'rotate16r': '', 'uint32': '', 'rotate8r': '', '_vital_loaded': '', 'rshift': '', 'lshift': '', 'lshift32': '', 'rotate32l': '', 'rshift32': '', 'rotate32r': '', 'sign_extension': '', '_vital_created': '', 'rotate64l': '', 'compare': '', 'uint64': '', 'rotate64r': ''}, \"vital#_gina#function('%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n") delfunction s:_SID " ___vital___ " bitwise operators " moved from github.com/ynkdir/vim-funlib let s:save_cpo = &cpo set cpo&vim " inner utility let s:bits = has('num64') ? 64 : 32 let s:mask = s:bits - 1 let s:mask32 = 32 - 1 let s:pow2 = [1] for s:i in range(s:mask) call add(s:pow2, s:pow2[-1] * 2) endfor unlet s:i let s:min = s:pow2[-1] " 32bit/64bit common method function! s:_throw(msg) abort throw 'vital: Bitwise: ' . a:msg endfunction " compare as unsigned int function! s:compare(a, b) abort if (a:a >= 0 && a:b >= 0) || (a:a < 0 && a:b < 0) return a:a < a:b ? -1 : a:a > a:b ? 1 : 0 else return a:a < 0 ? 1 : -1 endif endfunction function! s:lshift(a, n) abort return a:a * s:pow2[and(a:n, s:mask)] endfunction function! s:rshift(a, n) abort let n = and(a:n, s:mask) return n == 0 ? a:a : \ a:a < 0 ? (a:a - s:min) / s:pow2[n] + s:pow2[-2] / s:pow2[n - 1] \ : a:a / s:pow2[n] endfunction " 32bit or 64bit specific method " define sign_extension " lshift32/rshift32 64bit only implementation. if has('num64') " NOTE: " An int literal larger than or equal to 0x8000000000000000 will be rounded " to 0x7FFFFFFFFFFFFFFF after Vim 8.0.0219, so create it without literal let s:xFFFFFFFF00000000 = 0xFFFFFFFF * s:pow2[and(32, s:mask)] function! s:sign_extension(n) abort if and(a:n, 0x80000000) return or(a:n, s:xFFFFFFFF00000000) else return and(a:n, 0xFFFFFFFF) endif endfunction function! s:lshift32(a, n) abort return and(s:lshift(a:a, and(a:n, s:mask32)), 0xFFFFFFFF) endfunction function! s:rshift32(a, n) abort return s:rshift(and(a:a, 0xFFFFFFFF), and(a:n, s:mask32)) endfunction else function! s:sign_extension(n) abort return a:n endfunction endif " 32bit or 64bit specific method " builtin and funcref setup at module creation time. " define and/or/xor/invert built-in " lshift32/rshift32 32bit only altnative define. function! s:_vital_created(module) abort for op in ['and', 'or', 'xor', 'invert'] let a:module[op] = function(op) let s:[op] = a:module[op] endfor if !has('num64') let a:module.lshift32 = a:module.lshift let a:module.rshift32 = a:module.rshift endif endfunction " setup at module loaded time. " define inner utility part2 : use defined method function! s:_vital_loaded(V) abort if has('num64') let s:mask32bit = 0xFFFFFFFF let s:mask64bit = or( \ s:lshift(s:mask32bit, 32), \ s:mask32bit \) else let s:mask32bit = or( \ s:lshift(0xFFFF, 16), \ 0xFFFF \) endif endfunction " 32bit/64bit common method part2 : use defined method function! s:uint8(value) abort return and(a:value, 0xFF) endfunction function! s:uint16(value) abort return and(a:value, 0xFFFF) endfunction function! s:uint32(value) abort return and(a:value, s:mask32bit) endfunction function! s:rotate8l(data, bits) abort let data = s:uint8(a:data) return s:uint8(or(s:lshift(data, a:bits), \ s:rshift(data, 8 - a:bits))) endfunction function! s:rotate8r(data, bits) abort return s:rotate8l(a:data, 8 - a:bits) endfunction function! s:rotate16l(data, bits) abort let data = s:uint16(a:data) return s:uint16(or(s:lshift(data, a:bits), \ s:rshift(data, 16 - a:bits))) endfunction function! s:rotate16r(data, bits) abort return s:rotate16l(a:data, 16 - a:bits) endfunction function! s:rotate32l(data, bits) abort let data = s:uint32(a:data) return s:uint32(or(s:lshift(data, a:bits), \ s:rshift(data, 32 - a:bits))) endfunction function! s:rotate32r(data, bits) abort return s:rotate32l(a:data, 32 - a:bits) endfunction " 32bit or 64bit specific method part2 : use defined method " define uint64/rotate64l 64bit only implementation. " 32bit throw exception. if has('num64') function! s:uint64(value) abort return and(a:value, s:mask64bit) endfunction function! s:rotate64l(data, bits) abort let data = s:uint64(a:data) return s:uint64(or(s:lshift(data, a:bits), \ s:rshift(data, 64 - a:bits))) endfunction else function! s:uint64(value) abort call s:_throw('64bit unsupport.') endfunction function! s:rotate64l(data, bits) abort call s:_throw('64bit unsupport.') endfunction endif " When 32bit throw exception. function! s:rotate64r(data, bits) abort return s:rotate64l(a:data, 64 - a:bits) endfunction let &cpo = s:save_cpo unlet s:save_cpo " vim:set et ts=2 sts=2 sw=2 tw=0: