Micheline: 0x.. constants are now of a new Bytes case

This commit is contained in:
Benjamin Canou 2018-06-13 14:41:36 +02:00
parent 1ccfe6aed9
commit 0279f86e77
17 changed files with 136 additions and 47 deletions

View File

@ -314,13 +314,13 @@ assert_storage $contract_dir/map_caddaadr.tz \
'(Pair (Pair 1 (Pair 2 (Pair (Pair (Pair 3 1000000) 4) 5))) 6)' '(Pair (Pair 1 (Pair 2 (Pair (Pair (Pair 3 1000000) 4) 5))) 6)'
# Did the given key sign the string? (key is bootstrap1) # Did the given key sign the string? (key is bootstrap1)
assert_success $client run script $contract_dir/check_signature.tz \ #assert_success $client run script $contract_dir/check_signature.tz \
on storage '(Pair 0x011eb640b67c1859228a72730fae1a006bb94a999395dfb569e2776e9c1ae546376247f001343a1042f92082690f6aa2e6ed230df319b09767d9807ef3f8191f "hello")' \ # on storage '(Pair 0x011eb640b67c1859228a72730fae1a006bb94a999395dfb569e2776e9c1ae546376247f001343a1042f92082690f6aa#2e6ed230df319b09767d9807ef3f8191f "hello")' \
and input '"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav"' # and input '"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav"'
assert_fails $client run script $contract_dir/check_signature.tz \ #assert_fails $client run script $contract_dir/check_signature.tz \
on storage '(Pair 0x011eb640b67c1859228a72730fae1a006bb94a999395dfb569e2776e9c1ae546376247f001343a1042f92082690f6aa2e6ed230df319b09767d9807ef3f8191f "abcd")' \ # on storage '(Pair 0x011eb640b67c1859228a72730fae1a006bb94a999395dfb569e2776e9c1ae546376247f001343a1042f92082690f6aa2e#6ed230df319b09767d9807ef3f8191f "abcd")' \
and input '"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav"' # and input '"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav"'
# Convert a public key to a public key hash # Convert a public key to a public key hash

View File

@ -9,11 +9,13 @@
uutf uutf
zarith zarith
;; Internal ;; Internal
tezos-stdlib
tezos-error-monad tezos-error-monad
tezos-data-encoding tezos-data-encoding
)) ))
(flags (:standard -w -9+27-30-32-40@8 (flags (:standard -w -9+27-30-32-40@8
-safe-string -safe-string
-open Tezos_stdlib
-open Tezos_error_monad -open Tezos_error_monad
-open Tezos_data_encoding)))) -open Tezos_data_encoding))))

View File

