bitstring icon indicating copy to clipboard operation
bitstring copied to clipboard

Error matching literal single bits

Open devesascampos opened this issue 1 year ago • 2 comments

(Apols in advance if I'm doing something really dumb)

Have (ppx_)bitstring version 4.1.0 on ocaml 4.11.2

<><> bitstring: information on all versions <><><><><><><><><><><><><><><><>  🐫 
name                   bitstring
all-installed-versions 4.1.0 [default]

Trying to match a bitstring bs with a pattern containing/consisting of a single literal bit fails:

# let bs = Bitstring.bitstring_of_string "a";;
val bs : Bitstring.bitstring = (Bytes.of_string "a", 0, 8)
# match%bitstring bs with | {| 0:1 |} -> "working";;
Error: This pattern matches values of type int
       but a pattern was expected which matches values of type bool

(the {| appears underlined)

In fact, something like the pattern_matcher example in documentation.md also fails

# let pattern_matcher = function%bitstring
  | {| 1 : 1
     ; a : 2
     ; b : 16 : bigendian
  |} -> true
  | {| _ |} -> false
  ;;
Error: This pattern matches values of type int
       but a pattern was expected which matches values of type bool

(the {| appears underlined)

Replacing the literal with a variable works

# match%bitstring bs with | {| x:1 |} -> "working";;
- : string = "working"

And then adding a check serves as a workaround to get the original intent

# match%bitstring bs with | {| x:1:check(x = false) |} -> "working";;
- : string = "working"

but is clunky.

devesascampos avatar Sep 15 '22 11:09 devesascampos

I understand if this is expected behaviour (and the example is wrong) and I should just use bools

# match%bitstring bs with | {| false:1: |} -> "working";;
- : string = "working"
# match%bitstring bs with | {| true:1: |} -> "working";;
Exception: Match_failure ("//toplevel//", 1, 0).

but to me it strikes me as weird to be able to match 0b01 but not 0b0 particularly when matching longer patterns that contain longer sections of literal bits.

devesascampos avatar Sep 15 '22 11:09 devesascampos

~Looks like an oversight, thanks for reporting. I'll look into it.~ The documentation is inaccurate. Since the migration to PPX, single-bit values are interpreted as bool. The following does work:

let match_bits_with_expected_values _ =
    (*
     * Create a string of bits.
     *)
    let bits = Bitstring.bitstring_of_string "a" in 
    (*
     * Match expected bits.
     *)
    let actual = match%bitstring bits with
     | {| false:1 ; true:1 ; _ : -1 : bitstring |} -> true
     | {| _ |} -> false
    in
    assert actual

xguerin avatar Sep 15 '22 11:09 xguerin

Thx for the clarification.

devesascampos avatar Sep 16 '22 13:09 devesascampos