123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244(************************************************************************)(* * The Rocq Prover / The Rocq Development Team *)(* v * Copyright INRIA, CNRS and contributors *)(* <O___,, * (see version control and CREDITS file for authors & dates) *)(* \VV/ **************************************************************)(* // * This file is distributed under the terms of the *)(* * GNU Lesser General Public License Version 2.1 *)(* * (see LICENSE file for the text of the license) *)(************************************************************************)(*s Production of Scheme syntax. *)openPpopenCErrorsopenUtilopenNamesopenMinimlopenMlutilopenTableopenCommon(*s Scheme renaming issues. *)letkeywords=List.fold_right(funs->Id.Set.add(Id.of_strings))["define";"let";"lambda";"lambdas";"match";"apply";"car";"cdr";"error";"delay";"force";"_";"__"]Id.Set.emptyletpp_comments=str";; "++hs++fnl()letpp_header_comment=function|None->mt()|Somecom->pp_commentcom++fnl()++fnl()letpreamble__comment_usf=pp_header_commentcomment++str";; This extracted scheme code relies on some additional macros\n"++str";; available at http://www.pps.univ-paris-diderot.fr/~letouzey/scheme\n"++str"(load \"macros_extr.scm\")\n\n"++(ifusf.mldummythenstr"(define __ (lambda (_) __))\n\n"elsemt())letpr_idid=str@@String.map(func->ifc=='\''then'~'elsec)(Id.to_stringid)letparen=pp_partrueletpp_abstst=function|[]->assertfalse|[id]->paren(str"lambda "++paren(pr_idid)++spc()++st)|l->paren(str"lambdas "++paren(prlist_with_sepspcpr_idl)++spc()++st)letpp_applyst_=function|[]->st|[a]->hov2(paren(st++spc()++a))|args->hov2(paren(str"@ "++st++(prlist_strict(funx->spc()++x)args)))(*s The pretty-printer for Scheme syntax *)letpp_globaltablekr=ifis_inline_customrthenstr(find_customr)elsestr(Common.pp_globaltablekr)(*s Pretty-printing of expressions. *)letrecpp_exprtableenvargs=letapplyst=pp_applysttrueargsinfunction|MLreln->letid=get_db_namenenvinapply(pr_idid)|MLapp(f,args')->letstl=List.map(pp_exprtableenv[])args'inpp_exprtableenv(stl@args)f|MLlam_asa->letfl,a'=collect_lamsainletfl,env'=push_vars(List.mapid_of_mlidfl)envinapply(pp_abst(pp_exprtableenv'[]a')(List.revfl))|MLletin(id,a1,a2)->leti,env'=push_vars[id_of_mlidid]envinapply(hv0(hov2(paren(str"let "++paren(paren(pr_id(List.hdi)++spc()++pp_exprtableenv[]a1))++spc()++hov0(pp_exprtableenv'[]a2)))))|MLglobr->apply(pp_globaltableTermr)|MLcons(_,r,args')->assert(List.is_emptyargs);letst=str"`"++paren(pp_globaltableConsr++(ifList.is_emptyargs'thenmt()elsespc())++prlist_with_sepspc(pp_cons_argstableenv)args')inifis_coinductive(State.get_tabletable)rthenparen(str"delay "++st)elsest|MLtuple_->user_errPp.(str"Cannot handle tuples in Scheme yet.")|MLcase(_,_,pv)whennot(is_regular_matchpv)->user_errPp.(str"Cannot handle general patterns in Scheme yet.")|MLcase(_,t,pv)whenis_custom_matchpv->letmkfun(ids,_,e)=ifnot(List.is_emptyids)thennamed_lams(List.revids)eelsedummy_lams(ast_lift1e)1inapply(paren(hov2(str(find_custom_matchpv)++fnl()++prvect(funtr->pp_exprtableenv[](mkfuntr)++fnl())pv++pp_exprtableenv[]t)))|MLcase(typ,t,pv)->lete=ifnot(is_coinductive_type(State.get_tabletable)typ)thenpp_exprtableenv[]telseparen(str"force"++spc()++pp_exprtableenv[]t)inapply(v3(paren(str"match "++e++fnl()++pp_pattableenvpv)))|MLfix(i,ids,defs)->letids',env'=push_vars(List.rev(Array.to_listids))envinpp_fixtableenv'i(Array.of_list(List.revids'),defs)args|MLexns->(* An [MLexn] may be applied, but I don't really care. *)paren(str"error"++spc()++qss)|MLdummy_->str"__"(* An [MLdummy] may be applied, but I don't really care. *)|MLmagica->pp_exprtableenvargsa|MLaxioms->paren(str"error \"AXIOM TO BE REALIZED ("++strs++str")\"")|MLuint_->paren(str"Prelude.error \"EXTRACTION OF UINT NOT IMPLEMENTED\"")|MLfloat_->paren(str"Prelude.error \"EXTRACTION OF FLOAT NOT IMPLEMENTED\"")|MLstring_->paren(str"Prelude.error \"EXTRACTION OF STRING NOT IMPLEMENTED\"")|MLparray_->paren(str"Prelude.error \"EXTRACTION OF PARRAY NOT IMPLEMENTED\"")andpp_cons_argstableenv=function|MLcons(_,r,args)whenis_coinductive(State.get_tabletable)r->paren(pp_globaltableConsr++(ifList.is_emptyargsthenmt()elsespc())++prlist_with_sepspc(pp_cons_argstableenv)args)|e->str","++pp_exprtableenv[]eandpp_one_pattableenv(ids,p,t)=letr=matchpwith|Pusualr->r|Pcons(r,l)->r(* cf. the check [is_regular_match] above *)|_->assertfalseinletids,env'=push_vars(List.rev_mapid_of_mlidids)envinletargs=ifList.is_emptyidsthenmt()else(str" "++prlist_with_sepspcpr_id(List.revids))in(pp_globaltableConsr++args),(pp_exprtableenv'[]t)andpp_pattableenvpv=prvect_with_sepfnl(funx->lets1,s2=pp_one_pattableenvxinhov2(str"(("++s1++str")"++spc()++s2++str")"))pv(*s names of the functions ([ids]) are already pushed in [env],
and passed here just for convenience. *)andpp_fixtableenvj(ids,bl)args=paren(str"letrec "++(v0(paren(prvect_with_sepfnl(fun(fi,ti)->paren((pr_idfi)++spc()++(pp_exprtableenv[]ti)))(Array.map2(funidb->(id,b))idsbl))++fnl()++hov2(pp_apply(pr_id(ids.(j)))trueargs))))(*s Pretty-printing of a declaration. *)letpp_decltable=function|Dind_->mt()|Dtype_->mt()|Dfix(rv,defs,_)->letnames=Array.map(funr->ifis_inline_customrthenmt()elsepp_globaltableTermr)rvinprvecti(funir->letvoid=is_inline_customr||(not(is_customr)&&matchdefs.(i)withMLexn"UNUSED"->true|_->false)inifvoidthenmt()elsehov2(paren(str"define "++names.(i)++spc()++(ifis_customrthenstr(find_customr)elsepp_exprtable(empty_envtable())[]defs.(i)))++fnl())++fnl())rv|Dterm(r,a,_)->ifis_inline_customrthenmt()elsehov2(paren(str"define "++pp_globaltableTermr++spc()++(ifis_customrthenstr(find_customr)elsepp_exprtable(empty_envtable())[]a)))++fnl2()letrecpp_structure_elemtable=function|(l,SEdecld)->pp_decltabled|(l,SEmodulem)->pp_module_exprtablem.ml_mod_expr|(l,SEmodtypem)->mt()(* for the moment we simply discard module type *)andpp_module_exprtable=function|MEstruct(mp,sel)->prlist_strict(fune->pp_structure_elemtablee)sel|MEfunctor_->mt()(* for the moment we simply discard unapplied functors *)|MEident_|MEapply_->assertfalse(* should be expanded in extract_env *)letpp_structtable=letpp_sel(mp,sel)=State.with_visibilitytablemp[]beginfuntable->prlist_strict(fune->pp_structure_elemtablee)selendinprlist_strictpp_selletfile_namingstatemp=file_of_modfile(State.get_tablestate)mpletscheme_descr={keywords=keywords;file_suffix=".scm";file_naming=file_naming;preamble=preamble;pp_struct=pp_struct;sig_suffix=None;sig_preamble=(fun_____->mt());pp_sig=(fun__->mt());pp_decl=pp_decl;}