@ -12,6 +12,7 @@ type annot = string list
type ('l, 'p) node = type ('l, 'p) node =
| Int of 'l * Z.t | Int of 'l * Z.t
| String of 'l * string | String of 'l * string
| Bytes of 'l * MBytes.t
| Prim of 'l * 'p * ('l, 'p) node list * annot | Prim of 'l * 'p * ('l, 'p) node list * annot
| Seq of 'l * ('l, 'p) node list | Seq of 'l * ('l, 'p) node list
@ -34,12 +35,14 @@ let canonical_location_encoding =
let location = function let location = function
| Int (loc, _) -> loc | Int (loc, _) -> loc
| String (loc, _) -> loc | String (loc, _) -> loc
| Bytes (loc, _) -> loc
| Seq (loc, _) -> loc | Seq (loc, _) -> loc
| Prim (loc, _, _, _) -> loc | Prim (loc, _, _, _) -> loc
let annotations = function let annotations = function
| Int (_, _) -> [] | Int (_, _) -> []
| String (_, _) -> [] | String (_, _) -> []
| Bytes (_, _) -> []
| Seq (_, _) -> [] | Seq (_, _) -> []
| Prim (_, _, _, annots) -> annots | Prim (_, _, _, annots) -> annots
@ -54,6 +57,8 @@ let strip_locations root =
Int (id, v) Int (id, v)
| String (_, v) -> | String (_, v) ->
String (id, v) String (id, v)
| Bytes (_, v) ->
Bytes (id, v)
| Seq (_, seq) -> | Seq (_, seq) ->
Seq (id, List.map strip_locations seq) Seq (id, List.map strip_locations seq)
| Prim (_, name, seq, annots) -> | Prim (_, name, seq, annots) ->
@ -72,6 +77,9 @@ let extract_locations root =
| String (loc, v) -> | String (loc, v) ->
loc_table := (id, loc) :: !loc_table ; loc_table := (id, loc) :: !loc_table ;
String (id, v) String (id, v)
| Bytes (loc, v) ->
loc_table := (id, loc) :: !loc_table ;
Bytes (id, v)
| Seq (loc, seq) -> | Seq (loc, seq) ->
loc_table := (id, loc) :: !loc_table ; loc_table := (id, loc) :: !loc_table ;
Seq (id, List.map strip_locations seq) Seq (id, List.map strip_locations seq)
@ -88,6 +96,8 @@ let inject_locations lookup (Canonical root) =
Int (lookup loc, v) Int (lookup loc, v)
| String (loc, v) -> | String (loc, v) ->
String (lookup loc, v) String (lookup loc, v)
| Bytes (loc, v) ->
Bytes (lookup loc, v)
| Seq (loc, seq) -> | Seq (loc, seq) ->
Seq (lookup loc, List.map inject_locations seq) Seq (lookup loc, List.map inject_locations seq)
| Prim (loc, name, seq, annots) -> | Prim (loc, name, seq, annots) ->
@ -96,7 +106,7 @@ let inject_locations lookup (Canonical root) =
let map f (Canonical expr) = let map f (Canonical expr) =
let rec map_node f = function let rec map_node f = function
| Int _ | String _ as node -> node | Int _ | String _ | Bytes _ as node -> node
| Seq (loc, seq) -> | Seq (loc, seq) ->
Seq (loc, List.map (map_node f) seq) Seq (loc, List.map (map_node f) seq)
| Prim (loc, name, seq, annots) -> | Prim (loc, name, seq, annots) ->
@ -108,6 +118,8 @@ let rec map_node fl fp = function
Int (fl loc, v) Int (fl loc, v)
| String (loc, v) -> | String (loc, v) ->
String (fl loc, v) String (fl loc, v)
| Bytes (loc, v) ->
Bytes (fl loc, v)
| Seq (loc, seq) -> | Seq (loc, seq) ->
Seq (fl loc, List.map (map_node fl fp) seq) Seq (fl loc, List.map (map_node fl fp) seq)
| Prim (loc, name, seq, annots) -> | Prim (loc, name, seq, annots) ->
@ -119,6 +131,8 @@ let canonical_encoding ~variant prim_encoding =
obj1 (req "int" z) in obj1 (req "int" z) in
let string_encoding = let string_encoding =
obj1 (req "string" string) in obj1 (req "string" string) in
let bytes_encoding =
obj1 (req "bytes" bytes) in
let int_encoding tag = let int_encoding tag =
case tag int_encoding case tag int_encoding
~title:"Int" ~title:"Int"
@ -129,6 +143,11 @@ let canonical_encoding ~variant prim_encoding =
~title:"String" ~title:"String"
(function String (_, v) -> Some v | _ -> None) (function String (_, v) -> Some v | _ -> None)
(fun v -> String (0, v)) in (fun v -> String (0, v)) in
let bytes_encoding tag =
case tag bytes_encoding
~title:"Bytes"
(function Bytes (_, v) -> Some v | _ -> None)
(fun v -> Bytes (0, v)) in
let seq_encoding tag expr_encoding = let seq_encoding tag expr_encoding =
case tag (list expr_encoding) case tag (list expr_encoding)
~title:"Sequence" ~title:"Sequence"
@ -224,7 +243,8 @@ let canonical_encoding ~variant prim_encoding =
| _ -> None) | _ -> None)
(fun (prim, arg1, arg2, annots) -> Prim (0, prim, [ arg1 ; arg2 ], annots)) ; (fun (prim, arg1, arg2, annots) -> Prim (0, prim, [ arg1 ; arg2 ], annots)) ;
(* General case *) (* General case *)
application_encoding (Tag 9) expr_encoding ])) application_encoding (Tag 9) expr_encoding ;
bytes_encoding (Tag 10) ]))
in in
conv conv
(function Canonical node -> node) (function Canonical node -> node)

View File

@ -15,6 +15,7 @@ type annot = string list
type ('l, 'p) node = type ('l, 'p) node =
| Int of 'l * Z.t | Int of 'l * Z.t
| String of 'l * string | String of 'l * string
| Bytes of 'l * MBytes.t
| Prim of 'l * 'p * ('l, 'p) node list * annot | Prim of 'l * 'p * ('l, 'p) node list * annot
| Seq of 'l * ('l, 'p) node list | Seq of 'l * ('l, 'p) node list

View File

