123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)(* *)(* Permission is hereby granted, free of charge, to any person obtaining a *)(* copy of this software and associated documentation files (the "Software"),*)(* to deal in the Software without restriction, including without limitation *)(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)(* and/or sell copies of the Software, and to permit persons to whom the *)(* Software is furnished to do so, subject to the following conditions: *)(* *)(* The above copyright notice and this permission notice shall be included *)(* in all copies or substantial portions of the Software. *)(* *)(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)(* DEALINGS IN THE SOFTWARE. *)(* *)(*****************************************************************************)openAlpha_contextopenMichelineopenScript_tc_errorstypevar_annot=Var_annotofNon_empty_string.t[@@ocaml.unboxed]typetype_annot=Type_annotofNon_empty_string.t[@@ocaml.unboxed]typefield_annot=Field_annotofNon_empty_string.t[@@ocaml.unboxed]moduleFOR_TESTS=structletunsafe_var_annot_of_strings=Var_annot(Non_empty_string.of_string_exns)letunsafe_type_annot_of_strings=Type_annot(Non_empty_string.of_string_exns)letunsafe_field_annot_of_strings=Field_annot(Non_empty_string.of_string_exns)endletsome_var_annot_of_string_exns=Some(Var_annot(Non_empty_string.of_string_exns))letsome_field_annot_of_string_exns=Some(Field_annot(Non_empty_string.of_string_exns))letdefault_now_annot=some_var_annot_of_string_exn"now"letdefault_amount_annot=some_var_annot_of_string_exn"amount"letdefault_balance_annot=some_var_annot_of_string_exn"balance"letdefault_level_annot=some_var_annot_of_string_exn"level"letdefault_source_annot=some_var_annot_of_string_exn"source"letdefault_sender_annot=some_var_annot_of_string_exn"sender"letdefault_self_annot=some_var_annot_of_string_exn"self"letdefault_arg_annot=some_var_annot_of_string_exn"arg"letlambda_arg_annot=some_var_annot_of_string_exn"@arg"letdefault_param_annot=some_var_annot_of_string_exn"parameter"letdefault_storage_annot=some_var_annot_of_string_exn"storage"letdefault_car_annot=some_field_annot_of_string_exn"car"letdefault_cdr_annot=some_field_annot_of_string_exn"cdr"letdefault_contract_annot=some_field_annot_of_string_exn"contract"letdefault_addr_annot=some_field_annot_of_string_exn"address"letdefault_pack_annot=some_field_annot_of_string_exn"packed"letdefault_unpack_annot=some_field_annot_of_string_exn"unpacked"letdefault_slice_annot=some_field_annot_of_string_exn"slice"letdefault_elt_annot=some_field_annot_of_string_exn"elt"letdefault_key_annot=some_field_annot_of_string_exn"key"letdefault_hd_annot=some_field_annot_of_string_exn"hd"letdefault_tl_annot=some_field_annot_of_string_exn"tl"letdefault_some_annot=some_field_annot_of_string_exn"some"letdefault_left_annot=some_field_annot_of_string_exn"left"letdefault_right_annot=some_field_annot_of_string_exn"right"letdefault_sapling_state_annot=some_var_annot_of_string_exn"sapling"letdefault_sapling_balance_annot=some_var_annot_of_string_exn"sapling_balance"letunparse_type_annot:type_annotoption->stringlist=function|None->[]|Some(Type_annota)->[":"^(a:>string)]letunparse_var_annot:var_annotoption->stringlist=function|None->[]|Some(Var_annota)->["@"^(a:>string)]letunparse_field_annot:field_annotoption->stringlist=function|None->[]|Some(Field_annota)->["%"^(a:>string)]letfield_to_var_annot:field_annotoption->var_annotoption=function|None->None|Some(Field_annots)->Some(Var_annots)lettype_to_var_annot:type_annotoption->var_annotoption=function|None->None|Some(Type_annots)->Some(Var_annots)letvar_to_field_annot:var_annotoption->field_annotoption=function|None->None|Some(Var_annots)->Some(Field_annots)letdefault_annot~default=functionNone->default|annot->annotletgen_access_annot:var_annotoption->?default:field_annotoption->field_annotoption->var_annotoption=funvalue_annot?(default=None)field_annot->match(value_annot,field_annot,default)with|(None,None,_)|(Some_,None,None)->None|(None,Some(Field_annotf),_)->Some(Var_annotf)|(Some(Var_annotv),None,Some(Field_annotf))->Some(Var_annot(Non_empty_string.cat2v~sep:"."f))|(Some(Var_annotv),Some(Field_annotf),_)->Some(Var_annot(Non_empty_string.cat2v~sep:"."f))letmerge_type_annot:legacy:bool->type_annotoption->type_annotoption->type_annotoptiontzresult=fun~legacyannot1annot2->match(annot1,annot2)with|(None,None)|(Some_,None)|(None,Some_)->Result.return_none|(Some(Type_annota1),Some(Type_annota2))->iflegacy||Non_empty_string.(a1=a2)thenokannot1elseerror(Inconsistent_annotations(":"^(a1:>string),":"^(a2:>string)))letmerge_field_annot:legacy:bool->field_annotoption->field_annotoption->field_annotoptiontzresult=fun~legacyannot1annot2->match(annot1,annot2)with|(None,None)|(Some_,None)|(None,Some_)->Result.return_none|(Some(Field_annota1),Some(Field_annota2))->iflegacy||Non_empty_string.(a1=a2)thenokannot1elseerror(Inconsistent_annotations("%"^(a1:>string),"%"^(a2:>string)))letmerge_var_annot:var_annotoption->var_annotoption->var_annotoption=funannot1annot2->match(annot1,annot2)with|(None,None)|(Some_,None)|(None,Some_)->None|(Some(Var_annota1),Some(Var_annota2))->ifNon_empty_string.(a1=a2)thenannot1elseNoneleterror_unexpected_annotlocannot=matchannotwith|[]->Result.return_unit|_::_->error(Unexpected_annotationloc)(* Check that the predicate p holds on all s.[k] for k >= i *)letstring_iterpsi=letlen=String.lengthsinletrecauxi=ifCompare.Int.(i>=len)thenResult.return_unitelseps.[i]>>?fun()->aux(i+1)inauxiletis_allowed_char=function|'a'..'z'|'A'..'Z'|'_'|'.'|'%'|'@'|'0'..'9'->true|_->false(* Valid annotation characters as defined by the allowed_annot_char function from lib_micheline/micheline_parser *)letcheck_charlocc=ifis_allowed_charcthenResult.return_unitelseerror(Unexpected_annotationloc)(* This constant is defined in lib_micheline/micheline_parser which is not available in the environment. *)letmax_annot_length=255typeannot_opt=|Field_annot_optofNon_empty_string.toption|Type_annot_optofNon_empty_string.toption|Var_annot_optofNon_empty_string.toptionletpercent=Non_empty_string.of_string_exn"%"letpercent_percent=Non_empty_string.of_string_exn"%%"letat=Non_empty_string.of_string_exn"@"letparse_annotsloc?(allow_special_var=false)?(allow_special_field=false)l=(* allow empty annotations as wildcards but otherwise only accept
annotations that start with [a-zA-Z_] *)letsub_or_wildcardwraps=matchNon_empty_string.of_stringswith|None->ok@@wrapNone|Somes->(match(s:>string).[0]with|'a'..'z'|'A'..'Z'|'_'|'0'..'9'->(* check that all characters are valid*)string_iter(check_charloc)(s:>string)1>>?fun()->ok@@wrap(Somes)|_->error(Unexpected_annotationloc))inList.map_e(function|"@%"whenallow_special_var->ok@@Var_annot_opt(Somepercent)|"@%%"whenallow_special_var->ok@@Var_annot_opt(Somepercent_percent)|"%@"whenallow_special_field->ok@@Field_annot_opt(Someat)|s->(letlen=String.lengthsinifCompare.Int.(len=0||len>max_annot_length)thenerror(Unexpected_annotationloc)elseletrest=String.subs1(len-1)inmatchs.[0]with|':'->sub_or_wildcard(funa->Type_annot_opta)rest|'@'->sub_or_wildcard(funa->Var_annot_opta)rest|'%'->sub_or_wildcard(funa->Field_annot_opta)rest|_->error(Unexpected_annotationloc)))lletopt_var_of_var_opt=functionNone->None|Somea->Some(Var_annota)letopt_field_of_field_opt=function|None->None|Somea->Some(Field_annota)letopt_type_of_type_opt=function|None->None|Somea->Some(Type_annota)letclassify_annotlocl:(var_annotoptionlist*type_annotoptionlist*field_annotoptionlist)tzresult=trylet(_,rv,_,rt,_,rf)=List.fold_left(fun(in_v,rv,in_t,rt,in_f,rf)a->match(a,in_v,rv,in_t,rt,in_f,rf)with|(Var_annot_opta,true,_,_,_,_,_)|(Var_annot_opta,false,[],_,_,_,_)->(true,opt_var_of_var_opta::rv,false,rt,false,rf)|(Type_annot_opta,_,_,true,_,_,_)|(Type_annot_opta,_,_,false,[],_,_)->(false,rv,true,opt_type_of_type_opta::rt,false,rf)|(Field_annot_opta,_,_,_,_,true,_)|(Field_annot_opta,_,_,_,_,false,[])->(false,rv,false,rt,true,opt_field_of_field_opta::rf)|_->raiseExit)(false,[],false,[],false,[])linok(List.revrv,List.revrt,List.revrf)withExit->error(Ungrouped_annotationsloc)letget_one_annotloc=function|[]->Result.return_none|[a]->oka|_->error(Unexpected_annotationloc)letget_two_annotloc=function|[]->ok(None,None)|[a]->ok(a,None)|[a;b]->ok(a,b)|_->error(Unexpected_annotationloc)letparse_type_annot:Script.location->stringlist->type_annotoptiontzresult=funlocannot->parse_annotslocannot>>?classify_annotloc>>?fun(vars,types,fields)->error_unexpected_annotlocvars>>?fun()->error_unexpected_annotlocfields>>?fun()->get_one_annotloctypesletparse_composed_type_annot:Script.location->stringlist->(type_annotoption*field_annotoption*field_annotoption)tzresult=funlocannot->parse_annotslocannot>>?classify_annotloc>>?fun(vars,types,fields)->error_unexpected_annotlocvars>>?fun()->get_one_annotloctypes>>?funt->get_two_annotlocfields>|?fun(f1,f2)->(t,f1,f2)letparse_field_annot:Script.location->stringlist->field_annotoptiontzresult=funlocannot->parse_annotslocannot>>?classify_annotloc>>?fun(vars,types,fields)->error_unexpected_annotlocvars>>?fun()->error_unexpected_annotloctypes>>?fun()->get_one_annotlocfieldsletextract_field_annot:Script.node->(Script.node*field_annotoption)tzresult=function|Prim(loc,prim,args,annot)->letrecextract_firstacc=function|[]->(None,annot)|s::rest->ifCompare.Int.(String.lengths>0)&&Compare.Char.(s.[0]='%')then(Somes,List.rev_appendaccrest)elseextract_first(s::acc)restinlet(field_annot,annot)=extract_first[]annotin(matchfield_annotwith|None->Result.return_none|Somefield_annot->parse_field_annotloc[field_annot])>|?funfield_annot->(Prim(loc,prim,args,annot),field_annot)|expr->ok(expr,None)letcheck_correct_field:field_annotoption->field_annotoption->unittzresult=funf1f2->match(f1,f2)with|(None,_)|(_,None)->Result.return_unit|(Some(Field_annots1),Some(Field_annots2))->ifNon_empty_string.(s1=s2)thenResult.return_unitelseerror(Inconsistent_field_annotations("%"^(s1:>string),"%"^(s2:>string)))letparse_var_annot:Script.location->?default:var_annotoption->stringlist->var_annotoptiontzresult=funloc?defaultannot->parse_annotslocannot>>?classify_annotloc>>?fun(vars,types,fields)->error_unexpected_annotloctypes>>?fun()->error_unexpected_annotlocfields>>?fun()->get_one_annotlocvars>|?function|Some_asa->a|None->(matchdefaultwithSomea->a|None->None)letsplit_last_dot=function|None->(None,None)|Some(Field_annots)->(matchNon_empty_string.split_on_last'.'swith|Some(s1,s2)->letf=match(s2:>string)with|"car"|"cdr"->None|_->Some(Field_annots2)in(Some(Var_annots1),f)|None->(None,Some(Field_annots)))letsplit_if_special~loc~if_specialvf=matchfwith|Some(Field_annotfa)whenNon_empty_string.(fa=at)->(matchif_specialwith|Somespecial_var->ok@@split_last_dotspecial_var|None->error(Unexpected_annotationloc))|_->ok(v,f)letcommon_prefixv1v2=match(v1,v2)with|(Some(Var_annots1),Some(Var_annots2))whenNon_empty_string.(s1=s2)->v1|(Some_,None)->v1|(None,Some_)->v2|(_,_)->Noneletparse_constr_annot:Script.location->?if_special_first:field_annotoption->?if_special_second:field_annotoption->stringlist->(var_annotoption*type_annotoption*field_annotoption*field_annotoption)tzresult=funloc?if_special_first?if_special_secondannot->parse_annots~allow_special_field:truelocannot>>?classify_annotloc>>?fun(vars,types,fields)->get_one_annotlocvars>>?funv->get_one_annotloctypes>>?funt->get_two_annotlocfields>>?fun(f1,f2)->split_if_special~loc~if_special:if_special_firstvf1>>?fun(v1,f1)->split_if_special~loc~if_special:if_special_secondvf2>|?fun(v2,f2)->letv=matchvwithNone->common_prefixv1v2|Some_->vin(v,t,f1,f2)letparse_two_var_annot:Script.location->stringlist->(var_annotoption*var_annotoption)tzresult=funlocannot->parse_annotslocannot>>?classify_annotloc>>?fun(vars,types,fields)->error_unexpected_annotloctypes>>?fun()->error_unexpected_annotlocfields>>?fun()->get_two_annotlocvarsletvar_annot_from_special:field_name:field_annotoption->default:var_annotoption->value_annot:var_annotoption->var_annotoption->var_annotoption=fun~field_name~default~value_annotv->matchvwith|Some(Var_annotva)->(match(va:>string)with|"%"->field_to_var_annotfield_name|"%%"->default|_->v)|None->value_annotletparse_destr_annot:Script.location->stringlist->default_accessor:field_annotoption->field_name:field_annotoption->pair_annot:var_annotoption->value_annot:var_annotoption->(var_annotoption*field_annotoption)tzresult=funlocannot~default_accessor~field_name~pair_annot~value_annot->parse_annotsloc~allow_special_var:trueannot>>?classify_annotloc>>?fun(vars,types,fields)->error_unexpected_annotloctypes>>?fun()->get_one_annotlocvars>>?funv->get_one_annotlocfields>|?funf->letdefault=gen_access_annotpair_annotfield_name~default:default_accessorinletv=var_annot_from_special~field_name~default~value_annotvin(v,f)letparse_unpair_annot:Script.location->stringlist->field_name_car:field_annotoption->field_name_cdr:field_annotoption->pair_annot:var_annotoption->value_annot_car:var_annotoption->value_annot_cdr:var_annotoption->(var_annotoption*var_annotoption*field_annotoption*field_annotoption)tzresult=funlocannot~field_name_car~field_name_cdr~pair_annot~value_annot_car~value_annot_cdr->parse_annotsloc~allow_special_var:trueannot>>?classify_annotloc>>?fun(vars,types,fields)->error_unexpected_annotloctypes>>?fun()->get_two_annotlocvars>>?fun(vcar,vcdr)->get_two_annotlocfields>|?fun(fcar,fcdr)->letdefault_car=gen_access_annotpair_annotfield_name_car~default:default_car_annotinletdefault_cdr=gen_access_annotpair_annotfield_name_cdr~default:default_cdr_annotinletvcar=var_annot_from_special~field_name:field_name_car~default:default_car~value_annot:value_annot_carvcarinletvcdr=var_annot_from_special~field_name:field_name_cdr~default:default_cdr~value_annot:value_annot_cdrvcdrin(vcar,vcdr,fcar,fcdr)letparse_entrypoint_annot:Script.location->?default:var_annotoption->stringlist->(var_annotoption*field_annotoption)tzresult=funloc?defaultannot->parse_annotslocannot>>?classify_annotloc>>?fun(vars,types,fields)->error_unexpected_annotloctypes>>?fun()->get_one_annotlocfields>>?funf->get_one_annotlocvars>|?function|Some_asa->(a,f)|None->(matchdefaultwithSomea->(a,f)|None->(None,f))letparse_var_type_annot:Script.location->stringlist->(var_annotoption*type_annotoption)tzresult=funlocannot->parse_annotslocannot>>?classify_annotloc>>?fun(vars,types,fields)->error_unexpected_annotlocfields>>?fun()->get_one_annotlocvars>>?funv->get_one_annotloctypes>|?funt->(v,t)