mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-02-03 13:50:04 +08:00
187 lines
5.2 KiB
VimL
187 lines
5.2 KiB
VimL
" ___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('<sfile>'), '<SNR>\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('<SNR>%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:
|