1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556(** {1 Services} *)(** A service is a feature provided by a plugin. A typical service
would be a function to build terms, or to traverse all sub-terms,
or to perform E-matching, etc.
A registry is used to list all services provided by plugins and make
them available to users of the library, or to other plugins.
*)(* we use ['a lazy_t] to tie the knot properly when services
mutually depend on one another *)moduleM=Het_mapmoduleKey=structtype'at={key:'aHet_map.Key.t;key_name:string;}let[@inline]makekey_name={key_name;key=M.Key.create()}let[@inline]namek=k.key_namelet[@inline]makeffmt=CCFormat.ksprintf~f:makefmtendtypeany=Any:'aKey.t*'a->any(** Existential wrapper around a service *)moduleRegistry=structtypet={tbl:M.Tbl.t;mutablelst:anylist;}letcreate()={tbl=M.Tbl.create~size:16();lst=[];}letregister(r:t)(key:'aKey.t)(v:'a):unit=ifM.Tbl.memr.tblkey.Key.keythen(Error.errorf"service `%s` already registered"key.Key.key_name;);Log.debugf5(funk->k"register service `%s`"key.Key.key_name);M.Tbl.addr.tblkey.Key.keyv;r.lst<-Any(key,v)::r.lstlet[@inline]find(r:t)k=M.Tbl.findr.tblk.Key.keylet[@inline]to_iter(r:t)=Iter.of_listr.lstlet[@inline]find_exnrk=matchfindrkwith|Somev->v|None->Error.errorf"could not find service `%s`"(Key.namek)end