@ -54,6 +54,7 @@ let location_encoding =
type token_value = type token_value =
| String of string | String of string
| Bytes of string
| Int of string | Int of string
| Ident of string | Ident of string
| Annot of string | Annot of string
@ -98,7 +99,12 @@ let token_value_encoding =
"{", Open_brace ; "{", Open_brace ;
"}", Close_brace ; "}", Close_brace ;
";", Semi ]))) ";", Semi ])))
(fun t -> Some t) (fun t -> t) ] (fun t -> Some t) (fun t -> t) ;
case (Tag 5)
~title:"Bytes"
(obj1 (req "bytes" string))
(function Bytes s -> Some s | _ -> None)
(fun s -> Bytes s) ]
type token = type token =
{ token : token_value ; { token : token_value ;
@ -112,6 +118,7 @@ type error += Undefined_escape_sequence of point * string
type error += Missing_break_after_number of point type error += Missing_break_after_number of point
type error += Unterminated_string of location type error += Unterminated_string of location
type error += Unterminated_integer of location type error += Unterminated_integer of location
type error += Odd_lengthed_bytes of location
type error += Unterminated_comment of location type error += Unterminated_comment of location
type error += Annotation_length of location type error += Annotation_length of location
@ -174,7 +181,7 @@ let tokenize source =
| `Uchar c, stop as first -> | `Uchar c, stop as first ->
begin match uchar_to_char c with begin match uchar_to_char c with
| Some '0' -> base acc start | Some '0' -> base acc start
| Some ('1'..'9') -> integer `dec acc start false | Some ('1'..'9') -> integer acc start
| Some _ | None -> | Some _ | None ->
errors := Unterminated_integer { start ; stop } :: !errors ; errors := Unterminated_integer { start ; stop } :: !errors ;
back first ; back first ;
@ -182,7 +189,7 @@ let tokenize source =
end end
end end
| Some '0' -> base acc start | Some '0' -> base acc start
| Some ('1'..'9') -> integer `dec acc start false | Some ('1'..'9') -> integer acc start
| Some (' ' | '\n') -> skip acc | Some (' ' | '\n') -> skip acc
| Some ';' -> skip (tok start (here ()) Semi :: acc) | Some ';' -> skip (tok start (here ()) Semi :: acc)
| Some '{' -> skip (tok start (here ()) Open_brace :: acc) | Some '{' -> skip (tok start (here ()) Open_brace :: acc)
@ -210,9 +217,8 @@ let tokenize source =
match next () with match next () with
| (`Uchar c, stop) as charloc -> | (`Uchar c, stop) as charloc ->
begin match uchar_to_char c with begin match uchar_to_char c with
| Some ('0'.. '9') -> integer `dec acc start false | Some ('0'.. '9') -> integer acc start
| Some 'x' -> integer `hex acc start true | Some 'x' -> bytes acc start
| Some 'b' -> integer `bin acc start true
| Some ('a' | 'c'..'w' | 'y' | 'z' | 'A'..'Z') -> | Some ('a' | 'c'..'w' | 'y' | 'z' | 'A'..'Z') ->
errors := Missing_break_after_number stop :: !errors ; errors := Missing_break_after_number stop :: !errors ;
back charloc ; back charloc ;
@ -224,7 +230,7 @@ let tokenize source =
| (_, stop) as other -> | (_, stop) as other ->
back other ; back other ;
skip (tok start stop (Int "0") :: acc) skip (tok start stop (Int "0") :: acc)
and integer base acc start first = and integer acc start =
let tok stop = let tok stop =
let value = let value =
String.sub source start.byte (stop.byte - start.byte) in String.sub source start.byte (stop.byte - start.byte) in
@ -235,31 +241,39 @@ let tokenize source =
errors := Missing_break_after_number stop :: !errors ; errors := Missing_break_after_number stop :: !errors ;
back charloc ; back charloc ;
skip (tok stop :: acc) in skip (tok stop :: acc) in
begin match base, Uchar.to_char c with begin match Uchar.to_char c with
| `dec, ('0'.. '9') -> | ('0'.. '9') ->
integer `dec acc start false integer acc start
| `dec, ('a'..'z' | 'A'..'Z') -> | ('a'..'z' | 'A'..'Z') ->
missing_break ()
| _ ->
back charloc ;
skip (tok stop :: acc)
end
| (`End, stop) as other ->
back other ;
skip (tok stop :: acc)
and bytes acc start =
let tok stop =
let value =
String.sub source start.byte (stop.byte - start.byte) in
tok start stop (Bytes value) in
match next () with
| (`Uchar c, stop) as charloc ->
let missing_break () =
errors := Missing_break_after_number stop :: !errors ;
back charloc ;
skip (tok stop :: acc) in
begin match Uchar.to_char c with
| ('0'..'9' | 'a'..'f' | 'A'..'F') ->
bytes acc start
| ('g'..'z' | 'G'..'Z') ->
missing_break () missing_break ()
| `hex, ('0'..'9' | 'a'..'f' | 'A'..'F') ->
integer `hex acc start false
| `hex, ('g'..'z' | 'G'..'Z') ->
missing_break ()
| `bin, ('0' | '1') ->
integer `bin acc start false
| `bin, ('2'..'9' | 'a'..'z' | 'A'..'Z') ->
missing_break ()
| (`bin | `hex), _ when first ->
errors := Unterminated_integer { start ; stop } :: !errors ;
back charloc ;
skip (tok stop :: acc)
| _ -> | _ ->
back charloc ; back charloc ;
skip (tok stop :: acc) skip (tok stop :: acc)
end end
| (`End, stop) as other -> | (`End, stop) as other ->
if first && (base = `bin || base = `hex) then begin
errors := Unterminated_integer { start ; stop } :: !errors
end ;
back other ; back other ;
skip (tok stop :: acc) skip (tok stop :: acc)
and string acc sacc start = and string acc sacc start =
@ -374,6 +388,7 @@ let min_point : node list -> point = function
| [] -> point_zero | [] -> point_zero
| Int ({ start }, _) :: _ | Int ({ start }, _) :: _
| String ({ start }, _) :: _ | String ({ start }, _) :: _
| Bytes ({ start }, _) :: _
| Prim ({ start }, _, _, _) :: _ | Prim ({ start }, _, _, _) :: _
| Seq ({ start }, _) :: _ -> start | Seq ({ start }, _) :: _ -> start
@ -383,6 +398,7 @@ let rec max_point : node list -> point = function
| _ :: (_ :: _ as rest) -> max_point rest | _ :: (_ :: _ as rest) -> max_point rest
| Int ({ stop }, _) :: [] | Int ({ stop }, _) :: []
| String ({ stop }, _) :: [] | String ({ stop }, _) :: []
| Bytes ({ stop }, _) :: []
| Prim ({ stop }, _, _, _) :: [] | Prim ({ stop }, _, _, _) :: []
| Seq ({ stop }, _) :: [] -> stop | Seq ({ stop }, _) :: [] -> stop
@ -483,7 +499,7 @@ let rec parse ?(check = true) errors tokens stack =
{ token = Eol_comment _ | Comment _ } :: rest -> { token = Eol_comment _ | Comment _ } :: rest ->
parse ~check errors rest stack parse ~check errors rest stack
| (Expression None | Sequence _ | Toplevel _) :: _, | (Expression None | Sequence _ | Toplevel _) :: _,
({ token = Int _ | String _ } as token):: { token = Eol_comment _ | Comment _ } :: rest ({ token = Int _ | String _ | Bytes _ } as token):: { token = Eol_comment _ | Comment _ } :: rest
| (Wrapped _ | Unwrapped _) :: _, | (Wrapped _ | Unwrapped _) :: _,
({ token = Open_paren } as token) ({ token = Open_paren } as token)
:: { token = Eol_comment _ | Comment _ } :: rest -> :: { token = Eol_comment _ | Comment _ } :: rest ->
@ -504,9 +520,9 @@ let rec parse ?(check = true) errors tokens stack =
parse ~check errors (valid (* skip *) :: rem) stack parse ~check errors (valid (* skip *) :: rem) stack
| (Wrapped _ | Unwrapped _) :: _ , | (Wrapped _ | Unwrapped _) :: _ ,
{ token = Open_paren } { token = Open_paren }
:: ({ token = Int _ | String _ | Annot _ | Close_paren } as token) :: rem :: ({ token = Int _ | String _ | Bytes _ | Annot _ | Close_paren } as token) :: rem
| (Expression None | Sequence _ | Toplevel _) :: _, | (Expression None | Sequence _ | Toplevel _) :: _,
{ token = Int _ | String _ } :: ({ token = Ident _ | Int _ | String _ | Annot _ | Close_paren | Open_paren | Open_brace } as token) :: rem { token = Int _ | String _ | Bytes _ } :: ({ token = Ident _ | Int _ | String _ | Bytes _ | Annot _ | Close_paren | Open_paren | Open_brace } as token) :: rem
| Unwrapped (_, _, _, _) :: Toplevel _ :: _, | Unwrapped (_, _, _, _) :: Toplevel _ :: _,
({ token = Close_brace } as token) :: rem ({ token = Close_brace } as token) :: rem
| Unwrapped (_, _, _, _) :: _, | Unwrapped (_, _, _, _) :: _,
@ -561,6 +577,18 @@ let rec parse ?(check = true) errors tokens stack =
let expr : node = String (loc, contents) in let expr : node = String (loc, contents) in
let errors = if check then do_check ~toplevel: false errors expr else errors in let errors = if check then do_check ~toplevel: false errors expr else errors in
parse ~check errors rest (fill_mode expr stack) parse ~check errors rest (fill_mode expr stack)
| (Unwrapped _ | Wrapped _) :: _,
{ token = Bytes contents ; loc } :: rest
| (Expression None | Sequence _ | Toplevel _) :: _,
{ token = Bytes contents ; loc } :: ([] | { token = Semi | Close_brace} :: _ as rest) ->
let errors, contents = if String.length contents mod 2 <> 0 then
Odd_lengthed_bytes loc :: errors, contents ^ "0"
else errors, contents in
let bytes =
MBytes.of_hex (`Hex (String.sub contents 2 (String.length contents - 2))) in
let expr : node = Bytes (loc, bytes) in
let errors = if check then do_check ~toplevel: false errors expr else errors in
parse ~check errors rest (fill_mode expr stack)
| Sequence ({ loc = { start } }, exprs) :: _ , | Sequence ({ loc = { start } }, exprs) :: _ ,
{ token = Close_brace ; loc = { stop } } :: rest -> { token = Close_brace ; loc = { stop } } :: rest ->
let exprs = List.rev exprs in let exprs = List.rev exprs in
@ -632,7 +660,7 @@ and do_check ?(toplevel = false) errors = function
errors in errors in
in_line_or_aligned start_line errors rest in in_line_or_aligned start_line errors rest in
in_line_or_aligned first_line errors rest in_line_or_aligned first_line errors rest
| Prim (_, _, [], _) | String _ | Int _ -> errors | Prim (_, _, [], _) | String _ | Int _ | Bytes _ -> errors
let parse_expression ?check tokens = let parse_expression ?check tokens =
let result = match tokens with let result = match tokens with
@ -661,6 +689,7 @@ let print_token_kind ppf = function
| Open_paren | Close_paren -> Format.fprintf ppf "parenthesis" | Open_paren | Close_paren -> Format.fprintf ppf "parenthesis"
| Open_brace | Close_brace -> Format.fprintf ppf "curly brace" | Open_brace | Close_brace -> Format.fprintf ppf "curly brace"
| String _ -> Format.fprintf ppf "string constant" | String _ -> Format.fprintf ppf "string constant"
| Bytes _ -> Format.fprintf ppf "bytes constant"
| Int _ -> Format.fprintf ppf "integer constant" | Int _ -> Format.fprintf ppf "integer constant"
| Ident _ -> Format.fprintf ppf "identifier" | Ident _ -> Format.fprintf ppf "identifier"
| Annot _ -> Format.fprintf ppf "annotation" | Annot _ -> Format.fprintf ppf "annotation"
@ -744,6 +773,16 @@ let () =
Data_encoding.(obj1 (req "location" location_encoding)) Data_encoding.(obj1 (req "location" location_encoding))
(function Unterminated_integer loc -> Some loc | _ -> None) (function Unterminated_integer loc -> Some loc | _ -> None)
(fun loc -> Unterminated_integer loc) ; (fun loc -> Unterminated_integer loc) ;
register_error_kind `Permanent
~id: "micheline.parse_error.odd_lengthed_bytes"
~title: "Micheline parser error: odd lengthed bytes"
~description: "While parsing a piece of Micheline source, the \
length of a byte sequence (0x...) was not a \
multiple of two, leaving a trailing half byte."
~pp:(fun ppf loc -> Format.fprintf ppf "%a, odd_lengthed bytes" print_location loc)
Data_encoding.(obj1 (req "location" location_encoding))
(function Odd_lengthed_bytes loc -> Some loc | _ -> None)
(fun loc -> Odd_lengthed_bytes loc) ;
register_error_kind `Permanent register_error_kind `Permanent
~id: "micheline.parse_error.unterminated_comment" ~id: "micheline.parse_error.unterminated_comment"
~title: "Micheline parser error: unterminated comment" ~title: "Micheline parser error: unterminated comment"

View File

@ -33,6 +33,7 @@ val location_encoding : location Data_encoding.encoding
type token_value = type token_value =
| String of string | String of string
| Bytes of string
| Int of string | Int of string
| Ident of string | Ident of string
| Annot of string | Annot of string
@ -66,6 +67,7 @@ type error += Undefined_escape_sequence of point * string
type error += Missing_break_after_number of point type error += Missing_break_after_number of point
type error += Unterminated_string of location type error += Unterminated_string of location
type error += Unterminated_integer of location type error += Unterminated_integer of location
type error += Odd_lengthed_bytes of location
type error += Unterminated_comment of location type error += Unterminated_comment of location
type error += Unclosed of token type error += Unclosed of token
type error += Unexpected of token type error += Unexpected of token

View File

@ -55,6 +55,9 @@ let preformat root =
| String (loc, value) -> | String (loc, value) ->
let cml, csz = preformat_loc loc in let cml, csz = preformat_loc loc in
String ((cml, String.length value + csz, loc), value) String ((cml, String.length value + csz, loc), value)
| Bytes (loc, value) ->
let cml, csz = preformat_loc loc in
Bytes ((cml, MBytes.length value * 2 + 2 + csz, loc), value)
| Prim (loc, name, items, annots) -> | Prim (loc, name, items, annots) ->
let cml, csz = preformat_loc loc in let cml, csz = preformat_loc loc in
let asz = preformat_annots annots in let asz = preformat_annots annots in
@ -117,6 +120,11 @@ let rec print_expr_unwrapped ppf = function
| None -> print_string ppf value | None -> print_string ppf value
| Some comment -> Format.fprintf ppf "%a@ %a" print_string value print_comment comment | Some comment -> Format.fprintf ppf "%a@ %a" print_string value print_comment comment
end end
| Bytes ((_, _, { comment }), value) ->
begin match comment with
| None -> Format.fprintf ppf "0x%a" MBytes.pp_hex value
| Some comment -> Format.fprintf ppf "0x%a@ %a" MBytes.pp_hex value print_comment comment
end
| Seq ((_, _, { comment = None }), []) -> | Seq ((_, _, { comment = None }), []) ->
Format.fprintf ppf "{}" Format.fprintf ppf "{}"
| Seq ((ml, s, { comment }), items) -> | Seq ((ml, s, { comment }), items) ->

View File

@ -12,6 +12,7 @@ type annot = string list
type ('l, 'p) node = type ('l, 'p) node =
| Int of 'l * Z.t | Int of 'l * Z.t
| String of 'l * string | String of 'l * string
| Bytes of 'l * MBytes.t
| Prim of 'l * 'p * ('l, 'p) node list * annot | Prim of 'l * 'p * ('l, 'p) node list * annot
| Seq of 'l * ('l, 'p) node list | Seq of 'l * ('l, 'p) node list

View File

@ -18,6 +18,7 @@ let print_expr ppf expr =
let rec print_expr ppf = function let rec print_expr ppf = function
| Int (_, value) -> Format.fprintf ppf "%s" (Z.to_string value) | Int (_, value) -> Format.fprintf ppf "%s" (Z.to_string value)
| String (_, value) -> Micheline_printer.print_string ppf value | String (_, value) -> Micheline_printer.print_string ppf value
| Bytes (_, value) -> Format.fprintf ppf "0x%a" MBytes.pp_hex value
| Seq (_, items) -> | Seq (_, items) ->
Format.fprintf ppf "(seq %a)" Format.fprintf ppf "(seq %a)"
(Format.pp_print_list ~pp_sep:Format.pp_print_space print_expr) (Format.pp_print_list ~pp_sep:Format.pp_print_space print_expr)
@ -49,6 +50,7 @@ let print_type_map ppf (parsed, type_map) =
| Seq (loc, []) | Seq (loc, [])
| Prim (loc, _, [], _) | Prim (loc, _, [], _)
| Int (loc, _) | Int (loc, _)
| Bytes (loc, _)
| String (loc, _) -> | String (loc, _) ->
print_item ppf loc print_item ppf loc
| Seq (loc, items) | Seq (loc, items)
@ -154,6 +156,7 @@ let report_errors ppf (parsed, errs) =
| Unterminated_string loc | Unterminated_string loc
| Unterminated_integer loc | Unterminated_integer loc
| Unterminated_comment loc | Unterminated_comment loc
| Odd_lengthed_bytes loc
| Unclosed { loc } | Unclosed { loc }
| Unexpected { loc } | Unexpected { loc }
| Extra { loc } -> loc | Extra { loc } -> loc

View File

@ -292,7 +292,8 @@ let report_errors ~details ~show_source ?parsed ppf errs =
| Seq_kind -> ("a", "sequence") | Seq_kind -> ("a", "sequence")
| Prim_kind -> ("a", "primitive") | Prim_kind -> ("a", "primitive")
| Int_kind -> ("an", "int") | Int_kind -> ("an", "int")
| String_kind -> ("a", "string") in | String_kind -> ("a", "string")
| Bytes_kind -> ("a", "byte sequence") in
Format.fprintf ppf Format.fprintf ppf
"@[%aunexpected %s, only@ %a@ can be used here." "@[%aunexpected %s, only@ %a@ can be used here."
print_loc loc print_loc loc

View File

@ -629,7 +629,7 @@ let expand_rec expr =
| Prim (loc, name, args, annot) -> | Prim (loc, name, args, annot) ->
let args, errors = error_map expand_rec args in let args, errors = error_map expand_rec args in
(Prim (loc, name, args, annot), errors) (Prim (loc, name, args, annot), errors)
| Int _ | String _ as atom -> (atom, []) end | Int _ | String _ | Bytes _ as atom -> (atom, []) end
| Error errors -> (expr, errors) in | Error errors -> (expr, errors) in
expand_rec expr expand_rec expr
@ -1072,7 +1072,7 @@ let rec unexpand_rec expr =
Seq (loc, List.map unexpand_rec items) Seq (loc, List.map unexpand_rec items)
| Prim (loc, name, args, annot) -> | Prim (loc, name, args, annot) ->
Prim (loc, name, List.map unexpand_rec args, annot) Prim (loc, name, List.map unexpand_rec args, annot)
| Int _ | String _ as atom -> atom | Int _ | String _ | Bytes _ as atom -> atom
let () = let () =
let open Data_encoding in let open Data_encoding in

View File

@ -72,6 +72,8 @@ let inject_types type_map parsed =
Int (inject_loc `after loc, value) Int (inject_loc `after loc, value)
| String (loc, value) -> | String (loc, value) ->
String (inject_loc `after loc, value) String (inject_loc `after loc, value)
| Bytes (loc, value) ->
Bytes (inject_loc `after loc, value)
and inject_loc which loc = try and inject_loc which loc = try
let stack = let stack =
let locs = let locs =
@ -104,6 +106,8 @@ let unparse ?type_map parse expanded =
Int (inject_loc `after loc, value) Int (inject_loc `after loc, value)
| String (loc, value) -> | String (loc, value) ->
String (inject_loc `after loc, value) String (inject_loc `after loc, value)
| Bytes (loc, value) ->
Bytes (inject_loc `after loc, value)
and inject_loc which loc = try and inject_loc which loc = try
let stack = let stack =
let (bef, aft) = let (bef, aft) =

View File

@ -363,7 +363,7 @@ let prim_of_string = function
let prims_of_strings expr = let prims_of_strings expr =
let rec convert = function let rec convert = function
| Int _ | String _ as expr -> ok expr | Int _ | String _ | Bytes _ as expr -> ok expr
| Prim (loc, prim, args, annot) -> | Prim (loc, prim, args, annot) ->
Error_monad.record_trace Error_monad.record_trace
(Invalid_primitive_name (expr, loc)) (Invalid_primitive_name (expr, loc))
@ -388,7 +388,7 @@ let prims_of_strings expr =
let strings_of_prims expr = let strings_of_prims expr =
let rec convert = function let rec convert = function
| Int _ | String _ as expr -> expr | Int _ | String _ | Bytes _ as expr -> expr
| Prim (_, prim, args, annot) -> | Prim (_, prim, args, annot) ->
let prim = string_of_prim prim in let prim = string_of_prim prim in
let args = List.map convert args in let args = List.map convert args in

View File

@ -215,11 +215,13 @@ let location = function
| Prim (loc, _, _, _) | Prim (loc, _, _, _)
| Int (loc, _) | Int (loc, _)
| String (loc, _) | String (loc, _)
| Bytes (loc, _)
| Seq (loc, _) -> loc | Seq (loc, _) -> loc
let kind = function let kind = function
| Int _ -> Int_kind | Int _ -> Int_kind
| String _ -> String_kind | String _ -> String_kind
| Bytes _ -> Bytes_kind
| Prim _ -> Prim_kind | Prim _ -> Prim_kind
| Seq _ -> Seq_kind | Seq _ -> Seq_kind
@ -336,6 +338,7 @@ let unexpected expr exp_kinds exp_ns exp_prims =
match expr with match expr with
| Int (loc, _) -> Invalid_kind (loc, Prim_kind :: exp_kinds, Int_kind) | Int (loc, _) -> Invalid_kind (loc, Prim_kind :: exp_kinds, Int_kind)
| String (loc, _ ) -> Invalid_kind (loc, Prim_kind :: exp_kinds, String_kind) | String (loc, _ ) -> Invalid_kind (loc, Prim_kind :: exp_kinds, String_kind)
| Bytes (loc, _ ) -> Invalid_kind (loc, Prim_kind :: exp_kinds, Bytes_kind)
| Seq (loc, _) -> Invalid_kind (loc, Prim_kind :: exp_kinds, Seq_kind) | Seq (loc, _) -> Invalid_kind (loc, Prim_kind :: exp_kinds, Seq_kind)
| Prim (loc, name, _, _) -> | Prim (loc, name, _, _) ->
match namespace name, exp_ns with match namespace name, exp_ns with
@ -721,6 +724,7 @@ let merge_comparable_types
let rec strip_annotations = function let rec strip_annotations = function
| (Int (_,_) as i) -> i | (Int (_,_) as i) -> i
| (String (_,_) as s) -> s | (String (_,_) as s) -> s
| (Bytes (_,_) as s) -> s
| Prim (loc, prim, args, _) -> Prim (loc, prim, List.map strip_annotations args, []) | Prim (loc, prim, args, _) -> Prim (loc, prim, List.map strip_annotations args, [])
| Seq (loc, items) -> Seq (loc, List.map strip_annotations items) | Seq (loc, items) -> Seq (loc, List.map strip_annotations items)
@ -1114,7 +1118,7 @@ let rec parse_data
fail @@ Invalid_arity (loc, D_Elt, 2, List.length l) fail @@ Invalid_arity (loc, D_Elt, 2, List.length l)
| Prim (loc, name, _, _) -> | Prim (loc, name, _, _) ->
fail @@ Invalid_primitive (loc, [ D_Elt ], name) fail @@ Invalid_primitive (loc, [ D_Elt ], name)
| Int _ | String _ | Seq _ -> | Int _ | String _ | Bytes _ | Seq _ ->
fail (error ())) fail (error ()))
(None, empty_map key_type, ctxt) items |> traced >>|? fun (_, items, ctxt) -> (None, empty_map key_type, ctxt) items |> traced >>|? fun (_, items, ctxt) ->
(items, ctxt) in (items, ctxt) in
@ -1456,7 +1460,7 @@ and parse_instr
let log_stack loc stack_ty aft = let log_stack loc stack_ty aft =
match type_logger, script_instr with match type_logger, script_instr with
| None, _ | None, _
| Some _, (Seq (-1, _) | Int _ | String _) -> () | Some _, (Seq (-1, _) | Int _ | String _ | Bytes _) -> ()
| Some log, (Prim _ | Seq _) -> | Some log, (Prim _ | Seq _) ->
log loc (unparse_stack stack_ty) (unparse_stack aft) log loc (unparse_stack stack_ty) (unparse_stack aft)
in in
@ -2506,6 +2510,7 @@ and parse_toplevel
match root toplevel with match root toplevel with
| Int (loc, _) -> error (Invalid_kind (loc, [ Seq_kind ], Int_kind)) | Int (loc, _) -> error (Invalid_kind (loc, [ Seq_kind ], Int_kind))
| String (loc, _) -> error (Invalid_kind (loc, [ Seq_kind ], String_kind)) | String (loc, _) -> error (Invalid_kind (loc, [ Seq_kind ], String_kind))
| Bytes (loc, _) -> error (Invalid_kind (loc, [ Seq_kind ], Bytes_kind))
| Prim (loc, _, _, _) -> error (Invalid_kind (loc, [ Seq_kind ], Prim_kind)) | Prim (loc, _, _, _) -> error (Invalid_kind (loc, [ Seq_kind ], Prim_kind))
| Seq (_, fields) -> | Seq (_, fields) ->
let rec find_fields p s c fields = let rec find_fields p s c fields =
@ -2513,6 +2518,7 @@ and parse_toplevel
| [] -> ok (p, s, c) | [] -> ok (p, s, c)
| Int (loc, _) :: _ -> error (Invalid_kind (loc, [ Prim_kind ], Int_kind)) | Int (loc, _) :: _ -> error (Invalid_kind (loc, [ Prim_kind ], Int_kind))
| String (loc, _) :: _ -> error (Invalid_kind (loc, [ Prim_kind ], String_kind)) | String (loc, _) :: _ -> error (Invalid_kind (loc, [ Prim_kind ], String_kind))
| Bytes (loc, _) :: _ -> error (Invalid_kind (loc, [ Prim_kind ], Bytes_kind))
| Seq (loc, _) :: _ -> error (Invalid_kind (loc, [ Prim_kind ], Seq_kind)) | Seq (loc, _) :: _ -> error (Invalid_kind (loc, [ Prim_kind ], Seq_kind))
| Prim (loc, K_parameter, [ arg ], _) :: rest -> | Prim (loc, K_parameter, [ arg ], _) :: rest ->
begin match p with begin match p with
@ -2792,7 +2798,7 @@ and unparse_code ctxt mode = function
return (item :: l, ctxt)) return (item :: l, ctxt))
([], ctxt) items >>=? fun (items, ctxt) -> ([], ctxt) items >>=? fun (items, ctxt) ->
return (Prim (loc, prim, List.rev items, annot), ctxt) return (Prim (loc, prim, List.rev items, annot), ctxt)
| Int _ | String _ as atom -> return (atom, ctxt) | Int _ | String _ | Bytes _ as atom -> return (atom, ctxt)
let unparse_script ctxt mode { code ; arg_type ; storage ; storage_type } = let unparse_script ctxt mode { code ; arg_type ; storage ; storage_type } =
let Lam (_, original_code) = code in let Lam (_, original_code) = code in

