Michelson: Remove binding annotations

Use RENAME in code blocks instead.
This commit is contained in:
Alain Mebsout 2018-06-08 12:54:37 +02:00 committed by Benjamin Canou
parent b61df9d816
commit 1748f370fc
8 changed files with 105 additions and 317 deletions

View File

@ -726,7 +726,7 @@ Bitwise logical operators are also available on unsigned integers.
- ``NOT`` The return type of ``NOT`` is an ``int`` and not a ``nat``.
This is because the sign is also negated. The resulting integer is
computed using twos complement. For instance, the boolean negation
computed using two's complement. For instance, the boolean negation
of ``0`` is ``-1``. To get a natural back, a possibility is to use
``AND`` with an unsigned mask afterwards.
@ -801,7 +801,7 @@ constants as is, concatenate them and use them as keys.
Operations on pairs
~~~~~~~~~~~~~~~~~~~
- ``PAIR``: Build a pair from the stacks top two elements.
- ``PAIR``: Build a pair from the stack's top two elements.
::
@ -1282,7 +1282,7 @@ types by mistake. They are also mandatory checked for under/overflows.
::
:: tez : tez : S -> int : S
:: tez : tez : 'S -> int : 'S
> COMPARE / x : y : S => -1 : S
iff x < y
@ -1473,12 +1473,12 @@ VIII - Macros
-------------
In addition to the operations above, several extensions have been added
to the languages concrete syntax. If you are interacting with the node
to the language's concrete syntax. If you are interacting with the node
via RPC, bypassing the client, which expands away these macros, you will
need to desugar them yourself.
These macros are designed to be unambiguous and reversible, meaning that
errors are reported in terms of desugared syntax. Below youll see
errors are reported in terms of desugared syntax. Below you'll see
these macros defined in terms of other syntactic forms. That is how
these macros are seen by the node.
@ -1840,19 +1840,20 @@ line can also be written, using C-like delimiters (``/* ... */``).
X - Annotations
---------------
The annotation mechanism of Michelson provides ways to better track
data on the stack and to give additional type constraints.
The annotation mechanism of Michelson provides ways to better track data
on the stack and to give additional type constraints. Annotaions are
only here to add constraints, *i.e.* they cannot turn an otherwise
rejected program into an accepted one.
Stack visualization tools like the Michelsons Emacs mode print
Stack visualization tools like the Michelson's Emacs mode print
annotations associated with each type in the program, as propagated by
the typechecker as well as variable annotations on the types of elements
in the stack. This is useful as a debugging aid.
We distinguish four kinds of annotations:
We distinguish three kinds of annotations:
- type annotations, written ``:type_annot``,
- variable annotations, written ``@var_annot``,
- field or constructors annotations, written ``%field_annot``,
- and binding annotations, written ``$bind_annot``.
- and field or constructors annotations, written ``%field_annot``.
Type Annotations
~~~~~~~~~~~~~~~~
@ -2142,73 +2143,18 @@ the accessed field in the destructed pair must match the one given here.
:: (pair 'a ('b %snd)) : S -> 'b : 'S
Binding Annotations
~~~~~~~~~~~~~~~~~~~
Michelson supports an extra kind of annotations which act as variable
annotations for values bound by instructions inside code blocks.
::
IF_NONE $some_value bt bf
:: option 'a : 'S -> 'b : 'S
iff bt :: [ 'S -> 'b : 'S]
bf :: [ @some_value 'a : 'S -> 'b : 'S]
IF_LEFT $left_value $right_value bt bf
:: or 'a 'b : 'S -> 'c : 'S
iff bt :: [ @left_value 'a : 'S -> 'c : 'S]
bf :: [ @right_value 'b : 'S -> 'c : 'S]
IF_CONS $head $tail bt bf
:: list 'a : 'S -> 'b : 'S
iff bt :: [ @head 'a : @tail list 'a : 'S -> 'b : 'S]
bf :: [ 'S -> 'b : 'S]
MAP $x body
:: (list 'elt) : 'A -> (list 'b) : 'A
iff body :: [ @x 'elt : 'A -> 'b : 'A ]
MAP $x body
:: (set 'elt) : 'A -> (set 'b) : 'A
iff body :: [ @x 'elt : 'A -> 'b : 'A ]
MAP $k $v body
:: (map 'key 'val) : 'A -> (map 'key 'b) : 'A
iff body :: [ (pair ('key %k) ('val %v)) : 'A -> 'b : 'A ]
ITER $x body
:: (set 'elt) : 'A -> 'A
iff body :: [ @x 'elt : 'A -> 'A ]
ITER $x body
:: (list 'elt) : 'A -> 'A
iff body :: [ @x 'elt : 'A -> 'A ]
ITER $k $v body
:: (map 'elt 'val) : 'A -> 'A
iff body :: [ (pair ('elt %k) ('val %v)) : 'A -> 'A ]
LAMBDA $arg 'a 'b code
:: 'A -> (lambda 'a 'b) : 'A
iff code :: [ @arg 'a : [] -> 'b : [] ]
LOOP_LEFT $acc body
:: (or 'a 'b) : 'A -> 'A
iff body :: [ @acc 'a : 'A -> (or 'a 'b) : 'A ]
Syntax
~~~~~~
Primitive applications can receive one or many annotations.
An annotation is a sequence of characters that matches the regular
expression ``[\@\:\%\$][0-9a-zA-Z\.]*``. They come after the primitive
expression ``[\@\:\%\$][_0-9a-zA-Z\.]*``. They come after the primitive
name and before its potential arguments for primitive applications.
::
(prim @annot arg arg ...)
(prim @v :t %x arg1 arg2 ...)
Ordering between different kinds of annotations is not significant, but
@ -2343,10 +2289,16 @@ A similar mechanism is used for context dependent instructions:
NOW :: 'S -> @now timestamp : 'S
If now binding annotation is provided for instruction with code blocks
(that accept one), then the bound items on the stack will be given a
Inside nested code blocks, bound items on the stack will be given a
default variable name annotation depending on the instruction and stack
type.
type (which can be changed). For instance the annotated typing rule for
``ITER`` on lists is:
::
ITER body
:: @l (list 'e) : 'A -> 'A
iff body :: [ @l.elt e' : 'A -> 'A ]
XI - JSON syntax
---------------
@ -2387,8 +2339,8 @@ storage. The type of the global data of the storage is fixed for each
contract at origination time. This is ensured statically by checking on
origination that the code preserves the type of the global data. For
this, the code of the contract is checked to be of type
``lambda (pair arg global) -> (pair (list operation) global)`` where
``global`` is the type of the original global store given on origination.
``lambda (pair 'arg 'global) -> (pair (list operation) 'global)`` where
``'global`` is the type of the original global store given on origination.
The contract also takes a parameter and returns a list of internal operations,
hence the complete calling convention above. The internal operations are
queued for execution when the contract returns.
@ -2413,7 +2365,7 @@ Reservoir contract
We want to create a contract that stores tez until a timestamp ``T`` or
a maximum amount ``N`` is reached. Whenever ``N`` is reached before
``T``, all tokens are reversed to an account ``B`` (and the contract is
automatically deleted). Any call to the contracts code performed after
automatically deleted). Any call to the contract's code performed after
``T`` will otherwise transfer the tokens to another account ``A``.
We want to build this contract in a reusable manner, so we do not
@ -2621,7 +2573,7 @@ After the first day, nothing cam happen until ``T``.
During the 24 hours after ``T``, the buyer must pay ``(Q * K)`` to the
contract, minus the amount already sent.
After this day, if the buyer didnt pay enough then any transaction will
After this day, if the buyer didn't pay enough then any transaction will
send all the tokens to the seller.
Otherwise, the seller must deliver at least ``Q`` tons of dried peas to
@ -2961,7 +2913,7 @@ The language is implemented in OCaml as follows:
- The lower internal representation is written as a GADT whose type
parameters encode exactly the typing rules given in this
specification. In other words, if a program written in this
representation is accepted by OCamls typechecker, it is guaranteed
representation is accepted by OCaml's typechecker, it is guaranteed
type-safe. This of course also valid for programs not handwritten but
generated by OCaml code, so we are sure that any manipulated code is
type-safe.
@ -2973,7 +2925,7 @@ The language is implemented in OCaml as follows:
- The interpreter is basically the direct transcription of the
rewriting rules presented above. It takes an instruction, a stack and
transforms it. OCamls typechecker ensures that the transformation
transforms it. OCaml's typechecker ensures that the transformation
respects the pre and post stack types declared by the GADT case for
each instruction.

View File

@ -14,12 +14,12 @@ storage (map :stored_balance key_hash mutez);
code { DUP; CAR;
# Deposit into account
IF_LEFT { DUP; DIIP{ CDR %stored_balance; DUP };
DIP{ SWAP }; GET;
DIP{ SWAP }; GET @opt_prev_balance;
# Create the account
IF_SOME $previous_balance
# Add to an existing account
{ AMOUNT; ADD; SOME; SWAP; UPDATE; NIL operation; PAIR }
{ DIP{ AMOUNT; SOME }; UPDATE; NIL operation; PAIR }}
IF_SOME # Add to an existing account
{ RENAME @previous_balance;
AMOUNT; ADD; SOME; SWAP; UPDATE; NIL operation; PAIR }
{ DIP{ AMOUNT; SOME }; UPDATE; NIL operation; PAIR }}
# Withdrawl
{ DUP; DUP; DUP; DUP;
# Check signature on data
@ -31,10 +31,10 @@ code { DUP; CAR;
DIIP{ CDR %stored_balance; DUP };
CAR %from; HASH_KEY @from_hash; DIP{ SWAP }; GET;
# Account does not exist
IF_NONE $previous_balance
{ FAIL }
IF_NONE { FAIL }
# Account exists
{ DUP; DIIP{ DUP; CDAR %withdraw_amount; DUP };
{ RENAME @previous_balance;
DUP; DIIP{ DUP; CDAR %withdraw_amount; DUP };
# Ensure funds are available
DIP{ CMPLT @not_enough }; SWAP;
IF { FAIL }

View File

@ -1,7 +1,7 @@
parameter (map (int :k) (int :e));
storage (pair (int :k) (int :e));
code { CAR; PUSH @acc_e (int :e) 0; PUSH @acc_k (int :k) 0; PAIR; SWAP;
ITER $my_key $my_elt
{ DIP {DUP; CAR; DIP{CDR}}; DUP; # Last instr
DIP{CAR; ADD}; SWAP; DIP{CDR; ADD}; PAIR };
ITER
{ DIP {DUP; CAR; DIP{CDR}}; DUP; # Last instr
DIP{CAR; ADD}; SWAP; DIP{CDR; ADD}; PAIR };
NIL operation; PAIR}

View File

@ -572,15 +572,6 @@ let expand_if_right = function
error (Invalid_arity ("IF_RIGHT", List.length args, 2))
| _ -> ok @@ None
let expand_rename = function
| Prim (loc, "RENAME", [], annot) ->
ok @@ Some (Seq (loc, [
Prim (loc, "DUP", [], annot) ;
Prim (loc, "SWAP", [], []) ;
Prim (loc, "DROP", [], []) ;
]))
| _ -> ok @@ None
let expand original =
let rec try_expansions = function
| [] -> ok @@ original
@ -602,7 +593,6 @@ let expand original =
expand_asserts ;
expand_if_some ;
expand_if_right ;
expand_rename ;
]
let expand_rec expr =
@ -1008,15 +998,6 @@ let unexpand_if_right = function
Some (Prim (loc, "IF_RIGHT", [ right ; left ], annot))
| _ -> None
let unexpand_rename = function
| Seq (loc, [
Prim (_, "DUP", [], annot) ;
Prim (_, "SWAP", [], []) ;
Prim (_, "DROP", [], []) ;
]) ->
Some (Prim (loc, "RENAME", [], annot))
| _ -> None
let unexpand original =
let try_unexpansions unexpanders =
match
@ -1039,8 +1020,7 @@ let unexpand original =
unexpand_duuuuup ;
unexpand_compare ;
unexpand_if_some ;
unexpand_if_right ;
unexpand_rename ]
unexpand_if_right ]
let rec unexpand_rec expr =
match unexpand expr with

View File

@ -18,6 +18,7 @@ let default_balance_annot = Some (`Var_annot "balance")
let default_steps_annot = Some (`Var_annot "steps")
let default_source_annot = Some (`Var_annot "source")
let default_self_annot = Some (`Var_annot "self")
let default_arg_annot = Some (`Var_annot "arg")
let default_param_annot = Some (`Field_annot "parameter")
let default_storage_annot = Some (`Field_annot "storage")
@ -27,13 +28,14 @@ let default_contract_annot = Some (`Field_annot "contract")
let default_addr_annot = Some (`Field_annot "address")
let default_manager_annot = Some (`Field_annot "manager")
let default_arg_annot = Some (`Binding_annot "arg")
let default_elt_annot = Some (`Binding_annot "elt")
let default_key_annot = Some (`Binding_annot "key")
let default_hd_annot = Some (`Binding_annot "hd")
let default_some_annot = Some (`Binding_annot "some")
let default_left_annot = Some (`Binding_annot "left")
let default_right_annot = Some (`Binding_annot "right")
let default_elt_annot = Some (`Field_annot "elt")
let default_key_annot = Some (`Field_annot "key")
let default_hd_annot = Some (`Field_annot "hd")
let default_tl_annot = Some (`Field_annot "tl")
let default_some_annot = Some (`Field_annot "some")
let default_left_annot = Some (`Field_annot "left")
let default_right_annot = Some (`Field_annot "right")
let default_binding_annot = Some (`Field_annot "bnd")
let unparse_type_annot : type_annot option -> string list = function
| None -> []
@ -47,35 +49,11 @@ let unparse_field_annot : field_annot option -> string list = function
| None -> []
| Some `Field_annot a -> [ "%" ^ a ]
let unparse_binding_annot : binding_annot option -> string list = function
| None -> []
| Some `Binding_annot a -> [ "$" ^ a ]
let field_to_var_annot : field_annot option -> var_annot option =
function
| None -> None
| Some (`Field_annot s) -> Some (`Var_annot s)
let field_to_binding_annot : field_annot option -> binding_annot option =
function
| None -> None
| Some (`Field_annot s) -> Some (`Binding_annot s)
let binding_to_var_annot : binding_annot option -> var_annot option =
function
| None -> None
| Some (`Binding_annot s) -> Some (`Var_annot s)
let binding_to_field_annot : binding_annot option -> field_annot option =
function
| None -> None
| Some (`Binding_annot s) -> Some (`Field_annot s)
let var_to_binding_annot : var_annot option -> binding_annot option =
function
| None -> None
| Some (`Var_annot s) -> Some (`Binding_annot s)
let type_to_field_annot : type_annot option -> field_annot option =
function
| None -> None
@ -102,18 +80,6 @@ let gen_access_annot
| Some `Var_annot v, Some `Field_annot f, _ ->
Some (`Var_annot (String.concat "." [v; f]))
let gen_binding_access_annot
: var_annot option -> ?default:binding_annot option -> binding_annot option -> binding_annot option
= fun value_annot ?(default=None) binding_annot ->
match value_annot, binding_annot, default with
| None, None, _ | Some _, None, None | None, Some `Binding_annot "", _ -> None
| None, Some `Binding_annot b, _ ->
Some (`Binding_annot b)
| Some `Var_annot v, (None | Some `Binding_annot ""), Some `Binding_annot b ->
Some (`Binding_annot (String.concat "." [v; b]))
| Some `Var_annot v, Some `Binding_annot b, _ ->
Some (`Binding_annot (String.concat "." [v; b]))
let merge_type_annot
: type_annot option -> type_annot option -> type_annot option tzresult
= fun annot1 annot2 ->
@ -164,7 +130,6 @@ let parse_annots loc l =
| '@' -> ok (`Var_annot (String.sub s 1 @@ String.length s - 1) :: acc)
| ':' -> ok (`Type_annot (String.sub s 1 @@ String.length s - 1) :: acc)
| '%' -> ok (`Field_annot (String.sub s 1 @@ String.length s - 1) :: acc)
| '$' -> ok (`Binding_annot (String.sub s 1 @@ String.length s - 1) :: acc)
| _ -> error (Unexpected_annotation loc)
| exception Invalid_argument _ -> error (Unexpected_annotation loc)
end
@ -249,15 +214,14 @@ let parse_field_annot loc annot =
Lwt.return (parse_field_annot loc annot)
let classify_annot
: annot list -> var_annot list * type_annot list * field_annot list * binding_annot list
: annot list -> var_annot list * type_annot list * field_annot list
= fun l ->
let rv, rt, rf, rb = List.fold_left (fun (rv, rt, rf, rb) -> function
| `Var_annot _ as a -> a :: rv, rt, rf, rb
| `Type_annot _ as a -> rv, a :: rt, rf, rb
| `Field_annot _ as a -> rv, rt, a :: rf, rb
| `Binding_annot _ as a -> rv, rt, rf, a :: rb
) ([], [], [], []) l in
List.rev rv, List.rev rt, List.rev rf, List.rev rb
let rv, rt, rf = List.fold_left (fun (rv, rt, rf) -> function
| `Var_annot _ as a -> a :: rv, rt, rf
| `Type_annot _ as a -> rv, a :: rt, rf
| `Field_annot _ as a -> rv, rt, a :: rf
) ([], [], []) l in
List.rev rv, List.rev rt, List.rev rf
let get_one_annot loc = function
| [] -> Lwt.return (ok None)
@ -275,52 +239,27 @@ let parse_constr_annot
(var_annot option * type_annot option * field_annot option * field_annot option) tzresult Lwt.t
= fun loc annot ->
Lwt.return (parse_annots loc annot) >>=? fun annot ->
let vars, types, fields, bindings = classify_annot annot in
fail_unexpected_annot loc bindings >>=? fun () ->
let vars, types, fields = classify_annot annot in
get_one_annot loc vars >>=? fun v ->
get_one_annot loc types >>=? fun t ->
get_two_annot loc fields >>|? fun (f1, f2) ->
(v, t, f1, f2)
let parse_map_annot
: int -> string list ->
(var_annot option * type_annot option * binding_annot option * binding_annot option) tzresult Lwt.t
= fun loc annot ->
Lwt.return (parse_annots loc annot) >>=? fun annot ->
let vars, types, fields, bindings = classify_annot annot in
fail_unexpected_annot loc fields >>=? fun () ->
get_one_annot loc vars >>=? fun v ->
get_one_annot loc types >>=? fun t ->
get_two_annot loc bindings >>|? fun (b1, b2) ->
(v, t, b1, b2)
let parse_two_var_annot
: int -> string list -> (var_annot option * var_annot option) tzresult Lwt.t
= fun loc annot ->
Lwt.return (parse_annots loc annot) >>=? fun annot ->
let vars, types, fields, bindings = classify_annot annot in
fail_unexpected_annot loc bindings >>=? fun () ->
let vars, types, fields = classify_annot annot in
fail_unexpected_annot loc types >>=? fun () ->
fail_unexpected_annot loc fields >>=? fun () ->
get_two_annot loc vars
let parse_two_binding_annot
: int -> string list -> (binding_annot option * binding_annot option) tzresult Lwt.t
= fun loc annot ->
Lwt.return (parse_annots loc annot) >>=? fun annot ->
let vars, types, fields, bindings = classify_annot annot in
fail_unexpected_annot loc vars >>=? fun () ->
fail_unexpected_annot loc types >>=? fun () ->
fail_unexpected_annot loc fields >>=? fun () ->
get_two_annot loc bindings
let parse_var_field_annot
: int -> string list -> (var_annot option * field_annot option) tzresult Lwt.t
= fun loc annot ->
Lwt.return (parse_annots loc annot) >>=? fun annot ->
let vars, types, fields, bindings = classify_annot annot in
let vars, types, fields = classify_annot annot in
fail_unexpected_annot loc types >>=? fun () ->
fail_unexpected_annot loc bindings >>=? fun () ->
get_one_annot loc vars >>=? fun v ->
get_one_annot loc fields >>|? fun f ->
(v, f)
@ -329,42 +268,8 @@ let parse_var_type_annot
: int -> string list -> (var_annot option * type_annot option) tzresult Lwt.t
= fun loc annot ->
Lwt.return (parse_annots loc annot) >>=? fun annot ->
let vars, types, fields, bindings = classify_annot annot in
let vars, types, fields = classify_annot annot in
fail_unexpected_annot loc fields >>=? fun () ->
fail_unexpected_annot loc bindings >>=? fun () ->
get_one_annot loc vars >>=? fun v ->
get_one_annot loc types >>|? fun t ->
(v, t)
let parse_binding_annot
: int -> string list -> binding_annot option tzresult Lwt.t
= fun loc annot ->
Lwt.return (parse_annots loc annot) >>=? fun annot ->
let vars, types, fields, bindings = classify_annot annot in
fail_unexpected_annot loc vars >>=? fun () ->
fail_unexpected_annot loc types >>=? fun () ->
fail_unexpected_annot loc fields >>=? fun () ->
get_one_annot loc bindings
let parse_var_binding_annot
: int -> string list -> (var_annot option * binding_annot option) tzresult Lwt.t
= fun loc annot ->
Lwt.return (parse_annots loc annot) >>=? fun annot ->
let vars, types, fields, bindings = classify_annot annot in
fail_unexpected_annot loc types >>=? fun () ->
fail_unexpected_annot loc fields >>=? fun () ->
get_one_annot loc vars >>=? fun v ->
get_one_annot loc bindings >>|? fun b ->
(v, b)
let parse_var_type_binding_annot
: int -> string list ->
(var_annot option * type_annot option * binding_annot option) tzresult Lwt.t
= fun loc annot ->
Lwt.return (parse_annots loc annot) >>=? fun annot ->
let vars, types, fields, bindings = classify_annot annot in
fail_unexpected_annot loc fields >>=? fun () ->
get_one_annot loc vars >>=? fun v ->
get_one_annot loc types >>=? fun t ->
get_one_annot loc bindings >>|? fun b ->
(v, t, b)

View File

@ -18,6 +18,7 @@ val default_balance_annot : var_annot option
val default_steps_annot : var_annot option
val default_source_annot : var_annot option
val default_self_annot : var_annot option
val default_arg_annot : var_annot option
val default_param_annot : field_annot option
val default_storage_annot : field_annot option
@ -27,28 +28,24 @@ val default_contract_annot : field_annot option
val default_addr_annot : field_annot option
val default_manager_annot : field_annot option
val default_arg_annot : binding_annot option
val default_elt_annot : binding_annot option
val default_key_annot : binding_annot option
val default_hd_annot : binding_annot option
val default_some_annot : binding_annot option
val default_left_annot : binding_annot option
val default_right_annot : binding_annot option
val default_elt_annot : field_annot option
val default_key_annot : field_annot option
val default_hd_annot : field_annot option
val default_tl_annot : field_annot option
val default_some_annot : field_annot option
val default_left_annot : field_annot option
val default_right_annot : field_annot option
val default_binding_annot : field_annot option
(** Unparse annotations to their string representation *)
val unparse_type_annot : type_annot option -> string list
val unparse_var_annot : var_annot option -> string list
val unparse_field_annot : field_annot option -> string list
val unparse_binding_annot : binding_annot option -> string list
(** Convertions functions between different annotation kinds *)
val field_to_var_annot : field_annot option -> var_annot option
val field_to_binding_annot : field_annot option -> binding_annot option
val binding_to_var_annot : binding_annot option -> var_annot option
val binding_to_field_annot : binding_annot option -> field_annot option
val var_to_binding_annot : var_annot option -> binding_annot option
val type_to_field_annot : type_annot option -> field_annot option
val var_to_field_annot : var_annot option -> field_annot option
@ -60,12 +57,6 @@ val gen_access_annot :
var_annot option ->
?default:field_annot option -> field_annot option -> var_annot option
(** Generate a binding annotation, of the form $var.some *)
val gen_binding_access_annot :
var_annot option ->
?default:binding_annot option ->
binding_annot option -> binding_annot option
(** Merge type annotations.
@returns an error {!Inconsistent_type_annotations} if they are both present
and different *)
@ -127,29 +118,11 @@ val parse_constr_annot :
int -> string list ->
(var_annot option * type_annot option * field_annot option * field_annot option) tzresult Lwt.t
val parse_map_annot :
int -> string list ->
(var_annot option * type_annot option * binding_annot option * binding_annot option) tzresult Lwt.t
val parse_two_var_annot :
int -> string list -> (var_annot option * var_annot option) tzresult Lwt.t
val parse_two_binding_annot :
int -> string list ->
(binding_annot option * binding_annot option) tzresult Lwt.t
val parse_var_field_annot :
int -> string list -> (var_annot option * field_annot option) tzresult Lwt.t
val parse_var_type_annot :
int -> string list -> (var_annot option * type_annot option) tzresult Lwt.t
val parse_binding_annot :
int -> string list -> binding_annot option tzresult Lwt.t
val parse_var_binding_annot :
int -> string list -> (var_annot option * binding_annot option) tzresult Lwt.t
val parse_var_type_binding_annot :
int -> string list ->
(var_annot option * type_annot option * binding_annot option) tzresult Lwt.t

View File

@ -1491,11 +1491,8 @@ and parse_instr
(Item_t (Option_t ((t, some_field), _none_field, _), rest, option_annot) as bef) ->
check_kind [ Seq_kind ] bt >>=? fun () ->
check_kind [ Seq_kind ] bf >>=? fun () ->
parse_binding_annot loc annot >>=? fun binding_annot ->
let binding_annot = default_annot binding_annot
~default:(gen_binding_access_annot option_annot (field_to_binding_annot some_field)
~default:default_some_annot) in
let annot = binding_to_var_annot binding_annot in
fail_unexpected_annot loc annot >>=? fun () ->
let annot = gen_access_annot option_annot some_field ~default:default_some_annot in
parse_instr ?type_logger tc_context ctxt bt rest >>=? fun (btr, ctxt) ->
parse_instr ?type_logger tc_context ctxt bf (Item_t (t, rest, annot)) >>=? fun (bfr, ctxt) ->
let branch ibt ibf =
@ -1537,17 +1534,9 @@ and parse_instr
(Item_t (Union_t ((tl, l_field), (tr, r_field), _), rest, union_annot) as bef) ->
check_kind [ Seq_kind ] bt >>=? fun () ->
check_kind [ Seq_kind ] bf >>=? fun () ->
parse_two_binding_annot loc annot >>=? fun (left_bind_annot, right_bind_annot) ->
let left_bind_annot = default_annot left_bind_annot
~default:(gen_binding_access_annot union_annot
(field_to_binding_annot l_field)
~default:default_left_annot) in
let left_annot = binding_to_var_annot left_bind_annot in
let right_bind_annot = default_annot right_bind_annot
~default:(gen_binding_access_annot union_annot
(field_to_binding_annot r_field)
~default:default_right_annot) in
let right_annot = binding_to_var_annot right_bind_annot in
fail_unexpected_annot loc annot >>=? fun () ->
let left_annot = gen_access_annot union_annot l_field ~default:default_left_annot in
let right_annot = gen_access_annot union_annot r_field ~default:default_right_annot in
parse_instr ?type_logger tc_context ctxt bt (Item_t (tl, rest, left_annot)) >>=? fun (btr, ctxt) ->
parse_instr ?type_logger tc_context ctxt bf (Item_t (tr, rest, right_annot)) >>=? fun (bfr, ctxt) ->
let branch ibt ibf =
@ -1566,15 +1555,15 @@ and parse_instr
parse_var_annot loc annot >>=? fun annot ->
typed ctxt loc Cons_list (Item_t (List_t (t, ty_name), rest, annot))
| Prim (loc, I_IF_CONS, [ bt ; bf ], annot),
(Item_t (List_t (t, _), rest, list_annot) as bef) ->
(Item_t (List_t (t, ty_name), rest, list_annot) as bef) ->
check_kind [ Seq_kind ] bt >>=? fun () ->
check_kind [ Seq_kind ] bf >>=? fun () ->
parse_binding_annot loc annot >>=? fun hd_bind_annot ->
let hd_bind_annot = default_annot hd_bind_annot
~default:(gen_binding_access_annot list_annot default_hd_annot) in
let hd_annot = binding_to_var_annot hd_bind_annot in
fail_unexpected_annot loc annot >>=? fun () ->
let hd_annot = gen_access_annot list_annot default_hd_annot in
let tl_annot = gen_access_annot list_annot default_tl_annot in
parse_instr ?type_logger tc_context ctxt bt
(Item_t (t, bef, hd_annot)) >>=? fun (btr, ctxt) ->
(Item_t (t, Item_t (List_t (t, ty_name), rest, tl_annot), hd_annot))
>>=? fun (btr, ctxt) ->
parse_instr ?type_logger tc_context ctxt bf
rest >>=? fun (bfr, ctxt) ->
let branch ibt ibf =
@ -1588,11 +1577,9 @@ and parse_instr
| Prim (loc, I_MAP, [ body ], annot),
(Item_t (List_t (elt, _), starting_rest, list_annot)) ->
check_kind [ Seq_kind ] body >>=? fun () ->
parse_var_type_binding_annot loc annot
>>=? fun (ret_annot, list_ty_name, elt_bind_annot) ->
let elt_bind_annot = default_annot elt_bind_annot
~default:(gen_binding_access_annot list_annot default_elt_annot) in
let elt_annot = binding_to_var_annot elt_bind_annot in
parse_var_type_annot loc annot
>>=? fun (ret_annot, list_ty_name) ->
let elt_annot = gen_access_annot list_annot default_elt_annot in
parse_instr ?type_logger tc_context ctxt
body (Item_t (elt, starting_rest, elt_annot)) >>=? begin fun (judgement, ctxt) ->
match judgement with
@ -1609,10 +1596,8 @@ and parse_instr
| Prim (loc, I_ITER, [ body ], annot),
Item_t (List_t (elt, _), rest, list_annot) ->
check_kind [ Seq_kind ] body >>=? fun () ->
parse_binding_annot loc annot >>=? fun elt_bind_annot ->
let elt_bind_annot = default_annot elt_bind_annot
~default:(gen_binding_access_annot list_annot default_elt_annot) in
let elt_annot = binding_to_var_annot elt_bind_annot in
fail_unexpected_annot loc annot >>=? fun () ->
let elt_annot = gen_access_annot list_annot default_elt_annot in
parse_instr ?type_logger tc_context ctxt
body (Item_t (elt, rest, elt_annot)) >>=? begin fun (judgement, ctxt) ->
match judgement with
@ -1634,10 +1619,8 @@ and parse_instr
| Prim (loc, I_ITER, [ body ], annot),
Item_t (Set_t (comp_elt, _), rest, set_annot) ->
check_kind [ Seq_kind ] body >>=? fun () ->
parse_binding_annot loc annot >>=? fun elt_bind_annot ->
let elt_bind_annot = default_annot elt_bind_annot
~default:(gen_binding_access_annot set_annot default_elt_annot) in
let elt_annot = binding_to_var_annot elt_bind_annot in
fail_unexpected_annot loc annot >>=? fun () ->
let elt_annot = gen_access_annot set_annot default_elt_annot in
let elt = ty_of_comparable_ty comp_elt in
parse_instr ?type_logger tc_context ctxt
body (Item_t (elt, rest, elt_annot)) >>=? begin fun (judgement, ctxt) ->
@ -1675,14 +1658,14 @@ and parse_instr
parse_var_type_annot loc annot >>=? fun (annot, ty_name) ->
typed ctxt loc (Empty_map (tk, tv)) (Item_t (Map_t (tk, tv, ty_name), stack, annot))
| Prim (loc, I_MAP, [ body ], annot),
Item_t (Map_t (ck, elt, _), starting_rest, _map_annot) ->
Item_t (Map_t (ck, elt, _), starting_rest, map_annot) ->
let k = ty_of_comparable_ty ck in
check_kind [ Seq_kind ] body >>=? fun () ->
parse_map_annot loc annot >>=? fun (ret_annot, ty_name, key_bind_annot, elt_bind_annot) ->
let key_field = default_annot key_bind_annot ~default:default_key_annot |> binding_to_field_annot in
let elt_field = default_annot elt_bind_annot ~default:default_elt_annot |> binding_to_field_annot in
parse_var_type_annot loc annot >>=? fun (ret_annot, ty_name) ->
let binding_annot = gen_access_annot map_annot default_binding_annot in
parse_instr ?type_logger tc_context ctxt
body (Item_t (Pair_t ((k, key_field), (elt, elt_field), None), starting_rest, None)) >>=? begin fun (judgement, ctxt) ->
body (Item_t (Pair_t ((k, default_key_annot), (elt, default_elt_annot), None),
starting_rest, binding_annot)) >>=? begin fun (judgement, ctxt) ->
match judgement with
| Typed ({ aft = Item_t (ret, rest, _) ; _ } as ibody) ->
let invalid_map_body = Invalid_map_body (loc, ibody.aft) in
@ -1695,14 +1678,14 @@ and parse_instr
| Failed _ -> fail (Invalid_map_block_fail loc)
end
| Prim (loc, I_ITER, [ body ], annot),
Item_t (Map_t (comp_elt, element_ty, _), rest, _) ->
Item_t (Map_t (comp_elt, element_ty, _), rest, map_annot) ->
check_kind [ Seq_kind ] body >>=? fun () ->
parse_two_binding_annot loc annot >>=? fun (key_bind_annot, elt_bind_annot) ->
let key_field = default_annot key_bind_annot ~default:default_key_annot |> binding_to_field_annot in
let elt_field = default_annot elt_bind_annot ~default:default_elt_annot |> binding_to_field_annot in
fail_unexpected_annot loc annot >>=? fun () ->
let binding_annot = gen_access_annot map_annot default_binding_annot in
let key = ty_of_comparable_ty comp_elt in
parse_instr ?type_logger tc_context ctxt body
(Item_t (Pair_t ((key, key_field), (element_ty, elt_field), None), rest, None))
(Item_t (Pair_t ((key, default_key_annot), (element_ty, default_elt_annot), None),
rest, binding_annot))
>>=? begin fun (judgement, ctxt) -> match judgement with
| Typed ({ aft ; _ } as ibody) ->
let invalid_iter_body = Invalid_iter_body (loc, rest, ibody.aft) in
@ -1828,10 +1811,8 @@ and parse_instr
| Prim (loc, I_LOOP_LEFT, [ body ], annot),
(Item_t (Union_t ((tl, l_field), (tr, _), _), rest, union_annot) as stack) ->
check_kind [ Seq_kind ] body >>=? fun () ->
parse_binding_annot loc annot >>=? fun l_bind_annot ->
let l_bind_annot = default_annot l_bind_annot
~default:(gen_binding_access_annot union_annot (field_to_binding_annot l_field)) in
let l_annot = binding_to_var_annot l_bind_annot in
parse_var_annot loc annot >>=? fun annot ->
let l_annot = gen_access_annot union_annot l_field ~default:default_left_annot in
parse_instr ?type_logger tc_context ctxt body
(Item_t (tl, rest, l_annot)) >>=? begin fun (judgement, ctxt) -> match judgement with
| Typed ibody ->
@ -1839,10 +1820,10 @@ and parse_instr
trace unmatched_branches
(Lwt.return (stack_ty_eq 1 ibody.aft stack) >>=? fun Eq ->
Lwt.return (merge_stacks loc ibody.aft stack) >>=? fun _stack ->
typed ctxt loc (Loop_left ibody) (Item_t (tr, rest, None)))
typed ctxt loc (Loop_left ibody) (Item_t (tr, rest, annot)))
| Failed { descr } ->
let ibody = descr stack in
typed ctxt loc (Loop_left ibody) (Item_t (tr, rest, None))
typed ctxt loc (Loop_left ibody) (Item_t (tr, rest, annot))
end
| Prim (loc, I_LAMBDA, [ arg ; ret ; code ], annot),
stack ->
@ -1851,11 +1832,9 @@ and parse_instr
(Lwt.return (parse_ty ~allow_big_map:false ~allow_operation:true ret))
>>=? fun (Ex_ty ret) ->
check_kind [ Seq_kind ] code >>=? fun () ->
parse_var_binding_annot loc annot >>=? fun (annot, arg_bind_annot) ->
let arg_bind_annot = default_annot arg_bind_annot ~default:default_arg_annot in
let arg_annot = binding_to_var_annot arg_bind_annot in
parse_var_annot loc annot >>=? fun annot ->
parse_returning Lambda ?type_logger ctxt
(arg, arg_annot) ret code >>=? fun (lambda, ctxt) ->
(arg, default_arg_annot) ret code >>=? fun (lambda, ctxt) ->
typed ctxt loc (Lambda lambda) (Item_t (Lambda_t (arg, ret, None), stack, annot))
| Prim (loc, I_EXEC, [], annot),
Item_t (arg, Item_t (Lambda_t (param, ret, _), rest, _), _) ->

View File

@ -15,9 +15,8 @@ open Script_int
type var_annot = [ `Var_annot of string ]
type type_annot = [ `Type_annot of string ]
type field_annot = [ `Field_annot of string ]
type binding_annot = [ `Binding_annot of string ]
type annot = [ var_annot | type_annot | field_annot | binding_annot ]
type annot = [ var_annot | type_annot | field_annot ]
type 'ty comparable_ty =
| Int_key : type_annot option -> (z num) comparable_ty