From eb2789137ffb5463209cb2d1bc878133627d49cf Mon Sep 17 00:00:00 2001 From: Martin Tomazic Date: Thu, 7 Sep 2023 16:12:19 +0200 Subject: [PATCH 1/5] Kaitai: Print attribute repeat specification --- contrib/kaitai-ocaml/src/print.ml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/contrib/kaitai-ocaml/src/print.ml b/contrib/kaitai-ocaml/src/print.ml index 63cf7483536e..264afd90084d 100644 --- a/contrib/kaitai-ocaml/src/print.ml +++ b/contrib/kaitai-ocaml/src/print.ml @@ -52,6 +52,8 @@ let mapping l = let ( @? ) x xs = match x with None -> xs | Some x -> x :: xs +let ( @@? ) xs ys = match xs with None -> ys | Some xs -> xs @ ys + let metaSpec (t : MetaSpec.t) = mapping @@ Option.map (fun id -> ("id", scalar id)) t.id @@ -80,6 +82,16 @@ let attr_type_if_not_any attr = if attr.AttrSpec.dataType = AnyType then None else Some ("type", scalar (DataType.to_string attr.AttrSpec.dataType)) +let repeat_spec = + let open RepeatSpec in + function + | NoRepeat -> None + | RepeatUntil expr -> + Some + (("repeat", scalar "until") + :: [("repeat-until", scalar (Ast.to_string expr))]) + | _ -> failwith "not supported" + let attr_spec attr = match attr.AttrSpec.dataType with (* [BytesType] attr require size header. *) @@ -95,7 +107,8 @@ let attr_spec attr = mapping (Some ("id", scalar attr.AttrSpec.id) @? attr_type_if_not_any attr - @? Option.map (fun enum -> ("enum", scalar enum)) attr.AttrSpec.enum + @? repeat_spec attr.cond.repeat + @@? Option.map (fun enum -> ("enum", scalar enum)) attr.AttrSpec.enum @? []); ] -- GitLab From d17d6d9503dc54f6b11629e0f5739cf74d302359 Mon Sep 17 00:00:00 2001 From: Martin Tomazic Date: Wed, 6 Sep 2023 16:37:32 +0200 Subject: [PATCH 2/5] Kaitai-ocaml: Define `byte_group` type for big numbers --- contrib/kaitai-ocaml/src/types.ml | 30 ++++++++++++++++++- contrib/lib_kaitai_of_data_encoding/ground.ml | 25 ++++++++++++++++ .../lib_kaitai_of_data_encoding/ground.mli | 11 +++++++ .../lib_kaitai_of_data_encoding/helpers.ml | 9 ++++++ .../lib_kaitai_of_data_encoding/helpers.mli | 4 +++ 5 files changed, 78 insertions(+), 1 deletion(-) diff --git a/contrib/kaitai-ocaml/src/types.ml b/contrib/kaitai-ocaml/src/types.ml index 4ee1ea08c669..2a6154509d26 100644 --- a/contrib/kaitai-ocaml/src/types.ml +++ b/contrib/kaitai-ocaml/src/types.ml @@ -45,10 +45,19 @@ module Ast = struct | BitXor | BitAnd + let operator_to_string = function + | BitAnd -> "&" + | RShift -> ">>" + | _ -> failwith "not implemented" + type unaryop = Invert | Not | Minus type cmpop = Eq | NotEq | Lt | LtE | Gt | GtE + let cmpop_to_string = function + | NotEq -> "!=" + | _ -> failwith "not implemented" + type t = | Raw of string | BoolOp of {op : boolop; values : t list} @@ -77,7 +86,26 @@ module Ast = struct type expr = t - let to_string = function Name name -> name | _ -> failwith "not implemented" + let rec to_string = function + | Name name -> name + | UnaryOp {op; operand} -> + (match op with + | Not -> "not" + | _ -> failwith "unary operator not supported") + ^ to_string operand + | BinOp {left; op; right} -> + Format.sprintf + "(%s %s %s)" + (to_string left) + (operator_to_string op) + (to_string right) + | Compare {left; ops; right} -> + Format.sprintf + "(%s %s %s)" + (to_string left) + (cmpop_to_string ops) + (to_string right) + | _ -> failwith "not implemented" end type processExpr = diff --git a/contrib/lib_kaitai_of_data_encoding/ground.ml b/contrib/lib_kaitai_of_data_encoding/ground.ml index 02388eb13609..3f538a4848da 100644 --- a/contrib/lib_kaitai_of_data_encoding/ground.ml +++ b/contrib/lib_kaitai_of_data_encoding/ground.ml @@ -187,4 +187,29 @@ module Class = struct let bytes ~encoding_name = class_spec_of_attr ~encoding_name Attr.bytes let string ~encoding_name = class_spec_of_attr ~encoding_name Attr.string + + let byte_group = + { + (default_class_spec ~encoding_name:"group") with + seq = [{Attr.u1 with id = "b"}]; + instances = + [ + ( "has_next", + default_instance_spec + ~id:"has_next" + Ast.( + Compare + { + left = + BinOp {left = Name "b"; op = BitAnd; right = IntNum 128}; + ops = NotEq; + right = IntNum 0; + }) ); + ( "value", + default_instance_spec + ~id:"value" + (BinOp {left = Name "b"; op = BitAnd; right = IntNum 127}) ); + ]; + isTopLevel = false; + } end diff --git a/contrib/lib_kaitai_of_data_encoding/ground.mli b/contrib/lib_kaitai_of_data_encoding/ground.mli index a2868362c025..c14112ee5ca2 100644 --- a/contrib/lib_kaitai_of_data_encoding/ground.mli +++ b/contrib/lib_kaitai_of_data_encoding/ground.mli @@ -109,4 +109,15 @@ module Class : sig (** [string] returns [ClassSpec.t] definition of [Data_encoding.string]. *) val string : encoding_name:string -> ClassSpec.t + + (** [byte_group] represents a user defined type for a variable-length sequence + of bytes encoding a Zarith natural number. It is used for describing + encoding such as [Data_encoding.Z] and [Data_encoding.N]. + + As from the [Data_encoding] documentation: "each byte has a running unary + size bit: the most significant bit of each byte indicates whether this is + the last byte in the sequence (0) or whether the sequence continues (1). + Size bits ignored, the data is the binary representation of the number + in little-endian order." *) + val byte_group : ClassSpec.t end diff --git a/contrib/lib_kaitai_of_data_encoding/helpers.ml b/contrib/lib_kaitai_of_data_encoding/helpers.ml index bc3936f9e123..543115650072 100644 --- a/contrib/lib_kaitai_of_data_encoding/helpers.ml +++ b/contrib/lib_kaitai_of_data_encoding/helpers.ml @@ -80,3 +80,12 @@ let types_field_from_attr_seq attributes = let class_spec_of_attr ~encoding_name ?(enums = []) attr = let types = types_field_from_attr_seq [attr] in {(default_class_spec ~encoding_name) with seq = [attr]; enums; types} + +let default_instance_spec ~id value = + InstanceSpec. + { + doc = default_doc_spec; + descr = + InstanceSpec.ValueInstanceSpec + {id; path = []; value; ifExpr = None; dataTypeOpt = None}; + } diff --git a/contrib/lib_kaitai_of_data_encoding/helpers.mli b/contrib/lib_kaitai_of_data_encoding/helpers.mli index dbc9a4e5380b..9b0f5a9e6c3c 100644 --- a/contrib/lib_kaitai_of_data_encoding/helpers.mli +++ b/contrib/lib_kaitai_of_data_encoding/helpers.mli @@ -74,3 +74,7 @@ val class_spec_of_attr : ?enums:(string * EnumSpec.t) list -> AttrSpec.t -> ClassSpec.t + +(** [default_instance_spec ~id expr] returns a default instance specification for + of a given [id] and [expr]. *) +val default_instance_spec : id:string -> Ast.t -> InstanceSpec.t -- GitLab From 31af11e4f992c8d65eeb99f6451010a32f1327b5 Mon Sep 17 00:00:00 2001 From: Martin Tomazic Date: Thu, 7 Sep 2023 13:40:18 +0200 Subject: [PATCH 3/5] Kaitai: e2e translation for big numbers (Data_encoding.N) --- contrib/bin_codec_kaitai/kaitai.t | 20 +++++++++++++ contrib/kaitai-ocaml/src/print.ml | 6 +++- contrib/kaitai-ocaml/src/types.ml | 9 +++--- contrib/kaitai-struct-files/ground__N.ksy | 18 ++++++++++++ contrib/lib_kaitai_of_data_encoding/ground.ml | 23 +++++++++++++++ .../lib_kaitai_of_data_encoding/ground.mli | 3 ++ .../test/test_translation_of_ground_types.ml | 29 +++++++++++++++++++ .../lib_kaitai_of_data_encoding/translate.ml | 1 + 8 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 contrib/kaitai-struct-files/ground__N.ksy diff --git a/contrib/bin_codec_kaitai/kaitai.t b/contrib/bin_codec_kaitai/kaitai.t index 59b61eed6ff3..bf5b7e63c192 100644 --- a/contrib/bin_codec_kaitai/kaitai.t +++ b/contrib/bin_codec_kaitai/kaitai.t @@ -105,3 +105,23 @@ ground.string test seq: - id: fixed size (uint30) bytes type: fixed_bytes +ground.N test + $ ./codec.exe dump kaitai for ground.N + meta: + id: ground__N + endian: be + types: + group: + instances: + has_next: + value: ((b & 128) != 0) + value: + value: (b & 127) + seq: + - id: b + type: u1 + seq: + - id: groups + type: group + repeat: until + repeat-until: not (_.has_next) diff --git a/contrib/kaitai-ocaml/src/print.ml b/contrib/kaitai-ocaml/src/print.ml index 264afd90084d..a079ba680767 100644 --- a/contrib/kaitai-ocaml/src/print.ml +++ b/contrib/kaitai-ocaml/src/print.ml @@ -62,7 +62,11 @@ let metaSpec (t : MetaSpec.t) = t.endian @? [] -let instanceSpec _ = mapping [("test", scalar "test")] +let instanceSpec InstanceSpec.{doc = _; descr} = + match descr with + | ValueInstanceSpec instance -> + mapping [("value", scalar (Ast.to_string instance.value))] + | ParseInstanceSpec -> failwith "not supported" let instances_spec instances = mapping (instances |> List.map (fun (k, v) -> (k, instanceSpec v))) diff --git a/contrib/kaitai-ocaml/src/types.ml b/contrib/kaitai-ocaml/src/types.ml index 2a6154509d26..3eadd60c90eb 100644 --- a/contrib/kaitai-ocaml/src/types.ml +++ b/contrib/kaitai-ocaml/src/types.ml @@ -87,12 +87,12 @@ module Ast = struct type expr = t let rec to_string = function + | IntNum n -> Int.to_string n | Name name -> name - | UnaryOp {op; operand} -> - (match op with - | Not -> "not" + | UnaryOp {op; operand} -> ( + match op with + | Not -> "not " ^ to_string operand | _ -> failwith "unary operator not supported") - ^ to_string operand | BinOp {left; op; right} -> Format.sprintf "(%s %s %s)" @@ -105,6 +105,7 @@ module Ast = struct (to_string left) (cmpop_to_string ops) (to_string right) + | Attribute {value; attr} -> Format.sprintf "(%s.%s)" (to_string value) attr | _ -> failwith "not implemented" end diff --git a/contrib/kaitai-struct-files/ground__N.ksy b/contrib/kaitai-struct-files/ground__N.ksy new file mode 100644 index 000000000000..a98ec779c262 --- /dev/null +++ b/contrib/kaitai-struct-files/ground__N.ksy @@ -0,0 +1,18 @@ +meta: + id: ground__N + endian: be +types: + group: + instances: + has_next: + value: ((b & 128) != 0) + value: + value: (b & 127) + seq: + - id: b + type: u1 +seq: +- id: groups + type: group + repeat: until + repeat-until: not (_.has_next) diff --git a/contrib/lib_kaitai_of_data_encoding/ground.ml b/contrib/lib_kaitai_of_data_encoding/ground.ml index 3f538a4848da..08cbfee2b96d 100644 --- a/contrib/lib_kaitai_of_data_encoding/ground.ml +++ b/contrib/lib_kaitai_of_data_encoding/ground.ml @@ -212,4 +212,27 @@ module Class = struct ]; isTopLevel = false; } + + let repeat_until_end_bytes_group_attr = + { + default_attr_spec with + id = "groups"; + dataType = DataType.(ComplexDataType (UserType byte_group)); + cond = + AttrSpec.ConditionalSpec. + { + ifExpr = None; + repeat = + RepeatSpec.RepeatUntil + Ast.( + UnaryOp + { + op = Not; + operand = Attribute {value = Name "_"; attr = "has_next"}; + }); + }; + } + + let n ~encoding_name = + class_spec_of_attr ~encoding_name repeat_until_end_bytes_group_attr end diff --git a/contrib/lib_kaitai_of_data_encoding/ground.mli b/contrib/lib_kaitai_of_data_encoding/ground.mli index c14112ee5ca2..81da5d11812a 100644 --- a/contrib/lib_kaitai_of_data_encoding/ground.mli +++ b/contrib/lib_kaitai_of_data_encoding/ground.mli @@ -120,4 +120,7 @@ module Class : sig Size bits ignored, the data is the binary representation of the number in little-endian order." *) val byte_group : ClassSpec.t + + (** [n] returns [ClassSpec.t] for [Data_encoding.N]. *) + val n : encoding_name:string -> ClassSpec.t end diff --git a/contrib/lib_kaitai_of_data_encoding/test/test_translation_of_ground_types.ml b/contrib/lib_kaitai_of_data_encoding/test/test_translation_of_ground_types.ml index 59348c1146b2..88a301299401 100644 --- a/contrib/lib_kaitai_of_data_encoding/test/test_translation_of_ground_types.ml +++ b/contrib/lib_kaitai_of_data_encoding/test/test_translation_of_ground_types.ml @@ -232,3 +232,32 @@ let%expect_test "test fixed size string translation" = - id: fixed size (uint30) bytes type: fixed_bytes |}] + +let%expect_test "test big numbers translation" = + let s = + Kaitai_of_data_encoding.Translate.from_data_encoding + ~encoding_name:"ground_n" + Data_encoding.n + in + print_endline (Kaitai.Print.print s) ; + [%expect + {| + meta: + id: ground_n + endian: be + types: + group: + instances: + has_next: + value: ((b & 128) != 0) + value: + value: (b & 127) + seq: + - id: b + type: u1 + seq: + - id: groups + type: group + repeat: until + repeat-until: not (_.has_next) + |}] diff --git a/contrib/lib_kaitai_of_data_encoding/translate.ml b/contrib/lib_kaitai_of_data_encoding/translate.ml index 1d3a798d6b7d..3e5514abe038 100644 --- a/contrib/lib_kaitai_of_data_encoding/translate.ml +++ b/contrib/lib_kaitai_of_data_encoding/translate.ml @@ -77,6 +77,7 @@ let rec from_data_encoding : | Float -> Ground.Class.float ~encoding_name | Bytes (_kind_length, _) -> Ground.Class.bytes ~encoding_name | String (_kind_length, _) -> Ground.Class.string ~encoding_name + | N -> Ground.Class.n ~encoding_name | Tup e -> (* Naked Tup likely due to [tup1]. We simply ignore this constructor. *) from_data_encoding ~encoding_name e -- GitLab From 87e96e1b2c68e7a4de90c213967d39fa48448b5a Mon Sep 17 00:00:00 2001 From: Martin Tomazic Date: Tue, 12 Sep 2023 16:26:37 +0200 Subject: [PATCH 4/5] Kaitai: e2e translation for big numbers (Data_encoding.Z) --- contrib/bin_codec_kaitai/kaitai.t | 23 +++++++++++++ contrib/kaitai-ocaml/src/types.ml | 3 ++ .../007-PsDELPH1__gas__cost.ksy | 21 ++++++++++++ .../008-PtEdo2Zk__gas__cost.ksy | 21 ++++++++++++ contrib/kaitai-struct-files/ground__Z.ksy | 21 ++++++++++++ contrib/lib_kaitai_of_data_encoding/ground.ml | 33 +++++++++++++++++++ .../lib_kaitai_of_data_encoding/ground.mli | 3 ++ .../lib_kaitai_of_data_encoding/helpers.ml | 10 ++++-- .../lib_kaitai_of_data_encoding/helpers.mli | 8 +++-- .../test/test_translation_of_ground_types.ml | 32 ++++++++++++++++++ .../lib_kaitai_of_data_encoding/translate.ml | 1 + 11 files changed, 171 insertions(+), 5 deletions(-) create mode 100644 contrib/kaitai-struct-files/007-PsDELPH1__gas__cost.ksy create mode 100644 contrib/kaitai-struct-files/008-PtEdo2Zk__gas__cost.ksy create mode 100644 contrib/kaitai-struct-files/ground__Z.ksy diff --git a/contrib/bin_codec_kaitai/kaitai.t b/contrib/bin_codec_kaitai/kaitai.t index bf5b7e63c192..1bfaa2a6bfc4 100644 --- a/contrib/bin_codec_kaitai/kaitai.t +++ b/contrib/bin_codec_kaitai/kaitai.t @@ -125,3 +125,26 @@ ground.N test type: group repeat: until repeat-until: not (_.has_next) +ground.Z test + $ ./codec.exe dump kaitai for ground.Z + meta: + id: ground__Z + endian: be + types: + group: + instances: + has_next: + value: ((b & 128) != 0) + value: + value: (b & 127) + seq: + - id: b + type: u1 + instances: + is_negative: + value: (((groups[0].value) >> 6) == 1) + seq: + - id: groups + type: group + repeat: until + repeat-until: not (_.has_next) diff --git a/contrib/kaitai-ocaml/src/types.ml b/contrib/kaitai-ocaml/src/types.ml index 3eadd60c90eb..7d85178b69b7 100644 --- a/contrib/kaitai-ocaml/src/types.ml +++ b/contrib/kaitai-ocaml/src/types.ml @@ -56,6 +56,7 @@ module Ast = struct let cmpop_to_string = function | NotEq -> "!=" + | Eq -> "==" | _ -> failwith "not implemented" type t = @@ -106,6 +107,8 @@ module Ast = struct (cmpop_to_string ops) (to_string right) | Attribute {value; attr} -> Format.sprintf "(%s.%s)" (to_string value) attr + | Subscript {value; idx} -> + Format.sprintf "%s[%s]" (to_string value) (to_string idx) | _ -> failwith "not implemented" end diff --git a/contrib/kaitai-struct-files/007-PsDELPH1__gas__cost.ksy b/contrib/kaitai-struct-files/007-PsDELPH1__gas__cost.ksy new file mode 100644 index 000000000000..7e2222e3a5c4 --- /dev/null +++ b/contrib/kaitai-struct-files/007-PsDELPH1__gas__cost.ksy @@ -0,0 +1,21 @@ +meta: + id: 007-PsDELPH1__gas__cost + endian: be +types: + group: + instances: + has_next: + value: ((b & 128) != 0) + value: + value: (b & 127) + seq: + - id: b + type: u1 +instances: + is_negative: + value: (((groups[0].value) >> 6) == 1) +seq: +- id: groups + type: group + repeat: until + repeat-until: not (_.has_next) diff --git a/contrib/kaitai-struct-files/008-PtEdo2Zk__gas__cost.ksy b/contrib/kaitai-struct-files/008-PtEdo2Zk__gas__cost.ksy new file mode 100644 index 000000000000..68b4ba542c00 --- /dev/null +++ b/contrib/kaitai-struct-files/008-PtEdo2Zk__gas__cost.ksy @@ -0,0 +1,21 @@ +meta: + id: 008-PtEdo2Zk__gas__cost + endian: be +types: + group: + instances: + has_next: + value: ((b & 128) != 0) + value: + value: (b & 127) + seq: + - id: b + type: u1 +instances: + is_negative: + value: (((groups[0].value) >> 6) == 1) +seq: +- id: groups + type: group + repeat: until + repeat-until: not (_.has_next) diff --git a/contrib/kaitai-struct-files/ground__Z.ksy b/contrib/kaitai-struct-files/ground__Z.ksy new file mode 100644 index 000000000000..bb1605a3ab2d --- /dev/null +++ b/contrib/kaitai-struct-files/ground__Z.ksy @@ -0,0 +1,21 @@ +meta: + id: ground__Z + endian: be +types: + group: + instances: + has_next: + value: ((b & 128) != 0) + value: + value: (b & 127) + seq: + - id: b + type: u1 +instances: + is_negative: + value: (((groups[0].value) >> 6) == 1) +seq: +- id: groups + type: group + repeat: until + repeat-until: not (_.has_next) diff --git a/contrib/lib_kaitai_of_data_encoding/ground.ml b/contrib/lib_kaitai_of_data_encoding/ground.ml index 08cbfee2b96d..b27df117b333 100644 --- a/contrib/lib_kaitai_of_data_encoding/ground.ml +++ b/contrib/lib_kaitai_of_data_encoding/ground.ml @@ -235,4 +235,37 @@ module Class = struct let n ~encoding_name = class_spec_of_attr ~encoding_name repeat_until_end_bytes_group_attr + + let z ~encoding_name = + let instances = + [ + ( "is_negative", + default_instance_spec + ~id:"is_negative" + Ast.( + Compare + { + left = + BinOp + { + left = + Attribute + { + value = + Subscript + {value = Name "groups"; idx = IntNum 0}; + attr = "value"; + }; + op = RShift; + right = IntNum 6; + }; + ops = Eq; + right = IntNum 1; + }) ); + ] + in + class_spec_of_attr + ~encoding_name + repeat_until_end_bytes_group_attr + ~instances end diff --git a/contrib/lib_kaitai_of_data_encoding/ground.mli b/contrib/lib_kaitai_of_data_encoding/ground.mli index 81da5d11812a..c37667850a0a 100644 --- a/contrib/lib_kaitai_of_data_encoding/ground.mli +++ b/contrib/lib_kaitai_of_data_encoding/ground.mli @@ -123,4 +123,7 @@ module Class : sig (** [n] returns [ClassSpec.t] for [Data_encoding.N]. *) val n : encoding_name:string -> ClassSpec.t + + (** [z] returns [ClassSpec.t] for [Data_encoding.Z]. *) + val z : encoding_name:string -> ClassSpec.t end diff --git a/contrib/lib_kaitai_of_data_encoding/helpers.ml b/contrib/lib_kaitai_of_data_encoding/helpers.ml index 543115650072..3e4abcb5ad41 100644 --- a/contrib/lib_kaitai_of_data_encoding/helpers.ml +++ b/contrib/lib_kaitai_of_data_encoding/helpers.ml @@ -77,9 +77,15 @@ let types_field_from_attr_seq attributes = in List.fold_left add_uniq_assoc [] types -let class_spec_of_attr ~encoding_name ?(enums = []) attr = +let class_spec_of_attr ~encoding_name ?(enums = []) ?(instances = []) attr = let types = types_field_from_attr_seq [attr] in - {(default_class_spec ~encoding_name) with seq = [attr]; enums; types} + { + (default_class_spec ~encoding_name) with + seq = [attr]; + enums; + types; + instances; + } let default_instance_spec ~id value = InstanceSpec. diff --git a/contrib/lib_kaitai_of_data_encoding/helpers.mli b/contrib/lib_kaitai_of_data_encoding/helpers.mli index 9b0f5a9e6c3c..b05350bdb992 100644 --- a/contrib/lib_kaitai_of_data_encoding/helpers.mli +++ b/contrib/lib_kaitai_of_data_encoding/helpers.mli @@ -60,18 +60,20 @@ val default_class_spec : encoding_name:string -> ClassSpec.t as but a different value than [kv]. *) val add_uniq_assoc : (string * 'a) list -> string * 'a -> (string * 'a) list -(** [class_spec_of_attr ~encoding_name ?enums attr] returns a [ClassSpet.t] - for [attr]. +(** [class_spec_of_attr ~encoding_name ?enums ?instances attr] returns a + [ClassSpec.t] for [attr]. In case of [attr] being of [ComplexDataType UserType _] type, then [types] section of returned [ClassSpec.t] is automatically populated with an appropriate type. @param ~encoding_name is added to meta section as [id]. - @param ?enums is added to class specification if present. *) + @param ?enums is added to class specification if present. + @param ?instances is added to class specification if present. *) val class_spec_of_attr : encoding_name:string -> ?enums:(string * EnumSpec.t) list -> + ?instances:(string * InstanceSpec.t) list -> AttrSpec.t -> ClassSpec.t diff --git a/contrib/lib_kaitai_of_data_encoding/test/test_translation_of_ground_types.ml b/contrib/lib_kaitai_of_data_encoding/test/test_translation_of_ground_types.ml index 88a301299401..bc07f8280463 100644 --- a/contrib/lib_kaitai_of_data_encoding/test/test_translation_of_ground_types.ml +++ b/contrib/lib_kaitai_of_data_encoding/test/test_translation_of_ground_types.ml @@ -261,3 +261,35 @@ let%expect_test "test big numbers translation" = repeat: until repeat-until: not (_.has_next) |}] + +let%expect_test "test big numbers translation" = + let s = + Kaitai_of_data_encoding.Translate.from_data_encoding + ~encoding_name:"ground_z" + Data_encoding.z + in + print_endline (Kaitai.Print.print s) ; + [%expect + {| + meta: + id: ground_z + endian: be + types: + group: + instances: + has_next: + value: ((b & 128) != 0) + value: + value: (b & 127) + seq: + - id: b + type: u1 + instances: + is_negative: + value: (((groups[0].value) >> 6) == 1) + seq: + - id: groups + type: group + repeat: until + repeat-until: not (_.has_next) + |}] diff --git a/contrib/lib_kaitai_of_data_encoding/translate.ml b/contrib/lib_kaitai_of_data_encoding/translate.ml index 3e5514abe038..b3d28993f46a 100644 --- a/contrib/lib_kaitai_of_data_encoding/translate.ml +++ b/contrib/lib_kaitai_of_data_encoding/translate.ml @@ -78,6 +78,7 @@ let rec from_data_encoding : | Bytes (_kind_length, _) -> Ground.Class.bytes ~encoding_name | String (_kind_length, _) -> Ground.Class.string ~encoding_name | N -> Ground.Class.n ~encoding_name + | Z -> Ground.Class.z ~encoding_name | Tup e -> (* Naked Tup likely due to [tup1]. We simply ignore this constructor. *) from_data_encoding ~encoding_name e -- GitLab From 1fcb63ffc8d41c530263badc89ecbac8e8012f05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Proust?= Date: Mon, 25 Sep 2023 15:11:25 +0200 Subject: [PATCH 5/5] Contrib/kaitai: cosmetics (use list more uniformly) --- contrib/kaitai-ocaml/src/print.ml | 73 +++++++++++++++++-------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/contrib/kaitai-ocaml/src/print.ml b/contrib/kaitai-ocaml/src/print.ml index a079ba680767..07bc62333d2e 100644 --- a/contrib/kaitai-ocaml/src/print.ml +++ b/contrib/kaitai-ocaml/src/print.ml @@ -50,17 +50,18 @@ let mapping l = m_members = List.map (fun (k, v) -> (scalar k, v)) l; } -let ( @? ) x xs = match x with None -> xs | Some x -> x :: xs +let mapping_flatten l = mapping (List.flatten l) -let ( @@? ) xs ys = match xs with None -> ys | Some xs -> xs @ ys +let map_list_of_option f = function None -> [] | Some x -> [f x] let metaSpec (t : MetaSpec.t) = - mapping - @@ Option.map (fun id -> ("id", scalar id)) t.id - @? Option.map - (fun endian -> ("endian", scalar (Endianness.to_string endian))) - t.endian - @? [] + mapping_flatten + [ + map_list_of_option (fun id -> ("id", scalar id)) t.id; + map_list_of_option + (fun endian -> ("endian", scalar (Endianness.to_string endian))) + t.endian; + ] let instanceSpec InstanceSpec.{doc = _; descr} = match descr with @@ -83,54 +84,60 @@ let enums_spec enums = (** We only add "type" to Yaml if not [AnyType]. TODO: This is only correct if [AnyType] means no type? *) let attr_type_if_not_any attr = - if attr.AttrSpec.dataType = AnyType then None - else Some ("type", scalar (DataType.to_string attr.AttrSpec.dataType)) + match attr.AttrSpec.dataType with + | AnyType -> [] + | NumericType _ | BooleanType | BytesType _ | StrType _ | ComplexDataType _ -> + [("type", scalar (DataType.to_string attr.AttrSpec.dataType))] let repeat_spec = let open RepeatSpec in function - | NoRepeat -> None + | NoRepeat -> [] | RepeatUntil expr -> - Some - (("repeat", scalar "until") - :: [("repeat-until", scalar (Ast.to_string expr))]) + [ + ("repeat", scalar "until"); ("repeat-until", scalar (Ast.to_string expr)); + ] | _ -> failwith "not supported" +let enum_spec attr = + map_list_of_option (fun enum -> ("enum", scalar enum)) attr.AttrSpec.enum + let attr_spec attr = match attr.AttrSpec.dataType with (* [BytesType] attr require size header. *) | BytesType (BytesLimitType {size; _}) -> [ mapping - (Some ("id", scalar attr.AttrSpec.id) - @? Some ("size", scalar (Ast.to_string size)) - @? []); + [ + ("id", scalar attr.AttrSpec.id); + ("size", scalar (Ast.to_string size)); + ]; ] | _ -> [ - mapping - (Some ("id", scalar attr.AttrSpec.id) - @? attr_type_if_not_any attr - @? repeat_spec attr.cond.repeat - @@? Option.map (fun enum -> ("enum", scalar enum)) attr.AttrSpec.enum - @? []); + mapping_flatten + [ + [("id", scalar attr.AttrSpec.id)]; + attr_type_if_not_any attr; + repeat_spec attr.cond.repeat; + enum_spec attr; + ]; ] let seq_spec seq = sequence (List.concat_map attr_spec seq) -let not_empty = function [] -> false | _ -> true - let spec_if_non_empty name args f = - if not_empty args then Some (name, f args) else None + match args with [] -> [] | _ :: _ -> [(name, f args)] let rec to_yaml (t : ClassSpec.t) = - mapping - @@ (if t.isTopLevel then Some ("meta", metaSpec t.meta) else None) - @? spec_if_non_empty "types" t.types types_spec - @? spec_if_non_empty "instances" t.instances instances_spec - @? spec_if_non_empty "enums" t.enums enums_spec - @? spec_if_non_empty "seq" t.seq seq_spec - @? [] + mapping_flatten + [ + (if t.isTopLevel then [("meta", metaSpec t.meta)] else []); + spec_if_non_empty "types" t.types types_spec; + spec_if_non_empty "instances" t.instances instances_spec; + spec_if_non_empty "enums" t.enums enums_spec; + spec_if_non_empty "seq" t.seq seq_spec; + ] and types_spec types = mapping (types |> List.map (fun (k, v) -> (k, to_yaml v))) -- GitLab