My attempt at writing code to input values of arbitrary bitlength based on a bytearray in Factor. Any comments on the correctness or style would be appreciated.
USING: kernel locals accessors math sequences math.bitwise ;
TUPLE: bitreader bytearray curpos curbit ;
: <bitreader> ( bytearray -- bitreader ) 0 0 bitreader boa ;
: advance ( reader -- reader ) 0 >>curbit [ 1 + ] change-curpos ;
: check-advance ( reader -- reader ) dup curbit>> 8 = [ advance ] when ;
:: readsinglevalue ( bits reader -- result ) reader curpos>> reader bytearray>> nth
reader curbit>> dup bits 1 - + swap bit-range
reader [ bits + ] change-curbit check-advance drop ;
: bitsleft ( reader -- result ) curbit>> 8 swap - ;
DEFER: readbits
:: readmultivalue ( bits reader -- result ) reader bitsleft :> bitsextra
bitsextra reader readsinglevalue
bits bitsextra - reader readbits
bitsextra shift + ;
:: readbits ( bits reader -- result ) reader curbit>> bits + 8 < [ bits reader readsinglevalue ] [ bits reader readmultivalue ] if ;