https://gitlab.com/nomadic-labs/mi-cho-coq
Tip revision: edb58ee5551a4d2f09144173c589f34442160192 authored by Arvid Jakobsson on 06 November 2019, 15:08:13 UTC
Update coq-mi-cho-coq.opam: remove duplicate synpopsis
Update coq-mi-cho-coq.opam: remove duplicate synpopsis
Tip revision: edb58ee
micheline2michelson.v
Require Import Ascii String List.
Require Import untyped_syntax micheline_syntax error location.
Require Import syntax_type.
Require Import Lia.
Require Coq.Program.Wf.
Open Scope string.
Definition micheline2michelson_sctype (bem : loc_micheline) : M simple_comparable_type :=
let 'Mk_loc_micheline ((b, e), m) := bem in
match m with
| PRIM (_, "string") nil => Return _ string
| PRIM (_, "nat") nil => Return _ nat
| PRIM (_, "int") nil => Return _ int
| PRIM (_, "bytes") nil => Return _ bytes
| PRIM (_, "bool") nil => Return _ bool
| PRIM (_, "mutez") nil => Return _ mutez
| PRIM (_, "key_hash") nil => Return _ key_hash
| PRIM (_, "timestamp") nil => Return _ timestamp
| PRIM (_, "address") nil => Return _ address
| _ => Failed _ (Expansion b e)
end.
Fixpoint micheline2michelson_ctype (bem : loc_micheline) : M comparable_type :=
let 'Mk_loc_micheline ((b, e), m) := bem in
match m with
| PRIM (_, "pair") (a :: b :: nil) =>
bind (fun a =>
bind (fun b => Return _ (Cpair a b))
(micheline2michelson_ctype b)
)
(micheline2michelson_sctype a)
| _ =>
bind (fun a => Return _ (Comparable_type_simple a))
(micheline2michelson_sctype bem)
end.
Notation "A ;; B" := (untyped_syntax.SEQ A B) (at level 100, right associativity).
Fixpoint micheline2michelson_type (bem : loc_micheline) : M type :=
try (bind (fun ty => Return _ (Comparable_type ty)) (micheline2michelson_sctype bem))
(match bem with
| Mk_loc_micheline (_, PRIM (_, "key") nil) => Return _ key
| Mk_loc_micheline (_, PRIM (_, "unit") nil) => Return _ unit
| Mk_loc_micheline (_, PRIM (_, "signature") nil) => Return _ signature
| Mk_loc_micheline (_, PRIM (_, "operation") nil) => Return _ operation
| Mk_loc_micheline (_, PRIM (_, "option") (a :: nil)) =>
bind (fun a => Return _ (option a))
(micheline2michelson_type a)
| Mk_loc_micheline (_, PRIM (_, "list") (a :: nil)) =>
bind (fun a => Return _ (list a))
(micheline2michelson_type a)
| Mk_loc_micheline (_, PRIM (_, "contract") (a :: nil)) =>
bind (fun a => Return _ (contract a))
(micheline2michelson_type a)
| Mk_loc_micheline (_, PRIM (_, "set") (a :: nil)) =>
bind (fun a => Return _ (set a))
(micheline2michelson_ctype a)
| Mk_loc_micheline (_, PRIM (_, "pair") (a :: b :: nil)) =>
bind (fun a =>
bind (fun b => Return _ (pair a b))
(micheline2michelson_type b))
(micheline2michelson_type a)
| Mk_loc_micheline (_, PRIM (_, "or") (a :: b :: nil)) =>
bind (fun a =>
bind (fun b => Return _ (or a b))
(micheline2michelson_type b))
(micheline2michelson_type a)
| Mk_loc_micheline (_, PRIM (_, "lambda") (a :: b :: nil)) =>
bind (fun a =>
bind (fun b => Return _ (lambda a b))
(micheline2michelson_type b))
(micheline2michelson_type a)
| Mk_loc_micheline (_, PRIM (_, "map") (a :: b :: nil)) =>
bind (fun a =>
bind (fun b => Return _ (map a b))
(micheline2michelson_type b))
(micheline2michelson_ctype a)
| Mk_loc_micheline (_, PRIM (_, "big_map") (a :: b :: nil)) =>
bind (fun a =>
bind (fun b => Return _ (big_map a b))
(micheline2michelson_type b))
(micheline2michelson_ctype a)
| Mk_loc_micheline ((b, e), _) => Failed _ (Expansion b e)
end).
Fixpoint micheline2michelson_data (bem : loc_micheline) : M concrete_data :=
match bem with
| Mk_loc_micheline (_, SEQ l) =>
bind (fun l => Return _ (Concrete_seq l))
((fix micheline2michelson_data_list (l : Datatypes.list loc_micheline) : M (Datatypes.list concrete_data) :=
match l with
| nil => Return _ nil
| m :: l =>
bind (fun d =>
bind (fun l => Return _ (d :: l))
(micheline2michelson_data_list l))
(micheline2michelson_data m)
end) l)
| Mk_loc_micheline (_, STR s) => Return _ (String_constant s)
| Mk_loc_micheline (_, NUMBER z) => Return _ (Int_constant z)
| Mk_loc_micheline (_, BYTES s) => Return _ (Bytes_constant s)
| Mk_loc_micheline (_, PRIM (_, "Unit") nil) => Return _ Unit
| Mk_loc_micheline (_, PRIM (_, "True") nil) => Return _ True_
| Mk_loc_micheline (_, PRIM (_, "False") nil) => Return _ False_
| Mk_loc_micheline (_, PRIM (_, "Pair") (a :: b :: nil)) =>
bind (fun a =>
bind (fun b => Return _ (Pair a b))
(micheline2michelson_data b))
(micheline2michelson_data a)
| Mk_loc_micheline (_, PRIM (_, "Elt") (a :: b :: nil)) =>
bind (fun a =>
bind (fun b => Return _ (Elt a b))
(micheline2michelson_data b))
(micheline2michelson_data a)
| Mk_loc_micheline (_, PRIM (_, "Left") (a :: nil)) =>
bind (fun a => Return _ (Left a)) (micheline2michelson_data a)
| Mk_loc_micheline (_, PRIM (_, "Right") (a :: nil)) =>
bind (fun a => Return _ (Right a)) (micheline2michelson_data a)
| Mk_loc_micheline (_, PRIM (_, "Some") (a :: nil)) =>
bind (fun a => Return _ (Some_ a)) (micheline2michelson_data a)
| Mk_loc_micheline (_, PRIM (_, "None") nil) => Return _ None_
| Mk_loc_micheline ((b, e), PRIM s _) => Failed _ (Expansion b e)
end.
Definition op_of_string (s : String.string) b e :=
match s with
| "EQ" => Return _ EQ
| "NEQ" => Return _ NEQ
| "LE" => Return _ LE
| "GE" => Return _ GE
| "LT" => Return _ LT
| "GT" => Return _ GT
| _ => Failed _ (Expansion b e)
end.
Definition FAIL := UNIT ;; FAILWITH.
Definition ASSERT := IF_ NOOP FAIL.
Definition IF_op_of_string (s : String.string) b e bt bf :=
match s with
| String "I" (String "F" s) =>
bind (fun op => Return _ (op ;; IF_ bt bf))
(op_of_string s b e)
| _ => Failed _ (Expansion b e)
end.
Definition ASSERT_op_of_string (s : String.string) b e :=
match s with
| String "A" (String "S" (String "S" (String "E" (String "R" (String "T" (String "_" s)))))) =>
bind (fun op => Return _ (op ;; IF_ NOOP FAIL))
(op_of_string s b e)
| _ => Failed _ (Expansion b e)
end.
Definition ASSERT_NONE := IF_NONE NOOP FAIL.
Definition ASSERT_SOME := IF_NONE FAIL NOOP.
Definition ASSERT_LEFT := IF_LEFT NOOP FAIL.
Definition ASSERT_RIGHT := IF_LEFT FAIL NOOP.
Fixpoint DIPn n code :=
match n with
| 0 => code
| S n => DIP 1 (DIPn n code)
end.
Fixpoint DUP_Sn n :=
match n with
| 0 => DUP
| S n => DIP 1 (DUP_Sn n) ;; SWAP
end.
Definition IF_SOME bt bf := IF_NONE bf bt.
Definition IF_RIGHT bt bf := IF_LEFT bf bt.
Definition IF_NIL bt bf := IF_CONS bf bt.
Inductive cadr : Set :=
| Cadr_CAR : cadr -> cadr
| Cadr_CDR : cadr -> cadr
| Cadr_nil : cadr.
Fixpoint micheline2michelson_cadr (x : cadr) : instruction :=
match x with
| Cadr_CAR x => CAR ;; micheline2michelson_cadr x
| Cadr_CDR x => CDR ;; micheline2michelson_cadr x
| Cadr_nil => NOOP
end.
Fixpoint micheline2michelson_set_cadr (x : cadr) : instruction :=
match x with
| Cadr_CAR Cadr_nil =>
CDR ;; SWAP ;; PAIR
| Cadr_CDR Cadr_nil =>
CAR ;; PAIR
| Cadr_CAR x =>
DUP ;; DIP 1 (CAR;; micheline2michelson_set_cadr x) ;; CDR ;; SWAP ;; PAIR
| Cadr_CDR x =>
DUP ;; DIP 1 (CDR;; micheline2michelson_set_cadr x) ;; CAR ;; PAIR
| Cadr_nil => NOOP (* Should not happen *)
end.
Fixpoint micheline2michelson_map_cadr (x : cadr) (code : instruction) : instruction :=
match x with
| Cadr_CAR Cadr_nil =>
DUP ;; CDR ;; DIP 1 ( CAR ;; code ) ;; SWAP ;; PAIR
| Cadr_CDR Cadr_nil =>
DUP ;; CDR ;; code ;; SWAP ;; CAR ;; PAIR
| Cadr_CAR x =>
DUP ;; DIP 1 (CAR;; micheline2michelson_map_cadr x code) ;; CDR ;; SWAP ;; PAIR
| Cadr_CDR x =>
DUP ;; DIP 1 (CDR;; micheline2michelson_map_cadr x code) ;; CAR ;; PAIR
| Cadr_nil => code (* Should not happen *)
end.
(* PAPAIR stuff *)
Inductive direction := Left | Right.
Inductive papair_token := token_P | token_A | token_I.
Fixpoint lex_papair (s : String.string) (fail : exception) :
M (Datatypes.list papair_token) :=
match s with
| String "P" s =>
bind (fun l => Return _ (cons token_P l)) (lex_papair s fail)
| String "A" s =>
bind (fun l => Return _ (cons token_A l)) (lex_papair s fail)
| String "I" s =>
bind (fun l => Return _ (cons token_I l)) (lex_papair s fail)
| "R"%string => Return _ nil
| _ => Failed _ fail
end.
Inductive papair_d : direction -> Set :=
| Papair_d_P d : papair_d Left -> papair_d Right -> papair_d d
| Papair_d_A : papair_d Left
| Papair_d_I : papair_d Right.
Fixpoint parse_papair (d : direction) (s : Datatypes.list papair_token) (fail : exception)
(fuel : Datatypes.nat) (Hs : List.length s < fuel) {struct fuel} :
M (papair_d d * { r : Datatypes.list papair_token | List.length r < List.length s}).
Proof.
destruct fuel.
- destruct (PeanoNat.Nat.nlt_0_r _ Hs).
- destruct s as [|c s].
+ exact (Failed _ fail).
+ refine (match c, d
return M (papair_d d *
{ r : Datatypes.list papair_token | List.length r < S (List.length s)})
with
| token_P, d1 =>
bind
(fun '(l, exist _ s1 Hl) =>
bind (fun '(r, exist _ s2 Hr) =>
(Return _ (Papair_d_P d l r, exist _ s2 _)))
(parse_papair Right s1 fail fuel _))
(parse_papair Left s fail fuel _)
| token_A, Left => Return _ (Papair_d_A, exist _ s _)
| token_I, Right => Return _ (Papair_d_I, exist _ s _)
| _, _ => Failed _ fail
end); simpl in *; lia.
Defined.
Inductive papair_left : Set :=
| Papair_l_P : papair_left -> papair_right -> papair_left
| Papair_l_A : papair_left
with papair_right : Set :=
| Papair_r_P : papair_left -> papair_right -> papair_right
| Papair_r_I : papair_right.
Fixpoint papair_l_of_papair_d (x : papair_d Left) : papair_left :=
match x in papair_d Left return papair_left with
| Papair_d_A => Papair_l_A
| Papair_d_P Left l r =>
Papair_l_P (papair_l_of_papair_d l) (papair_r_of_papair_d r)
end
with
papair_r_of_papair_d (x : papair_d Right) : papair_right :=
match x in papair_d Right return papair_right with
| Papair_d_I => Papair_r_I
| Papair_d_P Right l r =>
Papair_r_P (papair_l_of_papair_d l) (papair_r_of_papair_d r)
end.
Fixpoint size_l (x : papair_left) :=
match x with
| Papair_l_A => 0
| Papair_l_P l r => 1 + size_l l + size_r r
end
with
size_r (y : papair_right) :=
match y with
| Papair_r_I => 0
| Papair_r_P l r => 1 + size_l l + size_r r
end.
Inductive papair : Set :=
| Papair_PAIR : papair
| Papair_A : papair -> papair
| Papair_I : papair -> papair
| Papair_P : papair -> papair -> papair.
Program Fixpoint papair_of_l_r (x : papair_left) (y : papair_right) {measure (size_l x + size_r y)}: papair :=
match x, y with
| Papair_l_A, Papair_r_I => Papair_PAIR
| Papair_l_A, Papair_r_P l r =>
Papair_A (papair_of_l_r l r)
| Papair_l_P l r, Papair_r_I =>
Papair_I (papair_of_l_r l r)
| Papair_l_P xl xr, Papair_r_P yl yr =>
Papair_P (papair_of_l_r xl xr) (papair_of_l_r yl yr)
end.
Next Obligation.
simpl.
lia.
Defined.
Next Obligation.
simpl.
lia.
Defined.
Next Obligation.
simpl.
lia.
Defined.
Fixpoint micheline2michelson_papair (x : papair) : instruction :=
match x with
| Papair_PAIR => PAIR
| Papair_A y => DIP 1 (micheline2michelson_papair y) ;; PAIR
| Papair_I x => micheline2michelson_papair x ;; PAIR
| Papair_P x y => micheline2michelson_papair x ;;
DIP 1 (micheline2michelson_papair y) ;;
PAIR
end.
Definition UNPAIR := DUP ;; CAR ;; DIP 1 CDR.
Fixpoint micheline2michelson_unpapair (x : papair) : instruction :=
match x with
| Papair_PAIR => UNPAIR
| Papair_A y => UNPAIR ;; DIP 1 (micheline2michelson_unpapair y)
| Papair_I x => UNPAIR ;; micheline2michelson_unpapair x
| Papair_P x y => UNPAIR ;;
DIP 1 (micheline2michelson_unpapair y) ;;
micheline2michelson_unpapair x
end.
Definition parse_papair_full (s : String.string) (fail : exception): M instruction :=
bind (fun toks : Datatypes.list papair_token =>
bind (fun '(l, exist _ toks2 Htoks2) =>
bind (fun '(r, exist _ toks3 Htoks3) =>
match toks3 with
| nil => Return _
(micheline2michelson_papair
(papair_of_l_r
(papair_l_of_papair_d l)
(papair_r_of_papair_d r)))
| _ => Failed _ fail
end
)
(parse_papair Right toks2 fail (S (List.length toks2)) ltac:(simpl; lia))
)
(parse_papair Left toks fail (S (List.length toks)) ltac:(simpl; lia))
)
(lex_papair s fail).
Definition parse_unpapair_full (s : String.string) (fail : exception): M instruction :=
bind (fun toks : Datatypes.list papair_token =>
bind (fun '(l, exist _ toks2 Htoks2) =>
bind (fun '(r, exist _ toks3 Htoks3) =>
match toks3 with
| nil => Return _
(micheline2michelson_unpapair
(papair_of_l_r
(papair_l_of_papair_d l)
(papair_r_of_papair_d r)))
| _ => Failed _ fail
end
)
(parse_papair Right toks2 fail (S (List.length toks2)) ltac:(simpl; lia))
)
(parse_papair Left toks fail (S (List.length toks)) ltac:(simpl; lia))
)
(lex_papair s fail).
Fixpoint micheline2michelson_instruction (m : loc_micheline) : M instruction :=
match m with
| Mk_loc_micheline (_, SEQ l) =>
(fix micheline2michelson_instr_seq (l : Datatypes.list loc_micheline) : M instruction :=
match l with
| nil => Return _ NOOP
| cons i nil => micheline2michelson_instruction i
| i1 :: l =>
bind (fun i1 =>
bind (fun i2 => Return _ (i1 ;; i2))
(micheline2michelson_instr_seq l))
(micheline2michelson_instruction i1)
end) l
| Mk_loc_micheline (_, PRIM (_, "FAILWITH") nil) => Return _ FAILWITH
| Mk_loc_micheline (_, PRIM (_, "EXEC") nil) => Return _ EXEC
| Mk_loc_micheline (_, PRIM (_, "APPLY") nil) => Return _ APPLY
| Mk_loc_micheline (_, PRIM (_, "DROP") nil) => Return _ (DROP 1)
| Mk_loc_micheline (_, PRIM (_, "DROP")
(Mk_loc_micheline (_, NUMBER n) :: nil)) =>
Return _ (DROP (BinInt.Z.to_nat n))
| Mk_loc_micheline (_, PRIM (_, "DUP") nil) => Return _ DUP
| Mk_loc_micheline (_, PRIM (_, "SWAP") nil) => Return _ SWAP
| Mk_loc_micheline (_, PRIM (_, "UNIT") nil) => Return _ UNIT
| Mk_loc_micheline (_, PRIM (_, "EQ") nil) => Return _ EQ
| Mk_loc_micheline (_, PRIM (_, "NEQ") nil) => Return _ NEQ
| Mk_loc_micheline (_, PRIM (_, "LT") nil) => Return _ LT
| Mk_loc_micheline (_, PRIM (_, "GT") nil) => Return _ GT
| Mk_loc_micheline (_, PRIM (_, "LE") nil) => Return _ LE
| Mk_loc_micheline (_, PRIM (_, "GE") nil) => Return _ GE
| Mk_loc_micheline (_, PRIM (_, "OR") nil) => Return _ OR
| Mk_loc_micheline (_, PRIM (_, "AND") nil) => Return _ AND
| Mk_loc_micheline (_, PRIM (_, "XOR") nil) => Return _ XOR
| Mk_loc_micheline (_, PRIM (_, "NOT") nil) => Return _ NOT
| Mk_loc_micheline (_, PRIM (_, "NEG") nil) => Return _ NEG
| Mk_loc_micheline (_, PRIM (_, "ABS") nil) => Return _ ABS
| Mk_loc_micheline (_, PRIM (_, "ISNAT") nil) => Return _ ISNAT
| Mk_loc_micheline (_, PRIM (_, "INT") nil) => Return _ INT
| Mk_loc_micheline (_, PRIM (_, "ADD") nil) => Return _ ADD
| Mk_loc_micheline (_, PRIM (_, "SUB") nil) => Return _ SUB
| Mk_loc_micheline (_, PRIM (_, "MUL") nil) => Return _ MUL
| Mk_loc_micheline (_, PRIM (_, "EDIV") nil) => Return _ EDIV
| Mk_loc_micheline (_, PRIM (_, "LSL") nil) => Return _ LSL
| Mk_loc_micheline (_, PRIM (_, "LSR") nil) => Return _ LSR
| Mk_loc_micheline (_, PRIM (_, "COMPARE") nil) => Return _ COMPARE
| Mk_loc_micheline (_, PRIM (_, "CONCAT") nil) => Return _ CONCAT
| Mk_loc_micheline (_, PRIM (_, "SIZE") nil) => Return _ SIZE
| Mk_loc_micheline (_, PRIM (_, "SLICE") nil) => Return _ SLICE
| Mk_loc_micheline (_, PRIM (_, "PAIR") nil) => Return _ PAIR
| Mk_loc_micheline (_, PRIM (_, "CAR") nil) => Return _ CAR
| Mk_loc_micheline (_, PRIM (_, "CDR") nil) => Return _ CDR
| Mk_loc_micheline (_, PRIM (_, "GET") nil) => Return _ GET
| Mk_loc_micheline (_, PRIM (_, "SOME") nil) => Return _ SOME
| Mk_loc_micheline (_, PRIM (_, "NONE") (ty :: nil)) =>
bind (fun ty => Return _ (NONE ty)) (micheline2michelson_type ty)
| Mk_loc_micheline (_, PRIM (_, "LEFT") (ty :: nil)) =>
bind (fun ty => Return _ (LEFT ty)) (micheline2michelson_type ty)
| Mk_loc_micheline (_, PRIM (_, "RIGHT") (ty :: nil)) =>
bind (fun ty => Return _ (RIGHT ty)) (micheline2michelson_type ty)
| Mk_loc_micheline (_, PRIM (_, "CONS") nil) => Return _ CONS
| Mk_loc_micheline (_, PRIM (_, "NIL") (ty :: nil)) =>
bind (fun ty => Return _ (NIL ty)) (micheline2michelson_type ty)
| Mk_loc_micheline (_, PRIM (_, "TRANSFER_TOKENS") nil) => Return _ TRANSFER_TOKENS
| Mk_loc_micheline (_, PRIM (_, "SET_DELEGATE") nil) => Return _ SET_DELEGATE
| Mk_loc_micheline (_, PRIM (_, "BALANCE") nil) => Return _ BALANCE
| Mk_loc_micheline (_, PRIM (_, "ADDRESS") nil) => Return _ ADDRESS
| Mk_loc_micheline (_, PRIM (_, "CONTRACT") (ty :: nil)) =>
bind (fun ty => Return _ (CONTRACT ty)) (micheline2michelson_type ty)
| Mk_loc_micheline (_, PRIM (_, "SOURCE") nil) => Return _ SOURCE
| Mk_loc_micheline (_, PRIM (_, "SENDER") nil) => Return _ SENDER
| Mk_loc_micheline (_, PRIM (_, "SELF") nil) => Return _ SELF
| Mk_loc_micheline (_, PRIM (_, "AMOUNT") nil) => Return _ AMOUNT
| Mk_loc_micheline (_, PRIM (_, "IMPLICIT_ACCOUNT") nil) => Return _ IMPLICIT_ACCOUNT
| Mk_loc_micheline (_, PRIM (_, "NOW") nil) => Return _ NOW
| Mk_loc_micheline (_, PRIM (_, "PACK") nil) => Return _ PACK
| Mk_loc_micheline (_, PRIM (_, "UNPACK") (ty :: nil)) =>
bind (fun ty => Return _ (UNPACK ty)) (micheline2michelson_type ty)
| Mk_loc_micheline (_, PRIM (_, "HASH_KEY") nil) => Return _ HASH_KEY
| Mk_loc_micheline (_, PRIM (_, "BLAKE2B") nil) => Return _ BLAKE2B
| Mk_loc_micheline (_, PRIM (_, "SHA256") nil) => Return _ SHA256
| Mk_loc_micheline (_, PRIM (_, "SHA512") nil) => Return _ SHA512
| Mk_loc_micheline (_, PRIM (_, "CHECK_SIGNATURE") nil) => Return _ CHECK_SIGNATURE
| Mk_loc_micheline (_, PRIM (_, "MEM") nil) => Return _ MEM
| Mk_loc_micheline (_, PRIM (_, "UPDATE") nil) => Return _ UPDATE
| Mk_loc_micheline (_, PRIM (_, "CHAIN_ID") nil) => Return _ CHAIN_ID
| Mk_loc_micheline (_, PRIM (_, "LOOP") (i :: nil)) =>
bind (fun i => Return _ (LOOP i)) (micheline2michelson_instruction i)
| Mk_loc_micheline (_, PRIM (_, "LOOP_LEFT") (i :: nil)) =>
bind (fun i => Return _ (LOOP_LEFT i)) (micheline2michelson_instruction i)
| Mk_loc_micheline (_, PRIM (_, "DIP") (i :: nil)) =>
bind (fun i => Return _ (DIP 1 i)) (micheline2michelson_instruction i)
| Mk_loc_micheline (_, PRIM (_, "DIP") (Mk_loc_micheline (_, NUMBER n) :: i :: nil)) =>
bind (fun i => Return _ (DIP (BinInt.Z.to_nat n) i)) (micheline2michelson_instruction i)
| Mk_loc_micheline (_, PRIM (_, "DIG") (Mk_loc_micheline (_, NUMBER n) :: nil)) =>
Return _ (DIG (BinInt.Z.to_nat n))
| Mk_loc_micheline (_, PRIM (_, "DUG") (Mk_loc_micheline (_, NUMBER n) :: nil)) =>
Return _ (DUG (BinInt.Z.to_nat n))
| Mk_loc_micheline (_, PRIM (_, "ITER") (i :: nil)) =>
bind (fun i => Return _ (ITER i)) (micheline2michelson_instruction i)
| Mk_loc_micheline (_, PRIM (_, "MAP") (i :: nil)) =>
bind (fun i => Return _ (MAP i)) (micheline2michelson_instruction i)
| Mk_loc_micheline
(_, PRIM (_, "CREATE_CONTRACT")
(Mk_loc_micheline
(_, SEQ
((Mk_loc_micheline (_, PRIM (_, "storage") (storage_ty :: nil))) ::
(Mk_loc_micheline (_, PRIM (_, "parameter") (params_ty :: nil))) ::
(Mk_loc_micheline (_, PRIM (_, "code") (i :: nil))) :: nil)) ::
nil)) =>
bind (fun i =>
bind (fun sty =>
bind (fun pty =>
Return _ (CREATE_CONTRACT sty pty i))
(micheline2michelson_type params_ty))
(micheline2michelson_type storage_ty))
(micheline2michelson_instruction i)
| Mk_loc_micheline
(_, PRIM (_, "CREATE_CONTRACT")
(Mk_loc_micheline
(_, SEQ
((Mk_loc_micheline (_, PRIM (_, "parameter") (params_ty :: nil))) ::
(Mk_loc_micheline (_, PRIM (_, "storage") (storage_ty :: nil))) ::
(Mk_loc_micheline (_, PRIM (_, "code") (i :: nil))) :: nil)) ::
nil)) =>
bind (fun i =>
bind (fun sty =>
bind (fun pty =>
Return _ (CREATE_CONTRACT sty pty i))
(micheline2michelson_type params_ty))
(micheline2michelson_type storage_ty))
(micheline2michelson_instruction i)
| Mk_loc_micheline (_, PRIM (_, "EMPTY_SET") (cty :: nil)) =>
bind (fun cty => Return _ (EMPTY_SET cty))
(micheline2michelson_ctype cty)
| Mk_loc_micheline (_, PRIM (_, "EMPTY_MAP") (kty :: vty :: nil)) =>
bind (fun kty =>
bind (fun vty =>
Return _ (EMPTY_MAP kty vty))
(micheline2michelson_type vty))
(micheline2michelson_ctype kty)
| Mk_loc_micheline (_, PRIM (_, "EMPTY_BIG_MAP") (kty :: vty :: nil)) =>
bind (fun kty =>
bind (fun vty =>
Return _ (EMPTY_BIG_MAP kty vty))
(micheline2michelson_type vty))
(micheline2michelson_ctype kty)
| Mk_loc_micheline (_, PRIM (_, "IF") (i1 :: i2 :: nil)) =>
bind (fun i1 =>
bind (fun i2 =>
Return _ (IF_ i1 i2))
(micheline2michelson_instruction i2))
(micheline2michelson_instruction i1)
| Mk_loc_micheline (_, PRIM (_, "IF_NONE") (i1 :: i2 :: nil)) =>
bind (fun i1 =>
bind (fun i2 =>
Return _ (IF_NONE i1 i2))
(micheline2michelson_instruction i2))
(micheline2michelson_instruction i1)
| Mk_loc_micheline (_, PRIM (_, "IF_LEFT") (i1 :: i2 :: nil)) =>
bind (fun i1 =>
bind (fun i2 =>
Return _ (IF_LEFT i1 i2))
(micheline2michelson_instruction i2))
(micheline2michelson_instruction i1)
| Mk_loc_micheline (_, PRIM (_, "IF_CONS") (i1 :: i2 :: nil)) =>
bind (fun i1 =>
bind (fun i2 =>
Return _ (IF_CONS i1 i2))
(micheline2michelson_instruction i2))
(micheline2michelson_instruction i1)
| Mk_loc_micheline (_, PRIM (_, "LAMBDA") (a :: b :: i :: nil)) =>
bind (fun a =>
bind (fun b =>
bind (fun i =>
Return _ (LAMBDA a b i))
(micheline2michelson_instruction i))
(micheline2michelson_type b))
(micheline2michelson_type a)
| Mk_loc_micheline (_, PRIM (_, "PUSH") (a :: v :: nil)) =>
bind (fun a =>
bind (fun v => Return _ (PUSH a v))
(match a with
| lambda _ _ =>
bind (fun i => Return _ (Instruction i))
(micheline2michelson_instruction v)
| _ => micheline2michelson_data v
end))
(micheline2michelson_type a)
| Mk_loc_micheline (_, PRIM (_, "RENAME") _) => Return _ NOOP
| Mk_loc_micheline (_, PRIM (_, "CAST") _) => Return _ NOOP
(* Macros *)
| Mk_loc_micheline ((b, e), PRIM (_, "FAIL") nil) => Return _ FAIL
| Mk_loc_micheline ((b, e), PRIM (_, "ASSERT") nil) => Return _ ASSERT
| Mk_loc_micheline ((b, e), PRIM (_, "ASSERT_NONE") nil) => Return _ ASSERT_NONE
| Mk_loc_micheline ((b, e), PRIM (_, "ASSERT_SOME") nil) => Return _ ASSERT_SOME
| Mk_loc_micheline ((b, e), PRIM (_, "ASSERT_LEFT") nil) => Return _ ASSERT_LEFT
| Mk_loc_micheline ((b, e), PRIM (_, "ASSERT_RIGHT") nil) => Return _ ASSERT_RIGHT
| Mk_loc_micheline (_, PRIM (_, "IF_SOME") (i1 :: i2 :: nil)) =>
bind (fun i1 =>
bind (fun i2 =>
Return _ (IF_SOME i1 i2))
(micheline2michelson_instruction i2))
(micheline2michelson_instruction i1)
| Mk_loc_micheline (_, PRIM (_, "IF_RIGHT") (i1 :: i2 :: nil)) =>
bind (fun i1 =>
bind (fun i2 =>
Return _ (IF_RIGHT i1 i2))
(micheline2michelson_instruction i2))
(micheline2michelson_instruction i1)
| Mk_loc_micheline (_, PRIM (_, "IF_NIL") (i1 :: i2 :: nil)) =>
bind (fun i1 =>
bind (fun i2 =>
Return _ (IF_NIL i1 i2))
(micheline2michelson_instruction i2))
(micheline2michelson_instruction i1)
| Mk_loc_micheline ((b, e), PRIM (_, String "C" (String "M" (String "P" s))) nil) =>
bind (fun op => Return _ (COMPARE ;; op))
(op_of_string s b e)
| Mk_loc_micheline ((b, e), PRIM (_,
String "I" (String "F" (String "C" (String "M" (String "P" s))))) (i1 :: i2 :: nil)) =>
bind (fun i1 =>
bind (fun i2 =>
bind (fun op => Return _ (COMPARE ;; op ;; IF_ i1 i2))
(op_of_string s b e))
(micheline2michelson_instruction i2))
(micheline2michelson_instruction i1)
| Mk_loc_micheline ((b, e), PRIM (_,
String "I" (String "F" s)) (i1 :: i2 :: nil)) =>
bind (fun i1 =>
bind (fun i2 =>
bind (fun op => Return _ (op ;; IF_ i1 i2))
(op_of_string s b e))
(micheline2michelson_instruction i2))
(micheline2michelson_instruction i1)
| Mk_loc_micheline ((b, e), PRIM (_,
String "A" (String "S" (String "S" (String "E" (String "R" (String "T"
(String "_" (String "C" (String "M" (String "P" s)))))))))) nil) =>
bind (fun op => Return _ (COMPARE;; op ;; IF_ NOOP FAIL))
(op_of_string s b e)
| Mk_loc_micheline ((b, e), PRIM (_,
String "A" (String "S" (String "S" (String "E" (String "R" (String "T"
(String "_" s))))))) nil) =>
bind (fun op => Return _ (op ;; IF_ NOOP FAIL))
(op_of_string s b e)
| Mk_loc_micheline ((b, e), PRIM (_, "CR") nil) =>
Failed _ (Expansion_prim b e "CR")
| Mk_loc_micheline ((b, e), PRIM (_, "SET_CR") nil) =>
Failed _ (Expansion_prim b e "SET_CR")
| Mk_loc_micheline ((b, e), PRIM (_, "MAP_CR") nil) =>
Failed _ (Expansion_prim b e "MAP_CR")
(* CADAAR *)
| Mk_loc_micheline ((b, e), PRIM (_, String "C" s) nil) =>
let prim := String "C" s in
let get_cadr := fix get_cadr s :=
match s with
| "R" => Return _ Cadr_nil
| String "A" s =>
bind (fun x => Return _ (Cadr_CAR x))
(get_cadr s)
| String "D" s =>
bind (fun x => Return _ (Cadr_CDR x))
(get_cadr s)
| _ => Failed _ (Expansion_prim b e prim)
end in
bind (fun x => Return _ (micheline2michelson_cadr x))
(get_cadr s)
| Mk_loc_micheline ((b, e),
PRIM (_, String "S" (String "E"(String "T"(String "_"(String "C" s)))))
nil) =>
let prim := String "S" (String "E"(String "T"(String "_"(String "C" s)))) in
let get_cadr := fix get_cadr s :=
match s with
| "R" => Return _ Cadr_nil
| String "A" s =>
bind (fun x => Return _ (Cadr_CAR x))
(get_cadr s)
| String "D" s =>
bind (fun x => Return _ (Cadr_CDR x))
(get_cadr s)
| _ => Failed _ (Expansion_prim b e prim)
end in
bind (fun x => Return _ (micheline2michelson_set_cadr x))
(get_cadr s)
| Mk_loc_micheline ((b, e),
PRIM (_, String "M" (String "A"(String "P"(String "_"(String "C" s)))))
(a :: nil)) =>
let prim := String "M" (String "A"(String "P"(String "_"(String "C" s)))) in
let get_cadr := fix get_cadr s :=
match s with
| "R" => Return _ Cadr_nil
| String "A" s =>
bind (fun x => Return _ (Cadr_CAR x))
(get_cadr s)
| String "D" s =>
bind (fun x => Return _ (Cadr_CDR x))
(get_cadr s)
| _ => Failed _ (Expansion_prim b e prim)
end in
bind (fun x =>
bind (fun code =>
Return _ (micheline2michelson_map_cadr x code))
(micheline2michelson_instruction a))
(get_cadr s)
| Mk_loc_micheline ((b, e), PRIM (_, String "D" (String "I" s)) (a :: nil)) =>
let is_diip := fix is_diip s :=
match s with
| "P" => true
| String "I" s => is_diip s
| _ => false
end in
if is_diip s then
bind (fun a => Return _ (DIPn (String.length s) a)) (micheline2michelson_instruction a)
else Failed _ (Expansion_prim b e (String "D" (String "I" s)))
| Mk_loc_micheline ((b, e), PRIM (_, "DUP") (Mk_loc_micheline (_, NUMBER n) :: nil)) =>
match BinInt.Z.to_nat n with
| S n => Return _ (DUP_Sn n)
| O => Failed _ (Expansion b e)
end
| Mk_loc_micheline ((b, e), PRIM (_, String "D" (String "U" (String "U" s))) nil) =>
let is_duup := fix is_duup s :=
match s with
| "P" => true
| String "U" s => is_duup s
| _ => false
end in
if is_duup s then Return _ (DUP_Sn (String.length s))
else Failed _ (Expansion_prim b e (String "D" (String "U" (String "U" s))))
(* PAPAIR *)
| Mk_loc_micheline ((b, e), PRIM (_, String "P" s) nil) =>
let prim := String "P" s in
let fail := Expansion_prim b e prim in
parse_papair_full s fail
(* UNPAPAIR *)
| Mk_loc_micheline ((b, e), PRIM (_, String "U" (String "N" (String "P" s))) nil) =>
let prim := String "U" (String "N" (String "P" s)) in
let fail := Expansion_prim b e prim in
parse_unpapair_full s fail
(* Unknown case *)
| Mk_loc_micheline ((b, e), PRIM (_, s) _) => Failed _ (Expansion_prim b e s)
| Mk_loc_micheline ((b, e), _) => Failed _ (Expansion b e)
end.
Record untyped_michelson_file :=
Mk_untyped_michelson_file
{ parameter : type;
storage : type;
code : instruction }.
Record untyped_michelson_file_opt :=
Mk_untyped_michelson_file_opt
{ parameter_opt : Datatypes.option type;
storage_opt : Datatypes.option type;
code_opt : Datatypes.option instruction }.
Definition read_parameter (ty : type) (f : untyped_michelson_file_opt) :=
match f.(parameter_opt) with
| None => Return _ {| parameter_opt := Some ty;
storage_opt := f.(storage_opt);
code_opt := f.(code_opt) |}
| Some _ => Failed _ Parsing
end.
Definition read_storage (ty : type) (f : untyped_michelson_file_opt) :=
match f.(storage_opt) with
| None => Return _ {| parameter_opt := f.(parameter_opt);
storage_opt := Some ty;
code_opt := f.(code_opt) |}
| Some _ => Failed _ Parsing
end.
Definition read_code (c : instruction) (f : untyped_michelson_file_opt) :=
match f.(code_opt) with
| None => Return _ {| parameter_opt := f.(parameter_opt);
storage_opt := f.(storage_opt);
code_opt := Some c |}
| Some _ => Failed _ Parsing
end.
Definition micheline2michelson_file (m : Datatypes.list loc_micheline) : M untyped_michelson_file :=
let l :=
match m with
| Mk_loc_micheline (_, SEQ l) :: nil => l
| l => l
end
in
bind (fun a =>
match a.(parameter_opt), a.(storage_opt), a.(code_opt) with
| Some param, Some storage, Some code =>
Return _ {| parameter := param; storage := storage; code := code |}
| _, _, _ => Failed _ Parsing
end)
(error.list_fold_left
(fun (a : untyped_michelson_file_opt) (lm : loc_micheline) =>
let 'Mk_loc_micheline (_, _, m) := lm in
match m with
| PRIM (_, _, "parameter") (cons param nil) =>
bind (fun ty => read_parameter ty a)
(micheline2michelson_type param)
| PRIM (_, _, "storage") (cons storage nil) =>
bind (fun ty => read_storage ty a)
(micheline2michelson_type storage)
| PRIM (_, _, "code") (cons code nil) =>
bind (fun c => read_code c a)
(micheline2michelson_instruction code)
| _ => Failed _ Parsing
end)
l
{| parameter_opt := None; storage_opt := None; code_opt := None |}).