1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009(*
* Copyright yutopp 2017 - .
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*)open!BasemoduleSf=Simple_term_formatmoduleZ=Aux.Z(* line number *)typeline_t=int[@@derivingsexp_of](* http://erlang.org/doc/apps/erts/absform.html *)typet=|AbstractCodeofform_tandform_t=|ModDeclofform_tlist|AttrExportofline_t*(string*int)list|AttrExportTypeofline_t*(string*int)list|AttrImportofline_t*(string*int)list|AttrModofline_t*string|AttrFileofline_t*string*line_t|DeclFunofline_t*string*int*clause_tlist|SpecFunofline_t*stringoption*string*int*type_tlist|DeclRecordofline_t*(line_t*string*expr_toption*type_toption)list|DeclTypeofline_t*string*(line_t*string)list*type_t|DeclOpaqueTypeofline_t*string*(line_t*string)list*type_t|AttrWildofline_t*string*Sf.t|FormEofandliteral_t=|LitAtomofline_t*string|LitIntegerofline_t*int|LitBigIntofline_t*Z.t|LitStringofline_t*stringandpattern_t=|PatConsofline_t*pattern_t*pattern_t|PatNilofline_t|PatMapofline_t*pattern_assoc_tlist|PatTupleofline_t*pattern_tlist|PatUniversalofline_t|PatVarofline_t*string|PatLitofliteral_tandpattern_assoc_t=|PatAssocExactofline_t*pattern_t*pattern_tandexpr_t=|ExprBodyofexpr_tlist|ExprCaseofline_t*expr_t*clause_tlist|ExprConsofline_t*expr_t*expr_t|ExprNilofline_t|ExprListComprehensionofline_t*expr_t*qualifier_tlist|ExprLocalFunRefofline_t*string*int|ExprRemoteFunRefofline_t*atom_or_var_t*atom_or_var_t*integer_or_var_t|ExprFunofline_t*stringoption*clause_tlist|ExprLocalCallofline_t*expr_t*expr_tlist|ExprRemoteCallofline_t*line_t*expr_t*expr_t*expr_tlist|ExprMapCreationofline_t*expr_assoc_tlist|ExprMapUpdateofline_t*expr_t*expr_assoc_tlist|ExprMatchofline_t*pattern_t*expr_t|ExprBinOpofline_t*string*expr_t*expr_t|ExprTupleofline_t*expr_tlist|ExprVarofline_t*string|ExprLitofliteral_tandexpr_assoc_t=|ExprAssocofline_t*expr_t*expr_t|ExprAssocExactofline_t*expr_t*expr_tandqualifier_t=|QualifierGeneratorofline_t*pattern_t*expr_t|QualifierFilterofexpr_tandatom_or_var_t=|AtomVarAtomofline_t*string|AtomVarVarofline_t*stringandinteger_or_var_t=|IntegerVarIntegerofline_t*int|IntegerVarVarofline_t*stringandclause_t=|ClsCaseofline_t*pattern_t*guard_sequence_toption*expr_t|ClsFunofline_t*pattern_tlist*guard_sequence_toption*expr_tandguard_sequence_t=|GuardSeqofguard_tlistandguard_t=|Guardofguard_test_tlistandguard_test_t=|GuardTestCallofline_t*literal_t*guard_test_tlist|GuardTestMapCreationofline_t*guard_test_assoc_tlist|GuardTestMapUpdateofline_t*guard_test_t*guard_test_assoc_tlist|GuardTestBinOpofline_t*string*guard_test_t*guard_test_t|GuardTestTupleofline_t*guard_test_tlist|GuardTestVarofline_t*string|GuardTestLitofliteral_tandguard_test_assoc_t=|GuardTestAssocofline_t*guard_test_t*guard_test_t|GuardTestAssocExactofline_t*guard_test_t*guard_test_tandtype_t=|TyAnnofline_t*type_t*type_t|TyBitstringofline_t*type_t*type_t|TyPredefofline_t*string*type_tlist|TyBinOpofline_t*type_t*string*type_t|TyUnaryOpofline_t*string*type_t|TyRangeofline_t*type_t*type_t|TyAnyMapofline_t|TyMapofline_t*type_assoc_tlist|TyVarofline_t*string|TyFunAnyofline_t|TyFunAnyArityofline_t*line_t*type_t|TyContFunofline_t*type_t*type_func_cont_t|TyFunofline_t*line_t*type_tlist*type_t|TyAnyTupleofline_t|TyTupleofline_t*type_tlist|TyUnionofline_t*type_tlist|TyUserofline_t*string*type_tlist|TyLitofliteral_tandtype_assoc_t=|TyAssocofline_t*type_t*type_t|TyAssocExactofline_t*type_t*type_tandtype_func_cont_t=|TyContoftype_func_cont_tlist|TyContRelofline_t*type_func_cont_t*type_t*type_t|TyContIsSubTypeofline_t[@@derivingsexp_of]typeerr_t=Sf.tErr.t[@@derivingsexp_of]lettrack~locresult=Result.map_error~f:(Err.record_backtrace~loc:loc)result(*
* Entry
*)letrecof_sfsf:(t,err_t)Result.t=letopenResult.Let_syntaxinmatchsfwith|Sf.Tuple(2,[Sf.Atom"raw_abstract_v1";sf_forms])->let%bindforms=sf_forms|>form_of_sf|>track~loc:[%here]inAbstractCodeforms|>return(* is it suitable here? *)|Sf.Tuple(3,[Sf.Atom"debug_info_v1";Sf.Atom"erl_abstract_code";Sf.Tuple(2,[sf_forms;_options])])->let%bindforms=sf_forms|>form_of_sf|>track~loc:[%here]inAbstractCodeforms|>return|_->Err.create~loc:[%here](Err.Not_supported_absform("root",sf))|>Result.fail(*
* 8.1 Module Declarations and Forms
*)andform_of_sfsf:(form_t,err_t)Result.t=letopenResult.Let_syntaxinmatchsfwith(* module declaration *)|Sf.Listsf_forms->let%bindforms=sf_forms|>List.map~f:form_of_sf|>Result.all|>track~loc:[%here]inModDeclforms|>return(* attribute -export *)|Sf.Tuple(4,[Sf.Atom"attribute";Sf.Integerline;Sf.Atom"export";Sf.Listsf_name_and_arity_list])->let%bindname_and_arity_list=sf_name_and_arity_list|>List.map~f:name_and_arity_of_sf|>Result.all|>track~loc:[%here]inAttrExport(line,name_and_arity_list)|>return(* attribute -export_type *)|Sf.Tuple(4,[Sf.Atom"attribute";Sf.Integerline;Sf.Atom"export_type";Sf.Listsf_name_and_arity_list])->let%bindname_and_arity_list=sf_name_and_arity_list|>List.map~f:name_and_arity_of_sf|>Result.all|>track~loc:[%here]inAttrExportType(line,name_and_arity_list)|>return(* attribute -import *)|Sf.Tuple(4,[Sf.Atom"attribute";Sf.Integerline;Sf.Atom"import";Sf.Listsf_name_and_arity_list])->let%bindname_and_arity_list=sf_name_and_arity_list|>List.map~f:name_and_arity_of_sf|>Result.all|>track~loc:[%here]inAttrImport(line,name_and_arity_list)|>return(* attribute -module *)|Sf.Tuple(4,[Sf.Atom"attribute";Sf.Integerline;Sf.Atom"module";Sf.Atommodule_name])->AttrMod(line,module_name)|>return(* attribute -file *)|Sf.Tuple(4,[Sf.Atom"attribute";Sf.Integerline;Sf.Atom"file";Sf.Tuple(2,[Sf.Stringfile;Sf.Integerfile_line])])->AttrFile(line,file,file_line)|>return(* function declaration *)|Sf.Tuple(5,[Sf.Atom"function";Sf.Integerline;Sf.Atomname;Sf.Integerarity;Sf.Listsf_f_clauses])->let%bindf_clauses=sf_f_clauses|>List.map~f:(cls_of_sf~in_function:true)|>Result.all|>track~loc:[%here]inDeclFun(line,name,arity,f_clauses)|>return(* function specification *)|Sf.Tuple(4,[Sf.Atom"attribute";Sf.Integerline;Sf.Atom"spec";Sf.Tuple(2,[Sf.Tuple(2,[Sf.Atomname;Sf.Integerarity]);Sf.Listsf_specs])])->let%bindspecs=sf_specs|>List.map~f:fun_type_of_sf|>Result.all|>track~loc:[%here]inSpecFun(line,None,name,arity,specs)|>return(* function specification(Mod) *)|Sf.Tuple(4,[Sf.Atom"attribute";Sf.Integerline;Sf.Atom"spec";Sf.Tuple(2,[Sf.Tuple(3,[Sf.Atomm;Sf.Atomname;Sf.Integerarity]);Sf.Listsf_specs])])->let%bindspecs=sf_specs|>List.map~f:fun_type_of_sf|>Result.all|>track~loc:[%here]inSpecFun(line,Somem,name,arity,specs)|>return(* record declaration *)|Sf.Tuple(4,[Sf.Atom"attribute";Sf.Integerline;Sf.Atom"record";Sf.Tuple(2,[Sf.Atomname;Sf.Listsf_record_fields])])->let%bindrecord_fields=sf_record_fields|>List.map~f:record_field_of_sf|>Result.all|>track~loc:[%here]inDeclRecord(line,record_fields)|>return(* type declaration *)|Sf.Tuple(4,[Sf.Atom"attribute";Sf.Integerline;Sf.Atom"type";Sf.Tuple(3,[Sf.Atomname;sf_t;Sf.Listsf_tvars]);])->let%bindt=sf_t|>type_of_sf|>track~loc:[%here]inlet%bindtvars=sf_tvars|>List.map~f:tvar_of_sf|>Result.all|>track~loc:[%here]inDeclType(line,name,tvars,t)|>return(* opaque type declaration *)|Sf.Tuple(4,[Sf.Atom"attribute";Sf.Integerline;Sf.Atom"opaque";Sf.Tuple(3,[Sf.Atomname;sf_t;Sf.Listsf_tvars]);])->let%bindt=sf_t|>type_of_sf|>track~loc:[%here]inlet%bindtvars=sf_tvars|>List.map~f:tvar_of_sf|>Result.all|>track~loc:[%here]inDeclOpaqueType(line,name,tvars,t)|>return(* wild attribute *)|Sf.Tuple(4,[Sf.Atom"attribute";Sf.Integerline;Sf.Atomattr;term])->AttrWild(line,attr,term)|>return(* eof *)|Sf.Tuple(2,[Sf.Atom"eof";Sf.Integerline])->FormEof|>return|_->Err.create~loc:[%here](Err.Not_supported_absform("form",sf))|>Result.failandname_and_arity_of_sfsf:((string*int),err_t)Result.t=matchsfwith|Sf.Tuple(2,[Sf.Atomname;Sf.Integerarity])->Ok(name,arity)|_->Err.create~loc:[%here](Err.Not_supported_absform("name_and_arity",sf))|>Result.failandrecord_field_of_sfsf:((int*string*expr_toption*type_toption),err_t)Result.t=letopenResult.Let_syntaxinmatchsfwith|Sf.Tuple(3,[Sf.Atom"record_field";Sf.Integerline;Sf.Tuple(3,[Sf.Atom"atom";_;Sf.Atomfield]);])->(line,field,None,None)|>return|Sf.Tuple(4,[Sf.Atom"record_field";Sf.Integerline;Sf.Tuple(3,[Sf.Atom"atom";_;Sf.Atomfield]);sf_e])->let%binde=sf_e|>expr_of_sf|>track~loc:[%here]in(line,field,Somee,None)|>return|Sf.Tuple(3,[Sf.Atom"typed_record_field";Sf.Tuple(3,[Sf.Atom"record_field";Sf.Integerline;Sf.Tuple(3,[Sf.Atom"atom";_;Sf.Atomfield])]);sf_t])->let%bindt=sf_t|>type_of_sf|>track~loc:[%here]in(line,field,None,Somet)|>return|Sf.Tuple(3,[Sf.Atom"typed_record_field";Sf.Tuple(4,[Sf.Atom"record_field";Sf.Integerline;Sf.Tuple(3,[Sf.Atom"atom";_;Sf.Atomfield]);sf_e]);sf_t])->let%binde=sf_e|>expr_of_sf|>track~loc:[%here]inlet%bindt=sf_t|>type_of_sf|>track~loc:[%here]in(line,field,Somee,Somet)|>return|_->Err.create~loc:[%here](Err.Not_supported_absform("record_field",sf))|>Result.failandtvar_of_sfsf:((line_t*string),err_t)Result.t=matchsfwith|Sf.Tuple(3,[Sf.Atom"var";Sf.Integerline;Sf.Atomtvar])->Ok(line,tvar)|_->Err.create~loc:[%here](Err.Not_supported_absform("tvar",sf))|>Result.fail(*
* 8.2 Atomic Literals
*)andlit_of_sfsf:(literal_t,err_t)Result.t=letopenResult.Let_syntaxinmatchsfwith|Sf.Tuple(3,[Sf.Atom"atom";Sf.Integerline;Sf.Atomv])->LitAtom(line,v)|>return|Sf.Tuple(3,[Sf.Atom"char";Sf.Integerline;_])->failwith"TODO"|Sf.Tuple(3,[Sf.Atom"float";Sf.Integerline;_])->failwith"TODO"|Sf.Tuple(3,[Sf.Atom"integer";Sf.Integerline;Sf.Integerv])->LitInteger(line,v)|>return|Sf.Tuple(3,[Sf.Atom"integer";Sf.Integerline;Sf.BigIntv])->LitBigInt(line,v)|>return|Sf.Tuple(3,[Sf.Atom"string";Sf.Integerline;Sf.Stringv])->LitString(line,v)|>return|_->Err.create~loc:[%here](Err.Not_supported_absform("lit",sf))|>Result.fail(*
* 8.3 Patterns
*)andpat_of_sfsf:(pattern_t,err_t)Result.t=letopenResult.Let_syntaxinmatchsfwith(* a cons pattern *)|Sf.Tuple(4,[Sf.Atom"cons";Sf.Integerline;sf_head;sf_tail])->let%bindhead=sf_head|>pat_of_sf|>track~loc:[%here]inlet%bindtail=sf_tail|>pat_of_sf|>track~loc:[%here]inPatCons(line,head,tail)|>return(* a nil pattern *)|Sf.Tuple(2,[Sf.Atom"nil";Sf.Integerline])->PatNilline|>return(* a map pattern *)|Sf.Tuple(3,[Sf.Atom"map";Sf.Integerline;Sf.Listsf_assocs])->let%bindassocs=sf_assocs|>List.map~f:pat_assoc_of_sf|>Result.all|>track~loc:[%here]inPatMap(line,assocs)|>return(* a tuple pattern *)|Sf.Tuple(3,[Sf.Atom"tuple";Sf.Integerline;Sf.Listsf_pats])->let%bindpats=sf_pats|>List.map~f:pat_of_sf|>Result.all|>track~loc:[%here]inPatTuple(line,pats)|>return(* a variable pattern *)|Sf.Tuple(3,[Sf.Atom"var";Sf.Integerline;Sf.Atom"_"])->PatUniversalline|>return(* a variable pattern *)|Sf.Tuple(3,[Sf.Atom"var";Sf.Integerline;Sf.Atomid])->PatVar(line,id)|>return(* atomic literal *)|sf_v->let%bindv=sf_v|>lit_of_sf|>track~loc:[%here]inPatLitv|>returnandpat_assoc_of_sfsf:(pattern_assoc_t,err_t)Result.t=letopenResult.Let_syntaxinmatchsfwith(* an exact association *)|Sf.Tuple(4,[Sf.Atom"map_field_exact";Sf.Integerline;sf_k;sf_v])->let%bindk=sf_k|>pat_of_sf|>track~loc:[%here]inlet%bindv=sf_v|>pat_of_sf|>track~loc:[%here]inPatAssocExact(line,k,v)|>return|_->Err.create~loc:[%here](Err.Not_supported_absform("pat_assoc",sf))|>Result.fail(*
* 8.4 Expressions
*)andexpr_of_sfsf:(expr_t,err_t)Result.t=letopenResult.Let_syntaxinmatchsfwith|Sf.Listsf_es->let%bindes=sf_es|>List.map~f:expr_of_sf|>Result.all|>track~loc:[%here]inExprBodyes|>return(* a case expression *)|Sf.Tuple(4,[Sf.Atom"case";Sf.Integerline;sf_e;Sf.Listsf_clauses])->let%binde=sf_e|>expr_of_sf|>track~loc:[%here]inlet%bindclauses=sf_clauses|>List.map~f:cls_of_sf|>Result.all|>track~loc:[%here]inExprCase(line,e,clauses)|>return(* a cons expression *)|Sf.Tuple(4,[Sf.Atom"cons";Sf.Integerline;sf_head;sf_tail])->let%bindhead=sf_head|>expr_of_sf|>track~loc:[%here]inlet%bindtail=sf_tail|>expr_of_sf|>track~loc:[%here]inExprCons(line,head,tail)|>return(* a nil expression *)|Sf.Tuple(2,[Sf.Atom"nil";Sf.Integerline])->ExprNilline|>return(* a list comprehension *)|Sf.Tuple(4,[Sf.Atom"lc";Sf.Integerline;sf_e;Sf.Listsf_qualifiers])->let%binde=sf_e|>expr_of_sf|>track~loc:[%here]inlet%bindqualifiers=sf_qualifiers|>List.map~f:qualifier_of_sf|>Result.all|>track~loc:[%here]inExprListComprehension(line,e,qualifiers)|>return(* a local function reference *)|Sf.Tuple(3,[Sf.Atom"fun";Sf.Integerline;Sf.Tuple(3,[Sf.Atom"function";Sf.Atomname;Sf.Integerarity])])->ExprLocalFunRef(line,name,arity)|>return(* a remote function reference *)|Sf.Tuple(3,[Sf.Atom"fun";Sf.Integerline;Sf.Tuple(4,[Sf.Atom"function";sf_module_name;sf_function_name;sf_arity])])->let%bindmodule_name=sf_module_name|>atom_or_var_of_sf|>track~loc:[%here]inlet%bindfunction_name=sf_function_name|>atom_or_var_of_sf|>track~loc:[%here]inlet%bindarity=sf_arity|>integer_or_var_of_sf|>track~loc:[%here]inExprRemoteFunRef(line,module_name,function_name,arity)|>return(* a function expression *)|Sf.Tuple(3,[Sf.Atom"fun";Sf.Integerline;Sf.Tuple(2,[Sf.Atom"clauses";Sf.Listsf_clauses])])->let%bindclauses=sf_clauses|>List.map~f:(cls_of_sf~in_function:true)|>Result.all|>track~loc:[%here]inExprFun(line,None,clauses)|>return(* a named function expression *)|Sf.Tuple(4,[Sf.Atom"named_fun";Sf.Integerline;Sf.Atomname;Sf.Listsf_clauses])->let%bindclauses=sf_clauses|>List.map~f:(cls_of_sf~in_function:true)|>Result.all|>track~loc:[%here]inExprFun(line,Somename,clauses)|>return(* a function call (remote) *)|Sf.Tuple(4,[Sf.Atom"call";Sf.Integerline_c;Sf.Tuple(4,[Sf.Atom"remote";Sf.Integerline_r;sf_m;sf_f]);Sf.Listsf_args])->let%bindm=sf_m|>expr_of_sf|>track~loc:[%here]inlet%bindf=sf_f|>expr_of_sf|>track~loc:[%here]inlet%bindargs=sf_args|>List.map~f:expr_of_sf|>Result.all|>track~loc:[%here]inExprRemoteCall(line_c,line_r,m,f,args)|>return(* a function call (local) *)|Sf.Tuple(4,[Sf.Atom"call";Sf.Integerline;sf_e;Sf.Listsf_es])->let%binde=sf_e|>expr_of_sf|>track~loc:[%here]inlet%bindes=sf_es|>List.map~f:expr_of_sf|>Result.all|>track~loc:[%here]inExprLocalCall(line,e,es)|>return(* a map creation *)|Sf.Tuple(3,[Sf.Atom"map";Sf.Integerline;Sf.Listsf_assocs])->let%bindassocs=sf_assocs|>List.map~f:expr_assoc_of_sf|>Result.all|>track~loc:[%here]inExprMapCreation(line,assocs)|>return(* a map update *)|Sf.Tuple(4,[Sf.Atom"map";Sf.Integerline;sf_m;Sf.Listsf_assocs])->let%bindm=sf_m|>expr_of_sf|>track~loc:[%here]inlet%bindassocs=sf_assocs|>List.map~f:expr_assoc_of_sf|>Result.all|>track~loc:[%here]inExprMapUpdate(line,m,assocs)|>return(* match operator expression *)|Sf.Tuple(4,[Sf.Atom"match";Sf.Integerline;sf_pattern;sf_body])->let%bindpattern=sf_pattern|>pat_of_sf|>track~loc:[%here]inlet%bindbody=sf_body|>expr_of_sf|>track~loc:[%here]inExprMatch(line,pattern,body)|>return(* an operator expression binary *)|Sf.Tuple(5,[Sf.Atom"op";Sf.Integerline;Sf.Atomop;sf_p1;sf_p2])->let%bindp1=sf_p1|>expr_of_sf|>track~loc:[%here]inlet%bindp2=sf_p2|>expr_of_sf|>track~loc:[%here]inExprBinOp(line,op,p1,p2)|>return(* a tuple skeleton *)|Sf.Tuple(3,[Sf.Atom"tuple";Sf.Integerline;Sf.Listsf_es])->let%bindes=sf_es|>List.map~f:expr_of_sf|>Result.all|>track~loc:[%here]inExprTuple(line,es)|>return(* a variable *)|Sf.Tuple(3,[Sf.Atom"var";Sf.Integerline;Sf.Atomid])->ExprVar(line,id)|>return(* atomic literal *)|sf_v->let%bindv=sf_v|>lit_of_sf|>track~loc:[%here]inExprLitv|>returnandexpr_assoc_of_sfsf:(expr_assoc_t,err_t)Result.t=letopenResult.Let_syntaxinmatchsfwith(* an association *)|Sf.Tuple(4,[Sf.Atom"map_field_assoc";Sf.Integerline;sf_k;sf_v])->let%bindk=sf_k|>expr_of_sf|>track~loc:[%here]inlet%bindv=sf_v|>expr_of_sf|>track~loc:[%here]inExprAssoc(line,k,v)|>return(* an exact association *)|Sf.Tuple(4,[Sf.Atom"map_field_exact";Sf.Integerline;sf_k;sf_v])->let%bindk=sf_k|>expr_of_sf|>track~loc:[%here]inlet%bindv=sf_v|>expr_of_sf|>track~loc:[%here]inExprAssocExact(line,k,v)|>return|_->Err.create~loc:[%here](Err.Not_supported_absform("expr_assoc",sf))|>Result.failandqualifier_of_sfsf:(qualifier_t,err_t)Result.t=letopenResult.Let_syntaxinmatchsfwith(* generator qualifier *)|Sf.Tuple(4,[Sf.Atom"generate";Sf.Integerline;sf_pattern;sf_expr])->let%bindpattern=sf_pattern|>pat_of_sf|>track~loc:[%here]inlet%bindexpr=sf_expr|>expr_of_sf|>track~loc:[%here]inQualifierGenerator(line,pattern,expr)|>return(* filter qualifier *)|sf_filter->let%bindfilter=sf_filter|>expr_of_sf|>track~loc:[%here]inQualifierFilterfilter|>returnandatom_or_var_of_sfsf:(atom_or_var_t,err_t)Result.t=letopenResult.Let_syntaxinmatchsfwith(* atom *)|(Sf.Tuple(3,[(Sf.Atom"atom");(Sf.Integerline);(Sf.Atomatom)]))->AtomVarAtom(line,atom)|>return(* variable *)|(Sf.Tuple(3,[(Sf.Atom"var");(Sf.Integerline);(Sf.Atomvar)]))->AtomVarVar(line,var)|>return|_->Err.create~loc:[%here](Err.Not_supported_absform("atom_or_var",sf))|>Result.failandinteger_or_var_of_sfsf=letopenResult.Let_syntaxinmatchsfwith(* integer *)|(Sf.Tuple(3,[(Sf.Atom"integer");(Sf.Integerline);(Sf.Integerarity)]))->IntegerVarInteger(line,arity)|>return(* variable *)|(Sf.Tuple(3,[(Sf.Atom"var");(Sf.Integerline);(Sf.Atomvar)]))->IntegerVarVar(line,var)|>return|_->Err.create~loc:[%here](Err.Not_supported_absform("integer_or_var",sf))|>Result.fail(*
* 8.5 Clauses
*)andcls_of_sf?(in_function=false)sf:(clause_t,err_t)Result.t=letopenResult.Let_syntaxinmatchsf,in_functionwith(* case clause P -> B *)|Sf.Tuple(5,[Sf.Atom"clause";Sf.Integerline;Sf.List[sf_pattern];Sf.List[];sf_body]),false->let%bindpattern=sf_pattern|>pat_of_sf|>track~loc:[%here]inlet%bindbody=sf_body|>expr_of_sf|>track~loc:[%here]inClsCase(line,pattern,None,body)|>return(* case clause P -> B when Gs *)|Sf.Tuple(5,[Sf.Atom"clause";Sf.Integerline;Sf.List[sf_pattern];sf_guards;sf_body]),false->let%bindpattern=sf_pattern|>pat_of_sf|>track~loc:[%here]inlet%bindguards=sf_guards|>guard_sequence_of_sf|>track~loc:[%here]inlet%bindbody=sf_body|>expr_of_sf|>track~loc:[%here]inClsCase(line,pattern,Someguards,body)|>return(* function clause ( Ps ) -> B *)|Sf.Tuple(5,[Sf.Atom"clause";Sf.Integerline;Sf.Listsf_patterns;Sf.List[];sf_body]),true->let%bindpatterns=sf_patterns|>List.map~f:pat_of_sf|>Result.all|>track~loc:[%here]inlet%bindbody=sf_body|>expr_of_sf|>track~loc:[%here]inClsFun(line,patterns,None,body)|>return(* function clause ( Ps ) when Gs -> B *)|Sf.Tuple(5,[Sf.Atom"clause";Sf.Integerline;Sf.Listsf_patterns;sf_guards;sf_body]),true->let%bindpatterns=sf_patterns|>List.map~f:pat_of_sf|>Result.all|>track~loc:[%here]inlet%bindguards=sf_guards|>guard_sequence_of_sf|>track~loc:[%here]inlet%bindbody=sf_body|>expr_of_sf|>track~loc:[%here]inClsFun(line,patterns,Someguards,body)|>return|_->Err.create~loc:[%here](Err.Not_supported_absform("cls",sf))|>Result.fail(*
* 8.6 Guards
*)andguard_sequence_of_sfsf:(guard_sequence_t,err_t)Result.t=letopenResult.Let_syntaxinmatchsfwith(* empty or non-empty sequence *)|Sf.Listsf_forms->let%bindforms=sf_forms|>List.map~f:guard_of_sf|>Result.all|>track~loc:[%here]inGuardSeqforms|>return|_->Err.create~loc:[%here](Err.Not_supported_absform("guard_sequence",sf))|>Result.failandguard_of_sfsf:(guard_t,err_t)Result.t=letopenResult.Let_syntaxinmatchsfwith(* non-empty sequence *)|Sf.Listsf_formswhenList.lengthsf_forms>0->let%bindforms=sf_forms|>List.map~f:guard_test_of_sf|>Result.all|>track~loc:[%here]inGuardforms|>return|_->Err.create~loc:[%here](Err.Not_supported_absform("guard",sf))|>Result.failandguard_test_of_sfsf:(guard_test_t,err_t)Result.t=letopenResult.Let_syntaxinmatchsfwith(* function call *)|Sf.Tuple(4,[Sf.Atom"call";Sf.Integerline;sf_name;Sf.Listsf_args])->let%bindname=sf_name|>lit_of_sf|>track~loc:[%here]inlet%bindargs=sf_args|>List.map~f:guard_test_of_sf|>Result.all|>track~loc:[%here]inGuardTestCall(line,name,args)|>return(* a map creation *)|Sf.Tuple(3,[Sf.Atom"map";Sf.Integerline;Sf.Listsf_assocs])->let%bindassocs=sf_assocs|>List.map~f:guard_test_assoc_of_sf|>Result.all|>track~loc:[%here]inGuardTestMapCreation(line,assocs)|>return(* a map update *)|Sf.Tuple(4,[Sf.Atom"map";Sf.Integerline;sf_m;Sf.Listsf_assocs])->let%bindm=sf_m|>guard_test_of_sf|>track~loc:[%here]inlet%bindassocs=sf_assocs|>List.map~f:guard_test_assoc_of_sf|>Result.all|>track~loc:[%here]inGuardTestMapUpdate(line,m,assocs)|>return(* a binary operator *)|Sf.Tuple(5,[Sf.Atom"op";Sf.Integerline;Sf.Atomop;sf_gt1;sf_gt2])->let%bindgt1=sf_gt1|>guard_test_of_sf|>track~loc:[%here]inlet%bindgt2=sf_gt2|>guard_test_of_sf|>track~loc:[%here]inGuardTestBinOp(line,op,gt1,gt2)|>return(* a tuple skeleton *)|Sf.Tuple(3,[Sf.Atom"tuple";Sf.Integerline;Sf.Listsf_gts])->let%bindgts=sf_gts|>List.map~f:guard_test_of_sf|>Result.all|>track~loc:[%here]inGuardTestTuple(line,gts)|>return(* variable pattern *)|Sf.Tuple(3,[Sf.Atom"var";Sf.Integerline;Sf.Atomid])->GuardTestVar(line,id)|>return(* atomic literal *)|sf_v->let%bindv=sf_v|>lit_of_sf|>track~loc:[%here]inGuardTestLitv|>returnandguard_test_assoc_of_sfsf:(guard_test_assoc_t,err_t)Result.t=letopenResult.Let_syntaxinmatchsfwith(* an association *)|Sf.Tuple(4,[Sf.Atom"map_field_assoc";Sf.Integerline;sf_k;sf_v])->let%bindk=sf_k|>guard_test_of_sf|>track~loc:[%here]inlet%bindv=sf_v|>guard_test_of_sf|>track~loc:[%here]inGuardTestAssoc(line,k,v)|>return(* an exact association *)|Sf.Tuple(4,[Sf.Atom"map_field_exact";Sf.Integerline;sf_k;sf_v])->let%bindk=sf_k|>guard_test_of_sf|>track~loc:[%here]inlet%bindv=sf_v|>guard_test_of_sf|>track~loc:[%here]inGuardTestAssocExact(line,k,v)|>return|_->Err.create~loc:[%here](Err.Not_supported_absform("guard_test_assoc",sf))|>Result.fail(*
* 8.7 Types
*)andtype_of_sfsf:(type_t,err_t)Result.t=letopenResult.Let_syntaxinmatchsfwith(* annotated type *)|Sf.Tuple(3,[Sf.Atom"ann_type";Sf.Integerline;Sf.List[sf_a;sf_t]])->let%binda=sf_a|>type_of_sf|>track~loc:[%here]inlet%bindt=sf_t|>type_of_sf|>track~loc:[%here]inTyAnn(line,a,t)|>return(* bitstring type *)|Sf.Tuple(4,[Sf.Atom"type";Sf.Integerline;Sf.Atom"binary";Sf.List[sf_m;sf_n]])->let%bindm=sf_m|>type_of_sf|>track~loc:[%here]inlet%bindn=sf_n|>type_of_sf|>track~loc:[%here]inTyBitstring(line,m,n)|>return(* fun type (any) *)|Sf.Tuple(4,[Sf.Atom"type";Sf.Integerline;Sf.Atom"fun";Sf.List[]])->TyFunAny(line)|>return(* fun type (any arity) *)|Sf.Tuple(4,[Sf.Atom"type";Sf.Integerline;Sf.Atom"fun";Sf.List[Sf.Tuple(3,[Sf.Atom"type";Sf.Integerline_any;Sf.Atom"any";]);sf_t0]])->let%bindt0=sf_t0|>type_of_sf|>track~loc:[%here]inTyFunAnyArity(line,line_any,t0)|>return(* map type (any) *)|Sf.Tuple(4,[Sf.Atom"type";Sf.Integerline;Sf.Atom"map";Sf.Atom"any"])->TyAnyMapline|>return(* map type *)|Sf.Tuple(4,[Sf.Atom"type";Sf.Integerline;Sf.Atom"map";Sf.Listsf_assocs])->let%bindassocs=sf_assocs|>List.map~f:type_assoc_of_sf|>Result.all|>track~loc:[%here]inTyMap(line,assocs)|>return(* operator type for a binary operator *)|Sf.Tuple(5,[Sf.Atom"op";Sf.Integerline;Sf.Atomop;sf_t1;sf_t2])->let%bindt1=sf_t1|>type_of_sf|>track~loc:[%here]inlet%bindt2=sf_t2|>type_of_sf|>track~loc:[%here]inTyBinOp(line,t1,op,t2)|>return(* operator type for a unary operator *)|Sf.Tuple(4,[Sf.Atom"op";Sf.Integerline;Sf.Atomop;sf_t0])->let%bindt0=sf_t0|>type_of_sf|>track~loc:[%here]inTyUnaryOp(line,op,t0)|>return(* range type *)|Sf.Tuple(4,[Sf.Atom"type";Sf.Integerline;Sf.Atom"range";Sf.List[sf_l;sf_h]])->let%bindl=sf_l|>type_of_sf|>track~loc:[%here]inlet%bindh=sf_h|>type_of_sf|>track~loc:[%here]inTyRange(line,l,h)|>return(* tuple type (any) *)|Sf.Tuple(4,[Sf.Atom"type";Sf.Integerline;Sf.Atom"tuple";Sf.Atom"any"])->TyAnyTupleline|>return(* tuple type *)|Sf.Tuple(4,[Sf.Atom"type";Sf.Integerline;Sf.Atom"tuple";Sf.Listsf_tys])->let%bindtys=sf_tys|>List.map~f:type_of_sf|>Result.all|>track~loc:[%here]inTyTuple(line,tys)|>return(* union type *)|Sf.Tuple(4,[Sf.Atom"type";Sf.Integerline;Sf.Atom"union";Sf.Listsf_tys])->let%bindtys=sf_tys|>List.map~f:type_of_sf|>Result.all|>track~loc:[%here]inTyUnion(line,tys)|>return(* predefined (or built-in) type OR fun type *)|Sf.Tuple(4,[Sf.Atom"type";Sf.Integerline;Sf.Atomn;Sf.Listsf_args])->beginmatchfun_type_of_sfsfwith|Okfn->Okfn|_->let%bindargs=sf_args|>List.map~f:type_of_sf|>Result.all|>track~loc:[%here]inTyPredef(line,n,args)|>returnend(* type variable *)|Sf.Tuple(3,[Sf.Atom"var";Sf.Integerline;Sf.Atomid])->TyVar(line,id)|>return(* user defined type *)|Sf.Tuple(4,[Sf.Atom"user_type";Sf.Integerline;Sf.Atomn;Sf.Listsf_args])->let%bindargs=sf_args|>List.map~f:type_of_sf|>Result.all|>track~loc:[%here]inTyUser(line,n,args)|>return(* atomic literal *)|sf_v->let%bindv=sf_v|>lit_of_sf|>track~loc:[%here]inTyLitv|>returnandfun_type_of_sfsf:(type_t,err_t)Result.t=letopenResult.Let_syntaxinmatchsfwith(* constrained function type *)|Sf.Tuple(4,[Sf.Atom"type";Sf.Integerline;Sf.Atom"bounded_fun";Sf.List[sf_fun_ty;sf_cont]])->let%bindfun_ty=sf_fun_ty|>type_of_sf|>track~loc:[%here]inlet%bindcont=sf_cont|>type_fun_cont_of_sf|>track~loc:[%here]inTyContFun(line,fun_ty,cont)|>return(* function type *)|Sf.Tuple(4,[Sf.Atom"type";Sf.Integerline;Sf.Atom"fun";Sf.List[Sf.Tuple(4,[Sf.Atom"type";Sf.Integerparams_line;Sf.Atom"product";Sf.Listsf_params]);sf_ret]])->let%bindparams=sf_params|>List.map~f:type_of_sf|>Result.all|>track~loc:[%here]inlet%bindret=sf_ret|>type_of_sf|>track~loc:[%here]inTyFun(line,params_line,params,ret)|>return|_->Err.create~loc:[%here](Err.Not_supported_absform("fun_type",sf))|>Result.failandtype_fun_cont_of_sfsf:(type_func_cont_t,err_t)Result.t=letopenResult.Let_syntaxinmatchsfwith|Sf.Listsf_constraints->let%bindconstraints=sf_constraints|>List.map~f:type_fun_cont_of_sf|>Result.all|>track~loc:[%here]inTyContconstraints|>return|Sf.Tuple(4,[Sf.Atom"type";Sf.Integerline;Sf.Atom"constraint";Sf.List[sf_c;Sf.List[sf_v;sf_t]]])->let%bindc=sf_c|>type_fun_cont_of_sf|>track~loc:[%here]inlet%bindv=sf_v|>type_of_sf|>track~loc:[%here]inlet%bindt=sf_t|>type_of_sf|>track~loc:[%here]inTyContRel(line,c,v,t)|>return|Sf.Tuple(3,[Sf.Atom"atom";Sf.Integerline;Sf.Atom"is_subtype"])->TyContIsSubTypeline|>return|_->Err.create~loc:[%here](Err.Not_supported_absform("type_fun_cont",sf))|>Result.failandtype_assoc_of_sfsf:(type_assoc_t,err_t)Result.t=letopenResult.Let_syntaxinmatchsfwith(* an association *)|Sf.Tuple(4,[Sf.Atom"type";Sf.Integerline;Sf.Atom"map_field_assoc";Sf.List[sf_k;sf_v]])->let%bindk=sf_k|>type_of_sf|>track~loc:[%here]inlet%bindv=sf_v|>type_of_sf|>track~loc:[%here]inTyAssoc(line,k,v)|>return(* an exact association *)|Sf.Tuple(4,[Sf.Atom"type";Sf.Integerline;Sf.Atom"map_field_exact";Sf.List[sf_k;sf_v]])->let%bindk=sf_k|>type_of_sf|>track~loc:[%here]inlet%bindv=sf_v|>type_of_sf|>track~loc:[%here]inTyAssocExact(line,k,v)|>return|_->Err.create~loc:[%here](Err.Not_supported_absform("type_assoc",sf))|>Result.fail(**)letof_etfetf:(t,err_t)Result.t=etf|>Sf.of_etf|>of_sf