Michelson macros: even more error handling
This commit is contained in:
parent
76e70a2799
commit
61984d6edd
@ -13,39 +13,55 @@ open Micheline
|
|||||||
type 'l node = ('l, string) Micheline.node
|
type 'l node = ('l, string) Micheline.node
|
||||||
|
|
||||||
type error += Unexpected_macro_annotation of string
|
type error += Unexpected_macro_annotation of string
|
||||||
type error += Dip_expects_sequence
|
type error += Sequence_expected of string
|
||||||
|
type error += Invalid_arity of string * int * int
|
||||||
|
|
||||||
|
let rec check_letters str i j f =
|
||||||
|
i > j || f (String.get str i) && check_letters str (i + 1) j f
|
||||||
|
|
||||||
let expand_caddadr original =
|
let expand_caddadr original =
|
||||||
ok @@ match original with
|
match original with
|
||||||
| Prim (loc, str, [], annot) ->
|
| Prim (loc, str, args, annot) ->
|
||||||
let len = String.length str in
|
let len = String.length str in
|
||||||
if len > 3
|
if len > 3
|
||||||
&& String.get str 0 = 'C'
|
&& String.get str 0 = 'C'
|
||||||
&& String.get str (len - 1) = 'R' then
|
&& String.get str (len - 1) = 'R'
|
||||||
|
&& check_letters str 1 (len - 2)
|
||||||
|
(function 'A' | 'D' -> true | _ -> false) then
|
||||||
|
begin match args with
|
||||||
|
| [] -> ok ()
|
||||||
|
| _ :: _ -> error (Invalid_arity (str, List.length args, 0))
|
||||||
|
end >>? fun () ->
|
||||||
let rec parse i ?annot acc =
|
let rec parse i ?annot acc =
|
||||||
if i = 0 then
|
if i = 0 then
|
||||||
Some (Seq (loc, acc, None))
|
Seq (loc, acc, None)
|
||||||
else
|
else
|
||||||
let annot = if i = (String.length str - 2) then annot else None in
|
let annot = if i = (String.length str - 2) then annot else None in
|
||||||
match String.get str i with
|
match String.get str i with
|
||||||
| 'A' -> parse (i - 1) (Prim (loc, "CAR", [], annot) :: acc)
|
| 'A' -> parse (i - 1) (Prim (loc, "CAR", [], annot) :: acc)
|
||||||
| 'D' -> parse (i - 1) (Prim (loc, "CDR", [], annot) :: acc)
|
| 'D' -> parse (i - 1) (Prim (loc, "CDR", [], annot) :: acc)
|
||||||
| _ -> None in
|
| _ -> assert false in
|
||||||
parse (len - 2) ?annot []
|
ok (Some (parse (len - 2) ?annot []))
|
||||||
else
|
else
|
||||||
None
|
ok None
|
||||||
| _ -> None
|
| _ -> ok None
|
||||||
|
|
||||||
let expand_set_caddadr original =
|
let expand_set_caddadr original =
|
||||||
ok @@ match original with
|
match original with
|
||||||
| Prim (loc, str, [], annot) ->
|
| Prim (loc, str, args, annot) ->
|
||||||
let len = String.length str in
|
let len = String.length str in
|
||||||
if len >= 7
|
if len >= 7
|
||||||
&& String.sub str 0 5 = "SET_C"
|
&& String.sub str 0 5 = "SET_C"
|
||||||
&& String.get str (len - 1) = 'R' then
|
&& String.get str (len - 1) = 'R'
|
||||||
|
&& check_letters str 5 (len - 2)
|
||||||
|
(function 'A' | 'D' -> true | _ -> false) then
|
||||||
|
begin match args with
|
||||||
|
| [] -> ok ()
|
||||||
|
| _ :: _ -> error (Invalid_arity (str, List.length args, 0))
|
||||||
|
end >>? fun () ->
|
||||||
let rec parse i acc =
|
let rec parse i acc =
|
||||||
if i = 4 then
|
if i = 4 then
|
||||||
Some acc
|
acc
|
||||||
else
|
else
|
||||||
match String.get str i with
|
match String.get str i with
|
||||||
| 'A' ->
|
| 'A' ->
|
||||||
@ -71,7 +87,7 @@ let expand_set_caddadr original =
|
|||||||
Prim (loc, "CAR", [], None) ;
|
Prim (loc, "CAR", [], None) ;
|
||||||
Prim (loc, "PAIR", [], None) ], None) in
|
Prim (loc, "PAIR", [], None) ], None) in
|
||||||
parse (i - 1) acc
|
parse (i - 1) acc
|
||||||
| _ -> None in
|
| _ -> assert false in
|
||||||
match String.get str (len - 2) with
|
match String.get str (len - 2) with
|
||||||
| 'A' ->
|
| 'A' ->
|
||||||
let init =
|
let init =
|
||||||
@ -79,7 +95,7 @@ let expand_set_caddadr original =
|
|||||||
[ Prim (loc, "CDR", [], None) ;
|
[ Prim (loc, "CDR", [], None) ;
|
||||||
Prim (loc, "SWAP", [], annot) ;
|
Prim (loc, "SWAP", [], annot) ;
|
||||||
Prim (loc, "PAIR", [], None) ], None) in
|
Prim (loc, "PAIR", [], None) ], None) in
|
||||||
parse (len - 3) init
|
ok (Some (parse (len - 3) init))
|
||||||
| 'D' ->
|
| 'D' ->
|
||||||
let init =
|
let init =
|
||||||
Seq (loc,
|
Seq (loc,
|
||||||
@ -90,25 +106,33 @@ let expand_set_caddadr original =
|
|||||||
| Some _ -> [ Prim (loc, "SWAP", [], annot) ;
|
| Some _ -> [ Prim (loc, "SWAP", [], annot) ;
|
||||||
Prim (loc, "SWAP", [], None) ;
|
Prim (loc, "SWAP", [], None) ;
|
||||||
pair]), None) in
|
pair]), None) in
|
||||||
parse (len - 3) init
|
ok (Some (parse (len - 3) init))
|
||||||
| _ -> None
|
| _ -> assert false
|
||||||
else
|
else
|
||||||
None
|
ok None
|
||||||
| _ -> None
|
| _ -> ok None
|
||||||
|
|
||||||
let expand_map_caddadr original =
|
let expand_map_caddadr original =
|
||||||
match original with
|
match original with
|
||||||
| Prim (loc, str, [ Seq _ as code ], annot) ->
|
| Prim (loc, str, args, annot) ->
|
||||||
begin match annot with
|
|
||||||
| Some _ -> (error (Unexpected_macro_annotation str))
|
|
||||||
| None -> ok () end >|? fun () ->
|
|
||||||
let len = String.length str in
|
let len = String.length str in
|
||||||
if len >= 7
|
if len >= 7
|
||||||
&& String.sub str 0 5 = "MAP_C"
|
&& String.sub str 0 5 = "MAP_C"
|
||||||
&& String.get str (len - 1) = 'R' then
|
&& String.get str (len - 1) = 'R'
|
||||||
|
&& check_letters str 5 (len - 2)
|
||||||
|
(function 'A' | 'D' -> true | _ -> false) then
|
||||||
|
begin match annot with
|
||||||
|
| Some _ -> (error (Unexpected_macro_annotation str))
|
||||||
|
| None -> ok ()
|
||||||
|
end >>? fun () ->
|
||||||
|
begin match args with
|
||||||
|
| [ Seq _ as code ] -> ok code
|
||||||
|
| [ _ ] -> error (Sequence_expected str)
|
||||||
|
| [] | _ :: _ :: _ -> error (Invalid_arity (str, List.length args, 1))
|
||||||
|
end >>? fun code ->
|
||||||
let rec parse i acc =
|
let rec parse i acc =
|
||||||
if i = 4 then
|
if i = 4 then
|
||||||
Some acc
|
acc
|
||||||
else
|
else
|
||||||
match String.get str i with
|
match String.get str i with
|
||||||
| 'A' ->
|
| 'A' ->
|
||||||
@ -134,7 +158,7 @@ let expand_map_caddadr original =
|
|||||||
Prim (loc, "CAR", [], None) ;
|
Prim (loc, "CAR", [], None) ;
|
||||||
Prim (loc, "PAIR", [], None) ], None) in
|
Prim (loc, "PAIR", [], None) ], None) in
|
||||||
parse (i - 1) acc
|
parse (i - 1) acc
|
||||||
| _ -> None in
|
| _ -> assert false in
|
||||||
match String.get str (len - 2) with
|
match String.get str (len - 2) with
|
||||||
| 'A' ->
|
| 'A' ->
|
||||||
let init =
|
let init =
|
||||||
@ -145,7 +169,7 @@ let expand_map_caddadr original =
|
|||||||
[ Seq (loc, [ Prim (loc, "CAR", [], None) ; code ], None) ], None) ;
|
[ Seq (loc, [ Prim (loc, "CAR", [], None) ; code ], None) ], None) ;
|
||||||
Prim (loc, "SWAP", [], None) ;
|
Prim (loc, "SWAP", [], None) ;
|
||||||
Prim (loc, "PAIR", [], None) ], None) in
|
Prim (loc, "PAIR", [], None) ], None) in
|
||||||
parse (len - 3) init
|
ok (Some (parse (len - 3) init))
|
||||||
| 'D' ->
|
| 'D' ->
|
||||||
let init =
|
let init =
|
||||||
Seq (loc,
|
Seq (loc,
|
||||||
@ -155,10 +179,10 @@ let expand_map_caddadr original =
|
|||||||
Prim (loc, "SWAP", [], None) ;
|
Prim (loc, "SWAP", [], None) ;
|
||||||
Prim (loc, "CAR", [], None) ;
|
Prim (loc, "CAR", [], None) ;
|
||||||
Prim (loc, "PAIR", [], None) ], None) in
|
Prim (loc, "PAIR", [], None) ], None) in
|
||||||
parse (len - 3) init
|
ok (Some (parse (len - 3) init))
|
||||||
| _ -> None
|
| _ -> assert false
|
||||||
else
|
else
|
||||||
None
|
ok None
|
||||||
| _ -> ok None
|
| _ -> ok None
|
||||||
|
|
||||||
exception Not_a_roman
|
exception Not_a_roman
|
||||||
@ -203,7 +227,8 @@ let expand_dxiiivp original =
|
|||||||
(Seq (loc, [ Prim (loc, "DIP", [ acc ], annot) ], None)) in
|
(Seq (loc, [ Prim (loc, "DIP", [ acc ], annot) ], None)) in
|
||||||
match args with
|
match args with
|
||||||
| [ Seq (_, _, _) as arg ] -> ok @@ Some (make depth arg)
|
| [ Seq (_, _, _) as arg ] -> ok @@ Some (make depth arg)
|
||||||
| _ -> error Dip_expects_sequence
|
| [ _ ] -> error (Sequence_expected str)
|
||||||
|
| [] | _ :: _ :: _ -> error (Invalid_arity (str, List.length args, 1))
|
||||||
with Not_a_roman -> ok None
|
with Not_a_roman -> ok None
|
||||||
else ok None
|
else ok None
|
||||||
| _ -> ok None
|
| _ -> ok None
|
||||||
@ -212,11 +237,13 @@ exception Not_a_pair
|
|||||||
|
|
||||||
let expand_paaiair original =
|
let expand_paaiair original =
|
||||||
match original with
|
match original with
|
||||||
| Prim (loc, str, [], annot) ->
|
| Prim (loc, str, args, annot) ->
|
||||||
let len = String.length str in
|
let len = String.length str in
|
||||||
if len > 4
|
if len > 4
|
||||||
&& String.get str 0 = 'P'
|
&& String.get str 0 = 'P'
|
||||||
&& String.get str (len - 1) = 'R' then
|
&& String.get str (len - 1) = 'R'
|
||||||
|
&& check_letters str 1 (len - 2)
|
||||||
|
(function 'A' | 'I' -> true | _ -> false) then
|
||||||
try
|
try
|
||||||
let rec parse i acc =
|
let rec parse i acc =
|
||||||
if i = 0 then
|
if i = 0 then
|
||||||
@ -234,19 +261,26 @@ let expand_paaiair original =
|
|||||||
:: accs)
|
:: accs)
|
||||||
else
|
else
|
||||||
raise_notrace Not_a_pair in
|
raise_notrace Not_a_pair in
|
||||||
ok @@ Some (Seq (loc, parse (len - 2) [], None))
|
let expanded = parse (len - 2) [] in
|
||||||
|
begin match args with
|
||||||
|
| [] -> ok ()
|
||||||
|
| _ :: _ -> error (Invalid_arity (str, List.length args, 0))
|
||||||
|
end >>? fun () ->
|
||||||
|
ok (Some (Seq (loc, expanded, None)))
|
||||||
with Not_a_pair -> ok None
|
with Not_a_pair -> ok None
|
||||||
else
|
else
|
||||||
ok None
|
ok None
|
||||||
| _ -> ok None
|
| _ -> ok None
|
||||||
|
|
||||||
let expand_unpaaiair original =
|
let expand_unpaaiair original =
|
||||||
ok @@ match original with
|
match original with
|
||||||
| Prim (loc, str, [], None) ->
|
| Prim (loc, str, args, None) ->
|
||||||
let len = String.length str in
|
let len = String.length str in
|
||||||
if len >= 6
|
if len >= 6
|
||||||
&& String.sub str 0 3 = "UNP"
|
&& String.sub str 0 3 = "UNP"
|
||||||
&& String.get str (len - 1) = 'R' then
|
&& String.get str (len - 1) = 'R'
|
||||||
|
&& check_letters str 3 (len - 2)
|
||||||
|
(function 'A' | 'I' -> true | _ -> false) then
|
||||||
try
|
try
|
||||||
let rec parse i acc =
|
let rec parse i acc =
|
||||||
if i = 2 then
|
if i = 2 then
|
||||||
@ -277,22 +311,31 @@ let expand_unpaaiair original =
|
|||||||
None) :: accs)
|
None) :: accs)
|
||||||
else
|
else
|
||||||
raise_notrace Not_a_pair in
|
raise_notrace Not_a_pair in
|
||||||
Some (parse (len - 2) [])
|
let expanded = parse (len - 2) [] in
|
||||||
with Not_a_pair -> None
|
begin match args with
|
||||||
|
| [] -> ok ()
|
||||||
|
| _ :: _ -> error (Invalid_arity (str, List.length args, 0))
|
||||||
|
end >>? fun () ->
|
||||||
|
ok (Some expanded)
|
||||||
|
with Not_a_pair -> ok None
|
||||||
else
|
else
|
||||||
None
|
ok None
|
||||||
| _ -> None
|
| _ -> ok None
|
||||||
|
|
||||||
exception Not_a_dup
|
exception Not_a_dup
|
||||||
|
|
||||||
let expand_duuuuup original =
|
let expand_duuuuup original =
|
||||||
ok @@ match original with
|
match original with
|
||||||
| Prim (loc, str, [], annot) ->
|
| Prim (loc, str, args, annot) ->
|
||||||
let len = String.length str in
|
let len = String.length str in
|
||||||
if len > 3
|
if len > 3
|
||||||
&& String.get str 0 = 'D'
|
&& String.get str 0 = 'D'
|
||||||
&& String.get str 1 = 'U'
|
&& String.get str (len - 1) = 'P'
|
||||||
&& String.get str (len - 1) = 'P' then
|
&& check_letters str 1 (len - 2) ((=) 'U') then
|
||||||
|
begin match args with
|
||||||
|
| [] -> ok ()
|
||||||
|
| _ :: _ -> error (Invalid_arity (str, List.length args, 0))
|
||||||
|
end >>? fun () ->
|
||||||
try
|
try
|
||||||
let rec parse i acc =
|
let rec parse i acc =
|
||||||
if i = 1 then acc
|
if i = 1 then acc
|
||||||
@ -302,76 +345,75 @@ let expand_duuuuup original =
|
|||||||
Prim (loc, "SWAP", [], None) ], None))
|
Prim (loc, "SWAP", [], None) ], None))
|
||||||
else
|
else
|
||||||
raise_notrace Not_a_dup in
|
raise_notrace Not_a_dup in
|
||||||
Some (parse (len - 2) (Seq (loc, [ Prim (loc, "DUP", [], annot) ], None)))
|
ok (Some (parse (len - 2) (Seq (loc, [ Prim (loc, "DUP", [], annot) ], None))))
|
||||||
with Not_a_dup -> None
|
with Not_a_dup -> ok None
|
||||||
else
|
else
|
||||||
None
|
ok None
|
||||||
| _ -> None
|
| _ -> ok None
|
||||||
|
|
||||||
let expand_compare original =
|
let expand_compare original =
|
||||||
ok @@ match original with
|
let cmp loc is =
|
||||||
|
let is =
|
||||||
|
List.map (fun i -> Prim (loc, i, [], None)) is in
|
||||||
|
ok (Some (Seq (loc, is, None))) in
|
||||||
|
let ifcmp loc is l r =
|
||||||
|
let is =
|
||||||
|
List.map (fun i -> Prim (loc, i, [], None)) is @
|
||||||
|
[ Prim (loc, "IF", [ l ; r ], None) ] in
|
||||||
|
ok (Some (Seq (loc, is, None))) in
|
||||||
|
match original with
|
||||||
| Prim (loc, "CMPEQ", [], None) ->
|
| Prim (loc, "CMPEQ", [], None) ->
|
||||||
Some (Seq (loc, [ Prim (loc, "COMPARE", [], None) ;
|
cmp loc [ "COMPARE" ; "EQ" ]
|
||||||
Prim (loc, "EQ", [], None) ], None))
|
|
||||||
| Prim (loc, "CMPNEQ", [], None) ->
|
| Prim (loc, "CMPNEQ", [], None) ->
|
||||||
Some (Seq (loc, [ Prim (loc, "COMPARE", [], None) ;
|
cmp loc [ "COMPARE" ; "NEQ" ]
|
||||||
Prim (loc, "NEQ", [], None) ], None))
|
|
||||||
| Prim (loc, "CMPLT", [], None) ->
|
| Prim (loc, "CMPLT", [], None) ->
|
||||||
Some (Seq (loc, [ Prim (loc, "COMPARE", [], None) ;
|
cmp loc [ "COMPARE" ; "LT" ]
|
||||||
Prim (loc, "LT", [], None) ], None))
|
|
||||||
| Prim (loc, "CMPGT", [], None) ->
|
| Prim (loc, "CMPGT", [], None) ->
|
||||||
Some (Seq (loc, [ Prim (loc, "COMPARE", [], None) ;
|
cmp loc [ "COMPARE" ; "GT" ]
|
||||||
Prim (loc, "GT", [], None) ], None))
|
|
||||||
| Prim (loc, "CMPLE", [], None) ->
|
| Prim (loc, "CMPLE", [], None) ->
|
||||||
Some (Seq (loc, [ Prim (loc, "COMPARE", [], None) ;
|
cmp loc [ "COMPARE" ; "LE" ]
|
||||||
Prim (loc, "LE", [], None) ], None))
|
|
||||||
| Prim (loc, "CMPGE", [], None) ->
|
| Prim (loc, "CMPGE", [], None) ->
|
||||||
Some (Seq (loc, [ Prim (loc, "COMPARE", [], None) ;
|
cmp loc [ "COMPARE" ; "GE" ]
|
||||||
Prim (loc, "GE", [], None) ], None))
|
| Prim (_, ("CMPEQ" | "CMPNEQ" | "CMPLT"
|
||||||
| Prim (loc, "IFCMPEQ", args, None) ->
|
| "CMPGT" | "CMPLE" | "CMPGE" as str), args, None) ->
|
||||||
Some (Seq (loc, [ Prim (loc, "COMPARE", [], None) ;
|
error (Invalid_arity (str, List.length args, 0))
|
||||||
Prim (loc, "EQ", [], None) ;
|
| Prim (loc, "IFCMPEQ", [ l ; r ], None) ->
|
||||||
Prim (loc, "IF", args, None) ], None))
|
ifcmp loc [ "COMPARE" ; "EQ" ] l r
|
||||||
| Prim (loc, "IFCMPNEQ", args, None) ->
|
| Prim (loc, "IFCMPNEQ", [ l ; r ], None) ->
|
||||||
Some (Seq (loc, [ Prim (loc, "COMPARE", [], None) ;
|
ifcmp loc [ "COMPARE" ; "NEQ" ] l r
|
||||||
Prim (loc, "NEQ", [], None) ;
|
| Prim (loc, "IFCMPLT", [ l ; r ], None) ->
|
||||||
Prim (loc, "IF", args, None) ], None))
|
ifcmp loc [ "COMPARE" ; "LT" ] l r
|
||||||
| Prim (loc, "IFCMPLT", args, None) ->
|
| Prim (loc, "IFCMPGT", [ l ; r ], None) ->
|
||||||
Some (Seq (loc, [ Prim (loc, "COMPARE", [], None) ;
|
ifcmp loc [ "COMPARE" ; "GT" ] l r
|
||||||
Prim (loc, "LT", [], None) ;
|
| Prim (loc, "IFCMPLE", [ l ; r ], None) ->
|
||||||
Prim (loc, "IF", args, None) ], None))
|
ifcmp loc [ "COMPARE" ; "LE" ] l r
|
||||||
| Prim (loc, "IFCMPGT", args, None) ->
|
| Prim (loc, "IFCMPGE", [ l ; r ], None) ->
|
||||||
Some (Seq (loc, [ Prim (loc, "COMPARE", [], None) ;
|
ifcmp loc [ "COMPARE" ; "GE" ] l r
|
||||||
Prim (loc, "GT", [], None) ;
|
| Prim (loc, "IFEQ", [ l ; r ], None) ->
|
||||||
Prim (loc, "IF", args, None) ], None))
|
ifcmp loc [ "EQ" ] l r
|
||||||
| Prim (loc, "IFCMPLE", args, None) ->
|
| Prim (loc, "IFNEQ", [ l ; r ], None) ->
|
||||||
Some (Seq (loc, [ Prim (loc, "COMPARE", [], None) ;
|
ifcmp loc [ "NEQ" ] l r
|
||||||
Prim (loc, "LE", [], None) ;
|
| Prim (loc, "IFLT", [ l ; r ], None) ->
|
||||||
Prim (loc, "IF", args, None) ], None))
|
ifcmp loc [ "LT" ] l r
|
||||||
| Prim (loc, "IFCMPGE", args, None) ->
|
| Prim (loc, "IFGT", [ l ; r ], None) ->
|
||||||
Some (Seq (loc, [ Prim (loc, "COMPARE", [], None) ;
|
ifcmp loc [ "GT" ] l r
|
||||||
Prim (loc, "GE", [], None) ;
|
| Prim (loc, "IFLE", [ l ; r ], None) ->
|
||||||
Prim (loc, "IF", args, None) ], None))
|
ifcmp loc [ "LE" ] l r
|
||||||
| Prim (loc, "IFEQ", args, None) ->
|
| Prim (loc, "IFGE", [ l ; r ], None) ->
|
||||||
Some (Seq (loc, [ Prim (loc, "EQ", [], None) ;
|
ifcmp loc [ "GE" ] l r
|
||||||
Prim (loc, "IF", args, None) ], None))
|
| Prim (_, ("IFCMPEQ" | "IFCMPNEQ" | "IFCMPLT"
|
||||||
| Prim (loc, "IFNEQ", args, None) ->
|
| "IFCMPGT" | "IFCMPLE" | "IFCMPGE"
|
||||||
Some (Seq (loc, [ Prim (loc, "NEQ", [], None) ;
|
| "IFEQ" | "IFNEQ" | "IFLT"
|
||||||
Prim (loc, "IF", args, None) ], None))
|
| "IFGT" | "IFLE" | "IFGE" as str), args, None) ->
|
||||||
| Prim (loc, "IFLT", args, None) ->
|
error (Invalid_arity (str, List.length args, 2))
|
||||||
Some (Seq (loc, [ Prim (loc, "LT", [], None) ;
|
| Prim (_, ("IFCMPEQ" | "IFCMPNEQ" | "IFCMPLT"
|
||||||
Prim (loc, "IF", args, None) ], None))
|
| "IFCMPGT" | "IFCMPLE" | "IFCMPGE"
|
||||||
| Prim (loc, "IFGT", args, None) ->
|
| "IFEQ" | "IFNEQ" | "IFLT"
|
||||||
Some (Seq (loc, [ Prim (loc, "GT", [], None) ;
|
| "IFGT" | "IFLE" | "IFGE"
|
||||||
Prim (loc, "IF", args, None) ], None))
|
| "CMPEQ" | "CMPNEQ" | "CMPLT"
|
||||||
| Prim (loc, "IFLE", args, None) ->
|
| "CMPGT" | "CMPLE" | "CMPGE" as str), [], Some _) ->
|
||||||
Some (Seq (loc, [ Prim (loc, "LE", [], None) ;
|
error (Unexpected_macro_annotation str)
|
||||||
Prim (loc, "IF", args, None) ], None))
|
| _ -> ok None
|
||||||
| Prim (loc, "IFGE", args, None) ->
|
|
||||||
Some (Seq (loc, [ Prim (loc, "GE", [], None) ;
|
|
||||||
Prim (loc, "IF", args, None) ], None))
|
|
||||||
| _ -> None
|
|
||||||
|
|
||||||
|
|
||||||
let expand_asserts original =
|
let expand_asserts original =
|
||||||
let fail_false loc =
|
let fail_false loc =
|
||||||
@ -389,8 +431,21 @@ let expand_asserts original =
|
|||||||
ok @@ Some (Seq (loc, [ Prim (loc, "IF_LEFT", fail_false loc, None) ], None))
|
ok @@ Some (Seq (loc, [ Prim (loc, "IF_LEFT", fail_false loc, None) ], None))
|
||||||
| Prim (loc, "ASSERT_RIGHT", [], None) ->
|
| Prim (loc, "ASSERT_RIGHT", [], None) ->
|
||||||
ok @@ Some (Seq (loc, [ Prim (loc, "IF_LEFT", fail_true loc, None) ], None))
|
ok @@ Some (Seq (loc, [ Prim (loc, "IF_LEFT", fail_true loc, None) ], None))
|
||||||
| Prim (loc, s, [], None)
|
| Prim (_, ("ASSERT" | "ASSERT_NONE" | "ASSERT_SOME"
|
||||||
|
| "ASSERT_LEFT" | "ASSERT_RIGHT" as str), args, None) ->
|
||||||
|
error (Invalid_arity (str, List.length args, 0))
|
||||||
|
| Prim (_, ("ASSERT" | "ASSERT_NONE" | "ASSERT_SOME"
|
||||||
|
| "ASSERT_LEFT" | "ASSERT_RIGHT" as str), [], Some _) ->
|
||||||
|
error (Unexpected_macro_annotation str)
|
||||||
|
| Prim (loc, s, args, annot)
|
||||||
when String.(length s > 7 && equal (sub s 0 7) "ASSERT_") ->
|
when String.(length s > 7 && equal (sub s 0 7) "ASSERT_") ->
|
||||||
|
begin match args with
|
||||||
|
| [] -> ok ()
|
||||||
|
| _ :: _ -> error (Invalid_arity (s, List.length args, 0))
|
||||||
|
end >>? fun () ->
|
||||||
|
begin match annot with
|
||||||
|
| Some _ -> (error (Unexpected_macro_annotation s))
|
||||||
|
| None -> ok () end >>? fun () ->
|
||||||
begin
|
begin
|
||||||
let remaining = String.(sub s 7 ((length s) - 7)) in
|
let remaining = String.(sub s 7 ((length s) - 7)) in
|
||||||
let remaining_prim = Prim(loc, remaining, [], None) in
|
let remaining_prim = Prim(loc, remaining, [], None) in
|
||||||
@ -413,11 +468,19 @@ let expand_asserts original =
|
|||||||
let expand_if_some = function
|
let expand_if_some = function
|
||||||
| Prim (loc, "IF_SOME", [ right ; left ], None) ->
|
| Prim (loc, "IF_SOME", [ right ; left ], None) ->
|
||||||
ok @@ Some (Seq (loc, [ Prim (loc, "IF_NONE", [ left ; right ], None) ], None))
|
ok @@ Some (Seq (loc, [ Prim (loc, "IF_NONE", [ left ; right ], None) ], None))
|
||||||
|
| Prim (_, "IF_SOME", args, None) ->
|
||||||
|
error (Invalid_arity ("IF_SOME", List.length args, 2))
|
||||||
|
| Prim (_, "IF_SOME", [], Some _) ->
|
||||||
|
error (Unexpected_macro_annotation "IF_SOME")
|
||||||
| _ -> ok @@ None
|
| _ -> ok @@ None
|
||||||
|
|
||||||
let expand_if_right = function
|
let expand_if_right = function
|
||||||
| Prim (loc, "IF_RIGHT", [ right ; left ], None) ->
|
| Prim (loc, "IF_RIGHT", [ right ; left ], None) ->
|
||||||
ok @@ Some (Seq (loc, [ Prim (loc, "IF_LEFT", [ left ; right ], None) ], None))
|
ok @@ Some (Seq (loc, [ Prim (loc, "IF_LEFT", [ left ; right ], None) ], None))
|
||||||
|
| Prim (_, "IF_RIGHT", args, None) ->
|
||||||
|
error (Invalid_arity ("IF_RIGHT", List.length args, 2))
|
||||||
|
| Prim (_, "IF_RIGHT", [], Some _) ->
|
||||||
|
error (Unexpected_macro_annotation "IF_RIGHT")
|
||||||
| _ -> ok @@ None
|
| _ -> ok @@ None
|
||||||
|
|
||||||
let expand original =
|
let expand original =
|
||||||
@ -781,28 +844,45 @@ let () =
|
|||||||
let open Data_encoding in
|
let open Data_encoding in
|
||||||
register_error_kind
|
register_error_kind
|
||||||
`Permanent
|
`Permanent
|
||||||
~id:"unexpectedMacroAnnotation"
|
~id:"michelson.macros.unexpected_annotation"
|
||||||
~title:"Unexpected annotation"
|
~title:"Unexpected annotation"
|
||||||
~description:"A macro had an annotation, but no annotation was permitted on this macro."
|
~description:"A macro had an annotation, but no annotation was permitted on this macro."
|
||||||
~pp:(fun ppf ->
|
~pp:(fun ppf ->
|
||||||
Format.fprintf ppf
|
Format.fprintf ppf
|
||||||
"@[<hov 0>@[<hov 2>Unexpected annotation on instruction %s.@]@]")
|
"Unexpected annotation on macro %s.")
|
||||||
(obj1
|
(obj1
|
||||||
(req "instrName" string))
|
(req "macro_name" string))
|
||||||
(function
|
(function
|
||||||
| Unexpected_macro_annotation str -> Some str
|
| Unexpected_macro_annotation str -> Some str
|
||||||
| _ -> None)
|
| _ -> None)
|
||||||
(fun s -> Unexpected_macro_annotation s) ;
|
(fun s -> Unexpected_macro_annotation s) ;
|
||||||
register_error_kind
|
register_error_kind
|
||||||
`Permanent
|
`Permanent
|
||||||
~id:"dipExpectsSequence"
|
~id:"michelson.macros.sequence_expected"
|
||||||
~title:"Dip instruction expects a sequence"
|
~title:"Macro expects a sequence"
|
||||||
~description:"A dip instruction expects a sequence, but a sequence was not provided"
|
~description:"An macro expects a sequence, but a sequence was not provided"
|
||||||
~pp:(fun ppf () ->
|
~pp:(fun ppf name ->
|
||||||
Format.fprintf ppf
|
Format.fprintf ppf
|
||||||
"@[<hov 0>@[<hov 2>DIP instructionf expects a sequence, but did not receive one.@]@]")
|
"Macro %s expects a sequence, but did not receive one." name)
|
||||||
empty
|
(obj1
|
||||||
|
(req "macro_name" string))
|
||||||
(function
|
(function
|
||||||
| Dip_expects_sequence -> Some ()
|
| Sequence_expected name -> Some name
|
||||||
| _ -> None)
|
| _ -> None)
|
||||||
(fun () -> Dip_expects_sequence)
|
(fun name -> Sequence_expected name) ;
|
||||||
|
register_error_kind
|
||||||
|
`Permanent
|
||||||
|
~id:"michelson.macros.bas_arity"
|
||||||
|
~title:"Wrong number of arguments to macro"
|
||||||
|
~description:"A wrong number of arguments was provided to a macro"
|
||||||
|
~pp:(fun ppf (name, got, exp) ->
|
||||||
|
Format.fprintf ppf
|
||||||
|
"Macro %s expects %d arguments, was given %d." name got exp)
|
||||||
|
(obj3
|
||||||
|
(req "macro_name" string)
|
||||||
|
(req "given_number_of_arguments" uint16)
|
||||||
|
(req "expected_number_of_arguments" uint16))
|
||||||
|
(function
|
||||||
|
| Invalid_arity (name, got, exp) -> Some (name, got, exp)
|
||||||
|
| _ -> None)
|
||||||
|
(fun (name, got, exp) -> Invalid_arity (name, got, exp))
|
||||||
|
@ -12,7 +12,8 @@ open Tezos_micheline
|
|||||||
type 'l node = ('l, string) Micheline.node
|
type 'l node = ('l, string) Micheline.node
|
||||||
|
|
||||||
type error += Unexpected_macro_annotation of string
|
type error += Unexpected_macro_annotation of string
|
||||||
type error += Dip_expects_sequence
|
type error += Sequence_expected of string
|
||||||
|
type error += Invalid_arity of string * int * int
|
||||||
|
|
||||||
val expand : 'l node -> 'l node tzresult
|
val expand : 'l node -> 'l node tzresult
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user