4
\$\begingroup\$

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 ;
\$\endgroup\$
1
\$\begingroup\$

Honestly, the code seems a bit long for what it does. I'm not suggesting anything crazy like code golf, but is there maybe some way to unify (byte_position, bit_position) so a single call advances one bit at a time? I'm looking for a simple invariant that you maintain across calls. The read* functions appear to be on the verbose side.

You have at least four kinds of values: byte_val, bit_val, byte_pos, bit_pos. I encourage clear consistent naming around those. In particular the comments about leaving "result" on the stack are more vague than I'd like to see.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.