123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604(*
* 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)
*)moduleSf=Simple_term_formatmoduleZ=Aux.Zletraise_unknown_errorformsf=failwith(Printf.sprintf"%s: unknown / %s"form(Sf.showsf))(* line number *)typeline_t=int[@@derivingshow](* 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=|PatMapofline_t*pattern_assoc_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|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|ExprBinOpofline_t*string*expr_t*expr_t|ExprVarofline_t*string|ExprLitofliteral_tandexpr_assoc_t=|ExprAssocofline_t*expr_t*expr_t|ExprAssocExactofline_t*expr_t*expr_tandclause_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|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|TyPredefofline_t*string*type_tlist|TyProductofline_t*type_tlist|TyVarofline_t*string|TyContFunofline_t*type_t*type_t|TyFunofline_t*type_t*type_t|TyContoftype_tlist|TyContRelofline_t*type_t*type_t*type_t|TyContIsSubTypeofline_t[@@derivingshow](*
* Entry
*)letrecof_sfsf=matchsfwith|Sf.Tuple(2,[Sf.Atom"raw_abstract_v1";forms])->AbstractCode(forms|>form_of_sf)(* is it suitable here? *)|Sf.Tuple(3,[Sf.Atom"debug_info_v1";Sf.Atom"erl_abstract_code";Sf.Tuple(2,[forms;_options])])->AbstractCode(forms|>form_of_sf)|_->raise_unknown_error"root"sf(*
* 8.1 Module Declarations and Forms
*)andform_of_sfsf=matchsfwith(* module declaration *)|Sf.Listforms->ModDecl(forms|>List.mapform_of_sf)(* attribute -export *)|Sf.Tuple(4,[Sf.Atom"attribute";Sf.Integerline;Sf.Atom"export";Sf.Listname_and_arity_list])->AttrExport(line,name_and_arity_list|>List.mapname_and_arity_of_sf)(* attribute -export_type *)|Sf.Tuple(4,[Sf.Atom"attribute";Sf.Integerline;Sf.Atom"export_type";Sf.Listname_and_arity_list])->AttrExportType(line,name_and_arity_list|>List.mapname_and_arity_of_sf)(* attribute -import *)|Sf.Tuple(4,[Sf.Atom"attribute";Sf.Integerline;Sf.Atom"import";Sf.Listname_and_arity_list])->AttrImport(line,name_and_arity_list|>List.mapname_and_arity_of_sf)(* attribute -module *)|Sf.Tuple(4,[Sf.Atom"attribute";Sf.Integerline;Sf.Atom"module";Sf.Atommodule_name])->AttrMod(line,module_name)(* 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)(* function declaration *)|Sf.Tuple(5,[Sf.Atom"function";Sf.Integerline;Sf.Atomname;Sf.Integerarity;Sf.Listf_clauses])->DeclFun(line,name,arity,f_clauses|>List.map(cls_of_sf~in_function:true))(* function specification *)|Sf.Tuple(4,[Sf.Atom"attribute";Sf.Integerline;Sf.Atom"spec";Sf.Tuple(2,[Sf.Tuple(2,[Sf.Atomname;Sf.Integerarity]);Sf.Listspecs])])->SpecFun(line,None,name,arity,specs|>List.mapfun_type_of_sf)(* 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.Listspecs])])->SpecFun(line,Somem,name,arity,specs|>List.mapfun_type_of_sf)(* record declaration *)|Sf.Tuple(4,[Sf.Atom"attribute";Sf.Integerline;Sf.Atom"record";Sf.Tuple(2,[Sf.Atomname;Sf.Listrecord_fields])])->DeclRecord(line,record_fields|>List.maprecord_field_of_sf)(* type declaration *)|Sf.Tuple(4,[Sf.Atom"attribute";Sf.Integerline;Sf.Atom"type";Sf.Tuple(3,[Sf.Atomname;t;Sf.Listtvars]);])->DeclType(line,name,tvars|>List.maptvar_of_sf,type_of_sft)(* opaque type declaration *)|Sf.Tuple(4,[Sf.Atom"attribute";Sf.Integerline;Sf.Atom"opaque";Sf.Tuple(3,[Sf.Atomname;t;Sf.Listtvars]);])->DeclOpaqueType(line,name,tvars|>List.maptvar_of_sf,type_of_sft)(* wild attribute *)|Sf.Tuple(4,[Sf.Atom"attribute";Sf.Integerline;Sf.Atomattr;term])->AttrWild(line,attr,term)(* eof *)|Sf.Tuple(2,[Sf.Atom"eof";Sf.Integerline])->FormEof|_->raise_unknown_error"form"sfandname_and_arity_of_sfsf=matchsfwith|Sf.Tuple(2,[Sf.Atomname;Sf.Integerarity])->(name,arity)|_->raise_unknown_error"name and arity"sfandrecord_field_of_sfsf=matchsfwith|Sf.Tuple(3,[Sf.Atom"record_field";Sf.Integerline;Sf.Tuple(3,[Sf.Atom"atom";_;Sf.Atomfield])])->(line,field,None,None)|Sf.Tuple(4,[Sf.Atom"record_field";Sf.Integerline;Sf.Tuple(3,[Sf.Atom"atom";_;Sf.Atomfield]);e])->(line,field,Some(expr_of_sfe),None)|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])]);t])->(line,field,None,Some(type_of_sft))|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]);e]);t])->(line,field,Some(expr_of_sfe),Some(type_of_sft))|_->raise_unknown_error"record_field"sfandtvar_of_sfsf=matchsfwith|Sf.Tuple(3,[Sf.Atom"var";Sf.Integerline;Sf.Atomtvar])->(line,tvar)|_->raise_unknown_error"type variable"sf(*
* 8.2 Atomic Literals
*)andlit_of_sfsf=matchsfwith|Sf.Tuple(3,[Sf.Atom"atom";Sf.Integerline;Sf.Atomv])->LitAtom(line,v)|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)|Sf.Tuple(3,[Sf.Atom"integer";Sf.Integerline;Sf.BigIntv])->LitBigInt(line,v)|Sf.Tuple(3,[Sf.Atom"string";Sf.Integerline;Sf.Stringv])->LitString(line,v)|_->raise_unknown_error"literal"sf(*
* 8.3 Patterns
*)andpat_of_sfsf=matchsfwith(* a map pattern *)|Sf.Tuple(3,[Sf.Atom"map";Sf.Integerline;Sf.Listassocs])->PatMap(line,assocs|>List.mappat_assoc_of_sf)(* a variable pattern *)|Sf.Tuple(3,[Sf.Atom"var";Sf.Integerline;Sf.Atom"_"])->PatUniversalline(* a variable pattern *)|Sf.Tuple(3,[Sf.Atom"var";Sf.Integerline;Sf.Atomid])->PatVar(line,id)(* atomic literal *)|v->PatLit(v|>lit_of_sf)andpat_assoc_of_sfsf=matchsfwith(* an exact association *)|Sf.Tuple(4,[Sf.Atom"map_field_exact";Sf.Integerline;k;v])->PatAssocExact(line,k|>pat_of_sf,v|>pat_of_sf)|_->raise_unknown_error"association"sf(*
* 8.4 Expressions
*)andexpr_of_sfsf=matchsfwith|Sf.Listes->ExprBody(es|>List.mapexpr_of_sf)(* a case expression *)|Sf.Tuple(4,[Sf.Atom"case";Sf.Integerline;e;Sf.Listclauses])->ExprCase(line,e|>expr_of_sf,clauses|>List.mapcls_of_sf)(* a function call (remote) *)|Sf.Tuple(4,[Sf.Atom"call";Sf.Integerline_c;Sf.Tuple(4,[Sf.Atom"remote";Sf.Integerline_r;m;f]);Sf.Listargs])->ExprRemoteCall(line_c,line_r,m|>expr_of_sf,f|>expr_of_sf,args|>List.mapexpr_of_sf)(* a function call (local) *)|Sf.Tuple(4,[Sf.Atom"call";Sf.Integerline;e;Sf.Listes])->ExprLocalCall(line,e|>expr_of_sf,es|>List.mapexpr_of_sf)(* a map creation *)|Sf.Tuple(3,[Sf.Atom"map";Sf.Integerline;Sf.Listassocs])->ExprMapCreation(line,assocs|>List.mapexpr_assoc_of_sf)(* a map update *)|Sf.Tuple(4,[Sf.Atom"map";Sf.Integerline;m;Sf.Listassocs])->ExprMapUpdate(line,m|>expr_of_sf,assocs|>List.mapexpr_assoc_of_sf)(* an operator expression binary *)|Sf.Tuple(5,[Sf.Atom"op";Sf.Integerline;Sf.Atomop;p1;p2])->ExprBinOp(line,op,p1|>expr_of_sf,p2|>expr_of_sf)(* a variable *)|Sf.Tuple(3,[Sf.Atom"var";Sf.Integerline;Sf.Atomid])->ExprVar(line,id)(* atomic literal *)|v->ExprLit(v|>lit_of_sf)andexpr_assoc_of_sfsf=matchsfwith(* an association *)|Sf.Tuple(4,[Sf.Atom"map_field_assoc";Sf.Integerline;k;v])->ExprAssoc(line,k|>expr_of_sf,v|>expr_of_sf)(* an exact association *)|Sf.Tuple(4,[Sf.Atom"map_field_exact";Sf.Integerline;k;v])->ExprAssocExact(line,k|>expr_of_sf,v|>expr_of_sf)|_->raise_unknown_error"association"sf(*
* 8.5 Clauses
*)andcls_of_sf?(in_function=false)sf=matchsf,in_functionwith(* case clause P -> B *)|Sf.Tuple(5,[Sf.Atom"clause";Sf.Integerline;Sf.List[pattern];Sf.List[];body]),false->ClsCase(line,pattern|>pat_of_sf,None,body|>expr_of_sf)(* case clause P -> B when Gs *)|Sf.Tuple(5,[Sf.Atom"clause";Sf.Integerline;Sf.List[pattern];guards;body]),false->ClsCase(line,pattern|>pat_of_sf,Some(guards|>guard_sequence_of_sf),body|>expr_of_sf)(* function clause ( Ps ) -> B *)|Sf.Tuple(5,[Sf.Atom"clause";Sf.Integerline;Sf.Listpatterns;Sf.List[];body]),true->ClsFun(line,patterns|>List.mappat_of_sf,None,body|>expr_of_sf)(* function clause ( Ps ) when Gs -> B *)|Sf.Tuple(5,[Sf.Atom"clause";Sf.Integerline;Sf.Listpatterns;guards;body]),true->ClsFun(line,patterns|>List.mappat_of_sf,Some(guards|>guard_sequence_of_sf),body|>expr_of_sf)|_->raise_unknown_error"cls"sf(*
* 8.6 Guards
*)andguard_sequence_of_sfsf=matchsfwith(* empty or non-empty sequence *)|Sf.Listforms->GuardSeq(forms|>List.mapguard_of_sf)|_->raise_unknown_error"guard_sequence"sfandguard_of_sfsf=matchsfwith(* non-empty sequence *)|Sf.ListformswhenList.lengthforms>0->Guard(forms|>List.mapguard_test_of_sf)|_->raise_unknown_error"guard"sfandguard_test_of_sfsf=matchsfwith(* function call *)|Sf.Tuple(4,[Sf.Atom"call";Sf.Integerline;name;Sf.Listargs])->GuardTestCall(line,name|>lit_of_sf,args|>List.mapguard_test_of_sf)(* a map creation *)|Sf.Tuple(3,[Sf.Atom"map";Sf.Integerline;Sf.Listassocs])->GuardTestMapCreation(line,assocs|>List.mapguard_test_assoc_of_sf)(* a map update *)|Sf.Tuple(4,[Sf.Atom"map";Sf.Integerline;m;Sf.Listassocs])->GuardTestMapUpdate(line,m|>guard_test_of_sf,assocs|>List.mapguard_test_assoc_of_sf)(* a binary operator *)|Sf.Tuple(5,[Sf.Atom"op";Sf.Integerline;Sf.Atomop;gt1;gt2])->GuardTestBinOp(line,op,gt1|>guard_test_of_sf,gt2|>guard_test_of_sf)(* variable pattern *)|Sf.Tuple(3,[Sf.Atom"var";Sf.Integerline;Sf.Atomid])->GuardTestVar(line,id)(* atomic literal *)|v->GuardTestLit(v|>lit_of_sf)andguard_test_assoc_of_sfsf=matchsfwith(* an association *)|Sf.Tuple(4,[Sf.Atom"map_field_assoc";Sf.Integerline;k;v])->GuardTestAssoc(line,k|>guard_test_of_sf,v|>guard_test_of_sf)(* an exact association *)|Sf.Tuple(4,[Sf.Atom"map_field_exact";Sf.Integerline;k;v])->GuardTestAssocExact(line,k|>guard_test_of_sf,v|>guard_test_of_sf)|_->raise_unknown_error"association"sf(*
* 8.7 Types
*)andtype_of_sfsf=matchsfwith(* annotated type *)|Sf.Tuple(3,[Sf.Atom"ann_type";Sf.Integerline;Sf.List[a;t]])->TyAnn(line,a|>type_of_sf,t|>type_of_sf)(* product type *)|Sf.Tuple(4,[Sf.Atom"type";Sf.Integerline;Sf.Atom"product";Sf.Listargs])->TyProduct(line,args|>List.maptype_of_sf)(* predefined (or built-in) type *)|Sf.Tuple(4,[Sf.Atom"type";Sf.Integerline;Sf.Atomn;Sf.Listargs])->TyPredef(line,n,args|>List.maptype_of_sf)(* type variable *)|Sf.Tuple(3,[Sf.Atom"var";Sf.Integerline;Sf.Atomid])->TyVar(line,id)|_->raise_unknown_error"type"sfandfun_type_of_sfsf=matchsfwith(* constrained function type *)|Sf.Tuple(4,[Sf.Atom"type";Sf.Integerline;Sf.Atom"bounded_fun";Sf.List[fun_ty;cont]])->TyContFun(line,fun_ty|>type_of_sf,cont|>cont_of_sf)(* function type *)|Sf.Tuple(4,[Sf.Atom"type";Sf.Integerline;Sf.Atom"fun";Sf.List[params;ret]])->TyFun(line,params|>type_of_sf,ret|>type_of_sf)|_->raise_unknown_error"fun_type"sfandcont_of_sfsf=matchsfwith|Sf.Listconstraints->TyCont(constraints|>List.mapcont_of_sf)|Sf.Tuple(4,[Sf.Atom"type";Sf.Integerline;Sf.Atom"constraint";Sf.List[c;Sf.List[v;t]]])->TyContRel(line,c|>cont_of_sf,v|>type_of_sf,t|>type_of_sf)|Sf.Tuple(3,[Sf.Atom"atom";Sf.Integerline;Sf.Atom"is_subtype"])->TyContIsSubTypeline|_->raise_unknown_error"cont_type"sf(**)letof_etfetf=etf|>Sf.of_etf|>of_sf