Michelson macros: annotations permitted and better error handling
This commit is contained in:
parent
ae2959b91c
commit
76e70a2799
@ -12,8 +12,11 @@ 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 += Dip_expects_sequence
|
||||||
|
|
||||||
let expand_caddadr original =
|
let expand_caddadr original =
|
||||||
match original with
|
ok @@ match original with
|
||||||
| Prim (loc, str, [], annot) ->
|
| Prim (loc, str, [], annot) ->
|
||||||
let len = String.length str in
|
let len = String.length str in
|
||||||
if len > 3
|
if len > 3
|
||||||
@ -23,6 +26,7 @@ let expand_caddadr original =
|
|||||||
if i = 0 then
|
if i = 0 then
|
||||||
Some (Seq (loc, acc, None))
|
Some (Seq (loc, acc, None))
|
||||||
else
|
else
|
||||||
|
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)
|
||||||
@ -33,8 +37,8 @@ let expand_caddadr original =
|
|||||||
| _ -> None
|
| _ -> None
|
||||||
|
|
||||||
let expand_set_caddadr original =
|
let expand_set_caddadr original =
|
||||||
match original with
|
ok @@ match original with
|
||||||
| Prim (loc, str, [], None) ->
|
| Prim (loc, str, [], 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"
|
||||||
@ -73,14 +77,19 @@ let expand_set_caddadr original =
|
|||||||
let init =
|
let init =
|
||||||
Seq (loc,
|
Seq (loc,
|
||||||
[ Prim (loc, "CDR", [], None) ;
|
[ Prim (loc, "CDR", [], None) ;
|
||||||
Prim (loc, "SWAP", [], None) ;
|
Prim (loc, "SWAP", [], annot) ;
|
||||||
Prim (loc, "PAIR", [], None) ], None) in
|
Prim (loc, "PAIR", [], None) ], None) in
|
||||||
parse (len - 3) init
|
parse (len - 3) init
|
||||||
| 'D' ->
|
| 'D' ->
|
||||||
let init =
|
let init =
|
||||||
Seq (loc,
|
Seq (loc,
|
||||||
[ Prim (loc, "CAR", [], None) ;
|
(Prim (loc, "CAR", [], None)) ::
|
||||||
Prim (loc, "PAIR", [], None) ], None) in
|
(let pair = Prim (loc, "PAIR", [], None) in
|
||||||
|
match annot with
|
||||||
|
| None -> [ pair ]
|
||||||
|
| Some _ -> [ Prim (loc, "SWAP", [], annot) ;
|
||||||
|
Prim (loc, "SWAP", [], None) ;
|
||||||
|
pair]), None) in
|
||||||
parse (len - 3) init
|
parse (len - 3) init
|
||||||
| _ -> None
|
| _ -> None
|
||||||
else
|
else
|
||||||
@ -89,7 +98,10 @@ let expand_set_caddadr original =
|
|||||||
|
|
||||||
let expand_map_caddadr original =
|
let expand_map_caddadr original =
|
||||||
match original with
|
match original with
|
||||||
| Prim (loc, str, [ Seq _ as code ], None) ->
|
| Prim (loc, str, [ Seq _ as code ], 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"
|
||||||
@ -129,9 +141,9 @@ let expand_map_caddadr original =
|
|||||||
Seq (loc,
|
Seq (loc,
|
||||||
[ Prim (loc, "DUP", [], None) ;
|
[ Prim (loc, "DUP", [], None) ;
|
||||||
Prim (loc, "CDR", [], None) ;
|
Prim (loc, "CDR", [], None) ;
|
||||||
|
Prim (loc, "DIP",
|
||||||
|
[ Seq (loc, [ Prim (loc, "CAR", [], None) ; code ], None) ], None) ;
|
||||||
Prim (loc, "SWAP", [], None) ;
|
Prim (loc, "SWAP", [], None) ;
|
||||||
Prim (loc, "CAR", [], None) ;
|
|
||||||
code ;
|
|
||||||
Prim (loc, "PAIR", [], None) ], None) in
|
Prim (loc, "PAIR", [], None) ], None) in
|
||||||
parse (len - 3) init
|
parse (len - 3) init
|
||||||
| 'D' ->
|
| 'D' ->
|
||||||
@ -147,7 +159,7 @@ let expand_map_caddadr original =
|
|||||||
| _ -> None
|
| _ -> None
|
||||||
else
|
else
|
||||||
None
|
None
|
||||||
| _ -> None
|
| _ -> ok None
|
||||||
|
|
||||||
exception Not_a_roman
|
exception Not_a_roman
|
||||||
|
|
||||||
@ -165,7 +177,7 @@ let decimal_of_roman roman =
|
|||||||
| 'X' -> 10
|
| 'X' -> 10
|
||||||
| 'V' -> 5
|
| 'V' -> 5
|
||||||
| 'I' -> 1
|
| 'I' -> 1
|
||||||
| _ -> raise Not_a_roman
|
| _ -> raise_notrace Not_a_roman
|
||||||
in
|
in
|
||||||
if Compare.Int.(n < !lastval)
|
if Compare.Int.(n < !lastval)
|
||||||
then arabic := !arabic - n
|
then arabic := !arabic - n
|
||||||
@ -176,7 +188,7 @@ let decimal_of_roman roman =
|
|||||||
|
|
||||||
let expand_dxiiivp original =
|
let expand_dxiiivp original =
|
||||||
match original with
|
match original with
|
||||||
| Prim (loc, str, [ arg ], None) ->
|
| 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'
|
||||||
@ -188,17 +200,19 @@ let expand_dxiiivp original =
|
|||||||
acc
|
acc
|
||||||
else
|
else
|
||||||
make (i - 1)
|
make (i - 1)
|
||||||
(Seq (loc, [ Prim (loc, "DIP", [ acc ], None) ], None)) in
|
(Seq (loc, [ Prim (loc, "DIP", [ acc ], annot) ], None)) in
|
||||||
Some (make depth arg)
|
match args with
|
||||||
with Not_a_roman -> None
|
| [ Seq (_, _, _) as arg ] -> ok @@ Some (make depth arg)
|
||||||
else None
|
| _ -> error Dip_expects_sequence
|
||||||
| _ -> None
|
with Not_a_roman -> ok None
|
||||||
|
else ok None
|
||||||
|
| _ -> ok None
|
||||||
|
|
||||||
exception Not_a_pair
|
exception Not_a_pair
|
||||||
|
|
||||||
let expand_paaiair original =
|
let expand_paaiair original =
|
||||||
match original with
|
match original with
|
||||||
| Prim (loc, str, [], None) ->
|
| Prim (loc, str, [], 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'
|
||||||
@ -209,25 +223,25 @@ let expand_paaiair original =
|
|||||||
acc
|
acc
|
||||||
else if String.get str i = 'I'
|
else if String.get str i = 'I'
|
||||||
&& String.get str (i - 1) = 'A' then
|
&& String.get str (i - 1) = 'A' then
|
||||||
parse (i - 2) (Prim (loc, "PAIR", [], None) :: acc)
|
parse (i - 2) (Prim (loc, "PAIR", [], if i = (len - 2) then annot else None) :: acc)
|
||||||
else if String.get str i = 'A' then
|
else if String.get str i = 'A' then
|
||||||
match acc with
|
match acc with
|
||||||
| [] ->
|
| [] ->
|
||||||
raise Not_a_pair
|
raise_notrace Not_a_pair
|
||||||
| acc :: accs ->
|
| acc :: accs ->
|
||||||
parse (i - 1)
|
parse (i - 1)
|
||||||
(Prim (loc, "DIP", [ Seq (loc, [ acc ], None) ], None)
|
(Prim (loc, "DIP", [ Seq (loc, [ acc ], None) ], None)
|
||||||
:: accs)
|
:: accs)
|
||||||
else
|
else
|
||||||
raise Not_a_pair in
|
raise_notrace Not_a_pair in
|
||||||
Some (Seq (loc, parse (len - 2) [], None))
|
ok @@ Some (Seq (loc, parse (len - 2) [], None))
|
||||||
with Not_a_pair -> None
|
with Not_a_pair -> ok None
|
||||||
else
|
else
|
||||||
None
|
ok None
|
||||||
| _ -> None
|
| _ -> ok None
|
||||||
|
|
||||||
let expand_unpaaiair original =
|
let expand_unpaaiair original =
|
||||||
match original with
|
ok @@ match original with
|
||||||
| Prim (loc, str, [], None) ->
|
| Prim (loc, str, [], None) ->
|
||||||
let len = String.length str in
|
let len = String.length str in
|
||||||
if len >= 6
|
if len >= 6
|
||||||
@ -252,7 +266,7 @@ let expand_unpaaiair original =
|
|||||||
else if String.get str i = 'A' then
|
else if String.get str i = 'A' then
|
||||||
match acc with
|
match acc with
|
||||||
| [] ->
|
| [] ->
|
||||||
raise Not_a_pair
|
raise_notrace Not_a_pair
|
||||||
| (Seq _ as acc) :: accs ->
|
| (Seq _ as acc) :: accs ->
|
||||||
parse (i - 1)
|
parse (i - 1)
|
||||||
(Prim (loc, "DIP", [ acc ], None) :: accs)
|
(Prim (loc, "DIP", [ acc ], None) :: accs)
|
||||||
@ -262,7 +276,7 @@ let expand_unpaaiair original =
|
|||||||
[ Seq (loc, [ acc ], None) ],
|
[ Seq (loc, [ acc ], None) ],
|
||||||
None) :: accs)
|
None) :: accs)
|
||||||
else
|
else
|
||||||
raise Not_a_pair in
|
raise_notrace Not_a_pair in
|
||||||
Some (parse (len - 2) [])
|
Some (parse (len - 2) [])
|
||||||
with Not_a_pair -> None
|
with Not_a_pair -> None
|
||||||
else
|
else
|
||||||
@ -272,8 +286,8 @@ let expand_unpaaiair original =
|
|||||||
exception Not_a_dup
|
exception Not_a_dup
|
||||||
|
|
||||||
let expand_duuuuup original =
|
let expand_duuuuup original =
|
||||||
match original with
|
ok @@ match original with
|
||||||
| Prim (loc, str, [], None) ->
|
| Prim (loc, str, [], 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'
|
||||||
@ -287,15 +301,15 @@ let expand_duuuuup original =
|
|||||||
(Seq (loc, [ Prim (loc, "DIP", [ acc ], None) ;
|
(Seq (loc, [ Prim (loc, "DIP", [ acc ], None) ;
|
||||||
Prim (loc, "SWAP", [], None) ], None))
|
Prim (loc, "SWAP", [], None) ], None))
|
||||||
else
|
else
|
||||||
raise Not_a_dup in
|
raise_notrace Not_a_dup in
|
||||||
Some (parse (len - 2) (Seq (loc, [ Prim (loc, "DUP", [], None) ], None)))
|
Some (parse (len - 2) (Seq (loc, [ Prim (loc, "DUP", [], annot) ], None)))
|
||||||
with Not_a_dup -> None
|
with Not_a_dup -> None
|
||||||
else
|
else
|
||||||
None
|
None
|
||||||
| _ -> None
|
| _ -> None
|
||||||
|
|
||||||
let expand_compare original =
|
let expand_compare original =
|
||||||
match original with
|
ok @@ match original with
|
||||||
| Prim (loc, "CMPEQ", [], None) ->
|
| Prim (loc, "CMPEQ", [], None) ->
|
||||||
Some (Seq (loc, [ Prim (loc, "COMPARE", [], None) ;
|
Some (Seq (loc, [ Prim (loc, "COMPARE", [], None) ;
|
||||||
Prim (loc, "EQ", [], None) ], None))
|
Prim (loc, "EQ", [], None) ], None))
|
||||||
@ -356,7 +370,7 @@ let expand_compare original =
|
|||||||
| Prim (loc, "IFGE", args, None) ->
|
| Prim (loc, "IFGE", args, None) ->
|
||||||
Some (Seq (loc, [ Prim (loc, "GE", [], None) ;
|
Some (Seq (loc, [ Prim (loc, "GE", [], None) ;
|
||||||
Prim (loc, "IF", args, None) ], None))
|
Prim (loc, "IF", args, None) ], None))
|
||||||
| _ -> None;;
|
| _ -> None
|
||||||
|
|
||||||
|
|
||||||
let expand_asserts original =
|
let expand_asserts original =
|
||||||
@ -366,15 +380,15 @@ let expand_asserts original =
|
|||||||
[ Seq(loc, [ Prim (loc, "FAIL", [], None) ], None) ; Seq(loc, [], None) ] in
|
[ Seq(loc, [ Prim (loc, "FAIL", [], None) ], None) ; Seq(loc, [], None) ] in
|
||||||
match original with
|
match original with
|
||||||
| Prim (loc, "ASSERT", [], None) ->
|
| Prim (loc, "ASSERT", [], None) ->
|
||||||
Some (Seq (loc, [ Prim (loc, "IF", fail_false loc, None) ], None))
|
ok @@ Some (Seq (loc, [ Prim (loc, "IF", fail_false loc, None) ], None))
|
||||||
| Prim (loc, "ASSERT_NONE", [], None) ->
|
| Prim (loc, "ASSERT_NONE", [], None) ->
|
||||||
Some (Seq (loc, [ Prim (loc, "IF_NONE", fail_false loc, None) ], None))
|
ok @@ Some (Seq (loc, [ Prim (loc, "IF_NONE", fail_false loc, None) ], None))
|
||||||
| Prim (loc, "ASSERT_SOME", [], None) ->
|
| Prim (loc, "ASSERT_SOME", [], None) ->
|
||||||
Some (Seq (loc, [ Prim (loc, "IF_NONE", fail_true loc, None) ], None))
|
ok @@ Some (Seq (loc, [ Prim (loc, "IF_NONE", fail_true loc, None) ], None))
|
||||||
| Prim (loc, "ASSERT_LEFT", [], None) ->
|
| Prim (loc, "ASSERT_LEFT", [], None) ->
|
||||||
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) ->
|
||||||
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 (loc, s, [], None)
|
||||||
when String.(length s > 7 && equal (sub s 0 7) "ASSERT_") ->
|
when String.(length s > 7 && equal (sub s 0 7) "ASSERT_") ->
|
||||||
begin
|
begin
|
||||||
@ -382,41 +396,37 @@ let expand_asserts original =
|
|||||||
let remaining_prim = Prim(loc, remaining, [], None) in
|
let remaining_prim = Prim(loc, remaining, [], None) in
|
||||||
match remaining with
|
match remaining with
|
||||||
| "EQ" | "NEQ" | "LT" | "LE" | "GE" | "GT" ->
|
| "EQ" | "NEQ" | "LT" | "LE" | "GE" | "GT" ->
|
||||||
Some (Seq (loc, [ remaining_prim ;
|
ok @@ Some (Seq (loc, [ remaining_prim ;
|
||||||
Prim (loc, "IF", fail_false loc, None) ], None))
|
Prim (loc, "IF", fail_false loc, None) ], None))
|
||||||
| _ ->
|
| _ ->
|
||||||
begin
|
begin
|
||||||
match expand_compare remaining_prim with
|
expand_compare remaining_prim >|? function
|
||||||
| None -> None
|
| None -> None
|
||||||
| Some seq ->
|
| Some seq ->
|
||||||
Some (Seq (loc, [ seq ;
|
Some (Seq (loc, [ seq ;
|
||||||
Prim (loc, "IF", fail_false loc, None) ], None))
|
Prim (loc, "IF", fail_false loc, None) ], None))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
| _ -> None
|
| _ -> ok None
|
||||||
|
|
||||||
|
|
||||||
let expand_if_some = function
|
let expand_if_some = function
|
||||||
| Prim (loc, "IF_SOME", [ right ; left ], None) ->
|
| Prim (loc, "IF_SOME", [ right ; left ], None) ->
|
||||||
Some (Seq (loc, [ Prim (loc, "IF_NONE", [ left ; right ], None) ], None))
|
ok @@ Some (Seq (loc, [ Prim (loc, "IF_NONE", [ left ; right ], None) ], None))
|
||||||
| _ -> 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) ->
|
||||||
Some (Seq (loc, [ Prim (loc, "IF_LEFT", [ left ; right ], None) ], None))
|
ok @@ Some (Seq (loc, [ Prim (loc, "IF_LEFT", [ left ; right ], None) ], None))
|
||||||
| _ -> None
|
| _ -> ok @@ None
|
||||||
|
|
||||||
let expand original =
|
let expand original =
|
||||||
let try_expansions expanders =
|
let rec try_expansions = function
|
||||||
match
|
| [] -> ok @@ original
|
||||||
List.fold_left
|
| expander :: expanders ->
|
||||||
(fun acc f ->
|
expander original >>? function
|
||||||
match acc with
|
| None -> try_expansions expanders
|
||||||
| None -> f original
|
| Some rewritten -> ok rewritten in
|
||||||
| Some rewritten -> Some rewritten)
|
|
||||||
None expanders with
|
|
||||||
| None -> original
|
|
||||||
| Some rewritten -> rewritten in
|
|
||||||
try_expansions
|
try_expansions
|
||||||
[ expand_caddadr ;
|
[ expand_caddadr ;
|
||||||
expand_set_caddadr ;
|
expand_set_caddadr ;
|
||||||
@ -744,7 +754,7 @@ let unexpand_if_right = function
|
|||||||
| _ -> None
|
| _ -> None
|
||||||
|
|
||||||
let unexpand original =
|
let unexpand original =
|
||||||
let try_expansions unexpanders =
|
let try_unexpansions unexpanders =
|
||||||
match
|
match
|
||||||
List.fold_left
|
List.fold_left
|
||||||
(fun acc f ->
|
(fun acc f ->
|
||||||
@ -754,7 +764,7 @@ let unexpand original =
|
|||||||
None unexpanders with
|
None unexpanders with
|
||||||
| None -> original
|
| None -> original
|
||||||
| Some rewritten -> rewritten in
|
| Some rewritten -> rewritten in
|
||||||
try_expansions
|
try_unexpansions
|
||||||
[ unexpand_asserts ;
|
[ unexpand_asserts ;
|
||||||
unexpand_caddadr ;
|
unexpand_caddadr ;
|
||||||
unexpand_set_caddadr ;
|
unexpand_set_caddadr ;
|
||||||
@ -766,3 +776,33 @@ let unexpand original =
|
|||||||
unexpand_compare ;
|
unexpand_compare ;
|
||||||
unexpand_if_some ;
|
unexpand_if_some ;
|
||||||
unexpand_if_right ]
|
unexpand_if_right ]
|
||||||
|
|
||||||
|
let () =
|
||||||
|
let open Data_encoding in
|
||||||
|
register_error_kind
|
||||||
|
`Permanent
|
||||||
|
~id:"unexpectedMacroAnnotation"
|
||||||
|
~title:"Unexpected annotation"
|
||||||
|
~description:"A macro had an annotation, but no annotation was permitted on this macro."
|
||||||
|
~pp:(fun ppf ->
|
||||||
|
Format.fprintf ppf
|
||||||
|
"@[<hov 0>@[<hov 2>Unexpected annotation on instruction %s.@]@]")
|
||||||
|
(obj1
|
||||||
|
(req "instrName" string))
|
||||||
|
(function
|
||||||
|
| Unexpected_macro_annotation str -> Some str
|
||||||
|
| _ -> None)
|
||||||
|
(fun s -> Unexpected_macro_annotation s) ;
|
||||||
|
register_error_kind
|
||||||
|
`Permanent
|
||||||
|
~id:"dipExpectsSequence"
|
||||||
|
~title:"Dip instruction expects a sequence"
|
||||||
|
~description:"A dip instruction expects a sequence, but a sequence was not provided"
|
||||||
|
~pp:(fun ppf () ->
|
||||||
|
Format.fprintf ppf
|
||||||
|
"@[<hov 0>@[<hov 2>DIP instructionf expects a sequence, but did not receive one.@]@]")
|
||||||
|
empty
|
||||||
|
(function
|
||||||
|
| Dip_expects_sequence -> Some ()
|
||||||
|
| _ -> None)
|
||||||
|
(fun () -> Dip_expects_sequence)
|
||||||
|
@ -11,19 +11,22 @@ open Tezos_micheline
|
|||||||
|
|
||||||
type 'l node = ('l, string) Micheline.node
|
type 'l node = ('l, string) Micheline.node
|
||||||
|
|
||||||
val expand : 'l node -> 'l node
|
type error += Unexpected_macro_annotation of string
|
||||||
|
type error += Dip_expects_sequence
|
||||||
|
|
||||||
val expand_caddadr : 'l node -> 'l node option
|
val expand : 'l node -> 'l node tzresult
|
||||||
val expand_set_caddadr : 'l node -> 'l node option
|
|
||||||
val expand_map_caddadr : 'l node -> 'l node option
|
val expand_caddadr : 'l node -> 'l node option tzresult
|
||||||
val expand_dxiiivp : 'l node -> 'l node option
|
val expand_set_caddadr : 'l node -> 'l node option tzresult
|
||||||
val expand_paaiair : 'l node -> 'l node option
|
val expand_map_caddadr : 'l node -> 'l node option tzresult
|
||||||
val expand_duuuuup : 'l node -> 'l node option
|
val expand_dxiiivp : 'l node -> 'l node option tzresult
|
||||||
val expand_compare : 'l node -> 'l node option
|
val expand_paaiair : 'l node -> 'l node option tzresult
|
||||||
val expand_asserts : 'l node -> 'l node option
|
val expand_duuuuup : 'l node -> 'l node option tzresult
|
||||||
val expand_unpaaiair : 'l node -> 'l node option
|
val expand_compare : 'l node -> 'l node option tzresult
|
||||||
val expand_if_some : 'l node -> 'l node option
|
val expand_asserts : 'l node -> 'l node option tzresult
|
||||||
val expand_if_right : 'l node -> 'l node option
|
val expand_unpaaiair : 'l node -> 'l node option tzresult
|
||||||
|
val expand_if_some : 'l node -> 'l node option tzresult
|
||||||
|
val expand_if_right : 'l node -> 'l node option tzresult
|
||||||
|
|
||||||
val unexpand : 'l node -> 'l node
|
val unexpand : 'l node -> 'l node
|
||||||
|
|
||||||
|
@ -18,18 +18,34 @@ type parsed =
|
|||||||
expansion_table : (int * (Micheline_parser.location * int list)) list ;
|
expansion_table : (int * (Micheline_parser.location * int list)) list ;
|
||||||
unexpansion_table : (int * int) list }
|
unexpansion_table : (int * int) list }
|
||||||
|
|
||||||
|
(* Unexpanded toplevel expression should be a sequence *)
|
||||||
let expand_all source ast errors =
|
let expand_all source ast errors =
|
||||||
let unexpanded, loc_table =
|
let unexpanded, loc_table =
|
||||||
extract_locations ast in
|
extract_locations ast in
|
||||||
|
let rec error_map (expanded, errors) f = function
|
||||||
|
| [] -> (List.rev expanded, List.rev errors)
|
||||||
|
| hd :: tl ->
|
||||||
|
let (new_expanded, new_errors) = f hd in
|
||||||
|
error_map
|
||||||
|
(new_expanded :: expanded, List.rev_append new_errors errors)
|
||||||
|
f tl in
|
||||||
|
let error_map = error_map ([], []) in
|
||||||
let rec expand expr =
|
let rec expand expr =
|
||||||
match Michelson_macros.expand expr with
|
match Michelson_macros.expand expr with
|
||||||
| Seq (loc, items, annot) ->
|
| Ok expanded ->
|
||||||
Seq (loc, List.map expand items, annot)
|
begin
|
||||||
| Prim (loc, name, args, annot) ->
|
match expanded with
|
||||||
Prim (loc, name, List.map expand args, annot)
|
| Seq (loc, items, annot) ->
|
||||||
| Int _ | String _ as atom -> atom in
|
let items, errors = error_map expand items in
|
||||||
|
(Seq (loc, items, annot), errors)
|
||||||
|
| Prim (loc, name, args, annot) ->
|
||||||
|
let args, errors = error_map expand args in
|
||||||
|
(Prim (loc, name, args, annot), errors)
|
||||||
|
| Int _ | String _ as atom -> (atom, []) end
|
||||||
|
| Error errors -> (expr, errors) in
|
||||||
|
let expanded, expansion_errors = expand (root unexpanded) in
|
||||||
let expanded, unexpansion_table =
|
let expanded, unexpansion_table =
|
||||||
extract_locations (expand (root unexpanded)) in
|
extract_locations expanded in
|
||||||
let expansion_table =
|
let expansion_table =
|
||||||
let sorted =
|
let sorted =
|
||||||
List.sort (fun (_, a) (_, b) -> compare a b) unexpansion_table in
|
List.sort (fun (_, a) (_, b) -> compare a b) unexpansion_table in
|
||||||
@ -54,12 +70,12 @@ let expand_all source ast errors =
|
|||||||
| Ok expanded ->
|
| Ok expanded ->
|
||||||
{ source ; unexpanded ; expanded ;
|
{ source ; unexpanded ; expanded ;
|
||||||
expansion_table ; unexpansion_table },
|
expansion_table ; unexpansion_table },
|
||||||
errors
|
errors @ expansion_errors
|
||||||
| Error errs ->
|
| Error errs ->
|
||||||
{ source ; unexpanded ;
|
{ source ; unexpanded ;
|
||||||
expanded = Micheline.strip_locations (Seq ((), [], None)) ;
|
expanded = Micheline.strip_locations (Seq ((), [], None)) ;
|
||||||
expansion_table ; unexpansion_table },
|
expansion_table ; unexpansion_table },
|
||||||
errs @ errors
|
errs @ errors @ expansion_errors
|
||||||
|
|
||||||
let parse_toplevel ?check source =
|
let parse_toplevel ?check source =
|
||||||
let tokens, lexing_errors = Micheline_parser.tokenize source in
|
let tokens, lexing_errors = Micheline_parser.tokenize source in
|
||||||
|
@ -609,7 +609,7 @@ let () =
|
|||||||
~title: "Unknown primitive name (typechecking error)"
|
~title: "Unknown primitive name (typechecking error)"
|
||||||
~description:
|
~description:
|
||||||
"In a script or data expression, a primitive was unknown."
|
"In a script or data expression, a primitive was unknown."
|
||||||
~pp:(fun ppf n -> Format.fprintf ppf "Unknown primitive %s." n)
|
~pp:(fun ppf n -> Format.fprintf ppf "Unknown primitive %s.@," n)
|
||||||
Data_encoding.(obj1 (req "wrongPrimitiveName" string))
|
Data_encoding.(obj1 (req "wrongPrimitiveName" string))
|
||||||
(function
|
(function
|
||||||
| Unknown_primitive_name got -> Some got
|
| Unknown_primitive_name got -> Some got
|
||||||
|
4
test/contracts/cadr_annotation.tz
Normal file
4
test/contracts/cadr_annotation.tz
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
parameter (pair (pair unit (string @no_name)) bool);
|
||||||
|
storage unit;
|
||||||
|
return unit;
|
||||||
|
code { CAR @name; CADR @second_name; DROP; UNIT; UNIT; PAIR }
|
6
test/contracts/macro_annotations.tz
Normal file
6
test/contracts/macro_annotations.tz
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
return unit;
|
||||||
|
parameter unit;
|
||||||
|
storage unit;
|
||||||
|
code { PUSH unit Unit ;
|
||||||
|
DUUP @truc ;
|
||||||
|
DROP ; DROP }
|
4
test/contracts/map_car.tz
Normal file
4
test/contracts/map_car.tz
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
parameter bool;
|
||||||
|
storage (pair bool nat);
|
||||||
|
return unit;
|
||||||
|
code { DUP; CAR; DIP{CDR}; SWAP; MAP_CAR { AND } ; UNIT; PAIR };
|
4
test/contracts/pair_macro.tz
Normal file
4
test/contracts/pair_macro.tz
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
parameter unit;
|
||||||
|
return unit;
|
||||||
|
storage unit;
|
||||||
|
code { UNIT; UNIT; UNIT; UNIT; UNIT; PAIAAIAIAIR @name; DROP}
|
@ -2,5 +2,5 @@ parameter tez;
|
|||||||
storage (pair (pair nat (pair nat (pair (pair (pair nat tez) nat) nat))) nat);
|
storage (pair (pair nat (pair nat (pair (pair (pair nat tez) nat) nat))) nat);
|
||||||
return unit;
|
return unit;
|
||||||
code { DUP ; CAR ; SWAP ; CDR ;
|
code { DUP ; CAR ; SWAP ; CDR ;
|
||||||
SET_CADDAADR ;
|
SET_CADDAADR @annot ;
|
||||||
UNIT ; PAIR };
|
UNIT ; PAIR };
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
parameter string;
|
parameter string;
|
||||||
storage (pair string nat);
|
storage (pair string nat);
|
||||||
return (pair string nat);
|
return (pair string nat);
|
||||||
code {DUP; CDR; DIP{CAR}; SET_CAR; DUP; PAIR};
|
code { DUP; CDR; DIP{CAR}; SET_CAR @hello; DUP; PAIR };
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
parameter nat;
|
parameter nat;
|
||||||
storage (pair string nat);
|
storage (pair string nat);
|
||||||
return (pair string nat);
|
return (pair string nat);
|
||||||
code {DUP; CDR; DIP{CAR}; SET_CDR; DUP; PAIR};
|
code { DUP; CDR; DIP{CAR}; SET_CDR @annot; DUP; PAIR };
|
||||||
|
4
test/contracts/unpair_macro.tz
Normal file
4
test/contracts/unpair_macro.tz
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
parameter unit;
|
||||||
|
storage unit;
|
||||||
|
return unit;
|
||||||
|
code { UNIT; UNIT; UNIT; UNIT; PAIAAIR; UNPAIAAIR; DROP; DROP; DROP; DROP }
|
Loading…
Reference in New Issue
Block a user