123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242(************************************************************************)(* * The Coq Proof Assistant / The Coq 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_globalkr=str(Common.pp_globalkr)(*s Pretty-printing of expressions. *)letrecpp_exprenvargs=letapplyst=pp_applysttrueargsinfunction|MLreln->letid=get_db_namenenvinapply(pr_idid)|MLapp(f,args')->letstl=List.map(pp_exprenv[])args'inpp_exprenv(stl@args)f|MLlam_asa->letfl,a'=collect_lamsainletfl,env'=push_vars(List.mapid_of_mlidfl)envinapply(pp_abst(pp_exprenv'[]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_exprenv[]a1))++spc()++hov0(pp_exprenv'[]a2)))))|MLglobr->apply(pp_globalTermr)|MLcons(_,r,args')->assert(List.is_emptyargs);letst=str"`"++paren(pp_globalConsr++(ifList.is_emptyargs'thenmt()elsespc())++prlist_with_sepspc(pp_cons_argsenv)args')inifis_coinductiverthenparen(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_exprenv[](mkfuntr)++fnl())pv++pp_exprenv[]t)))|MLcase(typ,t,pv)->lete=ifnot(is_coinductive_typetyp)thenpp_exprenv[]telseparen(str"force"++spc()++pp_exprenv[]t)inapply(v3(paren(str"match "++e++fnl()++pp_patenvpv)))|MLfix(i,ids,defs)->letids',env'=push_vars(List.rev(Array.to_listids))envinpp_fixenv'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_exprenvargsa|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_argsenv=function|MLcons(_,r,args)whenis_coinductiver->paren(pp_globalConsr++(ifList.is_emptyargsthenmt()elsespc())++prlist_with_sepspc(pp_cons_argsenv)args)|e->str","++pp_exprenv[]eandpp_one_patenv(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_globalConsr++args),(pp_exprenv'[]t)andpp_patenvpv=prvect_with_sepfnl(funx->lets1,s2=pp_one_patenvxinhov2(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_fixenvj(ids,bl)args=paren(str"letrec "++(v0(paren(prvect_with_sepfnl(fun(fi,ti)->paren((pr_idfi)++spc()++(pp_exprenv[]ti)))(Array.map2(funidb->(id,b))idsbl))++fnl()++hov2(pp_apply(pr_id(ids.(j)))trueargs))))(*s Pretty-printing of a declaration. *)letpp_decl=function|Dind_->mt()|Dtype_->mt()|Dfix(rv,defs,_)->letnames=Array.map(funr->ifis_inline_customrthenmt()elsepp_globalTermr)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_expr(empty_env())[]defs.(i)))++fnl())++fnl())rv|Dterm(r,a,_)->ifis_inline_customrthenmt()elsehov2(paren(str"define "++pp_globalTermr++spc()++(ifis_customrthenstr(find_customr)elsepp_expr(empty_env())[]a)))++fnl2()letrecpp_structure_elem=function|(l,SEdecld)->pp_decld|(l,SEmodulem)->pp_module_exprm.ml_mod_expr|(l,SEmodtypem)->mt()(* for the moment we simply discard module type *)andpp_module_expr=function|MEstruct(mp,sel)->prlist_strictpp_structure_elemsel|MEfunctor_->mt()(* for the moment we simply discard unapplied functors *)|MEident_|MEapply_->assertfalse(* should be expanded in extract_env *)letpp_struct=letpp_sel(mp,sel)=push_visiblemp[];letp=prlist_strictpp_structure_elemselinpop_visible();pinprlist_strictpp_selletscheme_descr={keywords=keywords;file_suffix=".scm";file_naming=file_of_modfile;preamble=preamble;pp_struct=pp_struct;sig_suffix=None;sig_preamble=(fun____->mt());pp_sig=(fun_->mt());pp_decl=pp_decl;}