123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183(*
* Copyright (c) 2014 Jeremy Yallop.
*
* This file is distributed under the terms of the MIT License.
* See the file LICENSE for details.
*)(* C pretty printing. *)[@@@warning"-9-27"]openCtypes_staticopenCstubs_c_languageopenFormatletformat_seqlbrfmt_itemseprbrfmtitems=letopenFormatinfprintffmt"%s@[@["lbr;ListLabels.iteriitems~f:(funiitem->ifi<>0thenfprintffmt"@]%s@ @["sep;fmt_itemfmtitem);fprintffmt"@]%s@]"rbrletformat_tyfmt(Tyty)=Ctypes.format_typfmttyletcvar_name=function|`Local(name,_)|`Global{name}->nameletcvarfmtv=fprintffmt"%s"(cvar_namev)letcconstfmt(`Inti)=fprintffmt"%s"(Signed.SInt.to_stringi)letreccamlxParamfmtargs=matchargswith[]->()|x1::[]->fprintffmt"@[CAMLxparam1@;(%s)@];"x1|x1::x2::[]->fprintffmt"@[CAMLxparam2@;(%s,@;%s)@];"x1x2|x1::x2::x3::[]->fprintffmt"@[CAMLxparam3@;(%s,@;%s,@;%s)@];"x1x2x3|x1::x2::x3::x4::[]->fprintffmt"@[CAMLxparam4@;(%s,@;%s,@;%s,@;%s)@];"x1x2x3x4|x1::x2::x3::x4::x5::rest->fprintffmt"@[CAMLxparam5@;(%s,@;%s,@;%s,@;%s,@;%s)@];"x1x2x3x4x5;camlxParamfmtrestletcamlParamfmtargs=matchargswith[]->fprintffmt"@[CAMLparam0@;()@];"|x1::[]->fprintffmt"@[CAMLparam1@;(%s)@];"x1|x1::x2::[]->fprintffmt"@[CAMLparam2@;(%s,@;%s)@];"x1x2|x1::x2::x3::[]->fprintffmt"@[CAMLparam3@;(%s,@;%s,@;%s)@];"x1x2x3|x1::x2::x3::x4::[]->fprintffmt"@[CAMLparam4@;(%s,@;%s,@;%s,@;%s)@];"x1x2x3x4|x1::x2::x3::x4::x5::rest->fprintffmt"@[CAMLparam5@;(%s,@;%s,@;%s,@;%s,@;%s)@];@ %a"x1x2x3x4x5camlxParamrest(* Determine whether the C expression [(ty)e] is equivalent to [e] *)letcast_unnecessary:ty->cexp->bool=letrecharmlesslr=matchl,rwith|Ty(PointerVoid),Ty(Pointer_)->true|Ty(View{ty}),t->harmless(Tyty)t|t,Ty(View{ty})->harmlesst(Tyty)|(Ty(Primitive_)asl),(Ty(Primitive_)asr)->l=r|_->falseinfuntye->harmlessty(Type_C.cexpe)letreccexpfmt:cexp->unit=function|#cconstasc->cconstfmtc|`Local_asx->cvarfmtx|`Cast(ty,e)whencast_unnecessarytye->cexpfmte|`Cast(ty,e)->fprintffmt"@[@[(%a)@]%a@]"format_tytycexpe|`Addr(`Global{name})|`Addr(`Local(name,_))->fprintffmt"@[&@[%s@]@]"nameletrecclvaluefmt:clvalue->unit=function|#cvarasx->cvarfmtx|`Index(lv,i)->fprintffmt"@[@[%a@]@[[%a]@]@]"clvaluelvcexpi|`Field(lv,f)->fprintffmt"@[@[%a@]@[.%s@]@]"clvaluelvf|`PointerField(lv,f)->fprintffmt"@[@[%a@]@[->%s@]@]"clvaluelvfletcamlopfmt:camlop->unit=function|`CAMLparam0->Format.fprintffmt"CAMLparam0()"|`CAMLlocalN(e,c)->Format.fprintffmt"CAMLlocalN(@[%a@],@ @[%a@])"cexpecexpc|`CAMLdrop->Format.fprintffmt"CAMLdrop"letreccefffmt:ceff->unit=function|#cexpase->cexpfmte|#camlopaso->camlopfmto|`Global_asx->cvarfmtx|`App({fname},es)->fprintffmt"@[%s(@["fname;letlast_exp=List.lengthes-1inList.iteri(funie->fprintffmt"@[%a@]%(%)"cexpe(ifi<>last_expthen",@ "else"":(_,_,_)format))es;fprintffmt")@]@]";|`Index(e,i)->fprintffmt"@[@[%a@]@[[%a]@]@]"ceffecexpi|`Derefe->fprintffmt"@[*@[%a@]@]"cexpe|`DerefField(e,f)->fprintffmt"@[@[%a@]->%s@]"cexpefletrecccompfmt:ccomp->unit=function|#cexpasewhenType_C.cexpe=TyVoid->fprintffmt"@[return@];"|#cexpase->fprintffmt"@[<2>return@;@[%a@]@];"cexpe|#ceffase->fprintffmt"@[<2>return@;@[%a@]@];"ceffe|`CAMLparam(xs,c)->fprintffmt"@[%a;@]@ %a"camlParamxsccompc|`Return(TyVoid,_)->fprintffmt"@[return@];"|`Return(Tyty,e)->fprintffmt"@[<2>return@;@[%a@]@];"cexpe|`CAMLreturnT(TyVoid,_)->fprintffmt"@[CAMLreturn0@];"|`CAMLreturnT(Tyty,e)->fprintffmt"@[<2>CAMLreturnT(@[%a@],@;@[%a@])@];"(funt->Ctypes.format_typt)tycexpe|`Let(xe,`Cast(ty,(#cexpase')))whencast_unnecessarytye'->ccompfmt(`Let(xe,e'))|`Let((`Local(x,_),e),`Local(y,_))whenx=y->ccompfmt(e:>ccomp)|`Let((`Local(name,TyVoid),e),s)->fprintffmt"@[%a;@]@ %a"ceffeccomps|`Let((`Local(name,Ty(Struct{tag})),e),s)->fprintffmt"@[struct@;%s@;%s@;=@;@[%a;@]@]@ %a"tagnameceffeccomps|`Let((`Local(name,Ty(Union{utag})),e),s)->fprintffmt"@[union@;%s@;%s@;=@;@[%a;@]@]@ %a"utagnameceffeccomps|`Let((`Local(name,Tyty),e),s)->fprintffmt"@[@[%a@]@;=@;@[%a;@]@]@ %a"(Ctypes.format_typ~name)tyceffeccomps|`LetConst(`Local(x,_),`Intc,s)->fprintffmt"@[enum@ {@[@ %s@ =@ %s@ };@]@]@ %a"x(Signed.SInt.to_stringc)ccomps|`LetAssign(lv,e,c)->fprintffmt"@[@[%a@]@;=@;@[%a@];@]@ %a"clvaluelvceffeccompcletformat_parameter_listparameterskfmt=letformat_argfmt(name,Tyt)=Ctypes_type_printing.format_typ~namefmttinmatchparameterswith|[]->Format.fprintffmt"%t(void)"k|[(_,TyVoid)]->Format.fprintffmt"@[%t@[(void)@]@]"k|_->Format.fprintffmt"@[%t@[%a@]@]"k(format_seq"("format_arg","")")parametersletcfundec:Format.formatter->cfundec->unit=funfmt(`Fundec(name,args,Tyreturn))->Ctypes_type_printing.format_typ'return(funcontextfmt->format_parameter_listargs(Ctypes_type_printing.format_name~name)fmt)`nonarrayfmtletstorage_classfmt=function`Static->fprintffmt"static@\n"|`Extern->()letcfundeffmt(`Function(dec,body,sc):cfundef)=storage_classfmtsc;fprintffmt"%a@\n{@[<v 2>@\n%a@]@\n}@\n"cfundecdecccompbody