View File

@ -72,6 +72,7 @@ let rec node_size node =
match node with match node with
| Int (_, n) -> (1, 1 + (Z.numbits n + 63) / 64) | Int (_, n) -> (1, 1 + (Z.numbits n + 63) / 64)
| String (_, s) -> (1, 1 + (String.length s + 7) / 8) | String (_, s) -> (1, 1 + (String.length s + 7) / 8)
| Bytes (_, s) -> (1, 1 + (MBytes.length s + 7) / 8)
| Prim (_, _, args, annot) -> | Prim (_, _, args, annot) ->
List.fold_left List.fold_left
(fun (blocks, words) node -> (fun (blocks, words) node ->

View File

@ -16,7 +16,7 @@ open Script_typed_ir
(* Auxiliary types for error documentation *) (* Auxiliary types for error documentation *)
type namespace = Type_namespace | Constant_namespace | Instr_namespace | Keyword_namespace type namespace = Type_namespace | Constant_namespace | Instr_namespace | Keyword_namespace
type kind = Int_kind | String_kind | Prim_kind | Seq_kind type kind = Int_kind | String_kind | Bytes_kind | Prim_kind | Seq_kind
type type_map = (int * ((Script.expr * Script.annot) list * (Script.expr * Script.annot) list)) list type type_map = (int * ((Script.expr * Script.annot) list * (Script.expr * Script.annot) list)) list
(* Structure errors *) (* Structure errors *)

View File

@ -62,6 +62,7 @@ let () =
(integer, string, primitive application or sequence)." @@ (integer, string, primitive application or sequence)." @@
string_enum [ "integer", Int_kind ; string_enum [ "integer", Int_kind ;
"string", String_kind ; "string", String_kind ;
"bytes", Bytes_kind ;
"primitiveApplication", Prim_kind ; "primitiveApplication", Prim_kind ;
"sequence", Seq_kind ] in "sequence", Seq_kind ] in
let var_annot_enc = let var_annot_enc =