123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256moduleValue=Runtime.ValueopenRuntime.Dynamic_Runner.SignaturemoduleMake_rec(Interface:INTERFACE)(MakeExtern:functor(Interp_AL:INTERP_AL)(Interp_SL:INTERP_SL)(Interp_PL:INTERP_PL)->EXTERN)(MakeInterp_AL:functor(Interface:INTERFACE)(Extern:EXTERN)()->INTERP_AL)(MakeInterp_SL:functor(Interface:INTERFACE)(Extern:EXTERN)()->INTERP_SL)(MakeInterp_PL:functor(Interface:INTERFACE)(Extern:EXTERN)()->INTERP_PL):RUNNER=structmoduleInterface=Interface(* Recursive instantiations *)modulerecExtern:EXTERN=structincludeMakeExtern(Interp_AL)(Interp_SL)(Interp_PL)endandInterp_AL:INTERP_AL=structincludeMakeInterp_AL(Interface)(Extern)()endandInterp_SL:INTERP_SL=structincludeMakeInterp_SL(Interface)(Extern)()endandInterp_PL:INTERP_PL=structincludeMakeInterp_PL(Interface)(Extern)()end(* Shared state *)letmode:moderef=refEmpty_modeletinit_mode(mode_:mode):unit=mode:=mode_(* Interpreter *)moduleInterp=structleteval_program(relname:string)(includes:stringlist)(path:string):program_result=match!modewith|AL_mode->Interp_AL.eval_programrelnameincludespath|SL_mode->Interp_SL.eval_programrelnameincludespath|PL_mode->Interp_PL.eval_programrelnameincludespath|Empty_mode->assertfalseleteval_rel(relname:string)(values:Value.tlist):rel_result=match!modewith|AL_mode->Interp_AL.eval_relrelnamevalues|SL_mode->Interp_SL.eval_relrelnamevalues|PL_mode->Interp_PL.eval_relrelnamevalues|Empty_mode->assertfalseleteval_func(funcname:string)(typs:Typ.tlist)(values:Value.tlist):func_result=match!modewith|AL_mode->Interp_AL.eval_funcfuncnametypsvalues|SL_mode->Interp_SL.eval_funcfuncnametypsvalues|PL_mode->Interp_PL.eval_funcfuncnametypsvalues|Empty_mode->assertfalse(* Cache management *)moduleCache=structletcache_on()=Interp_AL.Cache.cache_on();Interp_SL.Cache.cache_on();Interp_PL.Cache.cache_on()letcache_off()=Interp_AL.Cache.cache_off();Interp_SL.Cache.cache_off();Interp_PL.Cache.cache_off()end(* Clear the cache *)letclear():unit=Interp_AL.clear();Interp_SL.clear();Interp_PL.clear();Extern.clear()end(* Initialization *)letinit?(cache=true)?(det=false)?(guard=false)(spec_:spec):unit=Interface.initspec_;(matchspec_with|ALspec_al->init_modeAL_mode;Interp_AL.init~cache~det~guardspec_al|SLspec_sl->init_modeSL_mode;Interp_SL.init~cache~det~guardspec_sl|PLspec_pl->init_modePL_mode;Interp_PL.init~cache~det~guardspec_pl|Empty->assertfalse);Extern.init_mode!mode(* Cache management *)letclear():unit=Extern.clear();Interp.clear()moduleCache=structletcache_on()=Interp_AL.Cache.cache_on();Interp_SL.Cache.cache_on();Interp_PL.Cache.cache_on()letcache_off()=Interp_AL.Cache.cache_off();Interp_SL.Cache.cache_off();Interp_PL.Cache.cache_off()endend(* Variant for externs that do not depend on the interpreters.
Because there is no Extern↔Interp circular dependency, no module rec is needed. *)moduleMake_nonrec(Interface:INTERFACE)(MakeExtern:functor()->EXTERN)(MakeInterp_AL:functor(Interface:INTERFACE)(Extern:EXTERN)()->INTERP_AL)(MakeInterp_SL:functor(Interface:INTERFACE)(Extern:EXTERN)()->INTERP_SL)(MakeInterp_PL:functor(Interface:INTERFACE)(Extern:EXTERN)()->INTERP_PL):RUNNER=structmoduleInterface=Interface(* Sequential instantiations: Extern is independent of the interpreters *)moduleExtern:EXTERN=MakeExtern()moduleInterp_AL:INTERP_AL=MakeInterp_AL(Interface)(Extern)()moduleInterp_SL:INTERP_SL=MakeInterp_SL(Interface)(Extern)()moduleInterp_PL:INTERP_PL=MakeInterp_PL(Interface)(Extern)()(* Shared state *)letmode:moderef=refEmpty_modeletinit_mode(mode_:mode):unit=mode:=mode_(* Interpreter *)moduleInterp=structleteval_program(relname:string)(includes:stringlist)(path:string):program_result=match!modewith|AL_mode->Interp_AL.eval_programrelnameincludespath|SL_mode->Interp_SL.eval_programrelnameincludespath|PL_mode->Interp_PL.eval_programrelnameincludespath|Empty_mode->assertfalseleteval_rel(relname:string)(values:Value.tlist):rel_result=match!modewith|AL_mode->Interp_AL.eval_relrelnamevalues|SL_mode->Interp_SL.eval_relrelnamevalues|PL_mode->Interp_PL.eval_relrelnamevalues|Empty_mode->assertfalseleteval_func(funcname:string)(typs:Typ.tlist)(values:Value.tlist):func_result=match!modewith|AL_mode->Interp_AL.eval_funcfuncnametypsvalues|SL_mode->Interp_SL.eval_funcfuncnametypsvalues|PL_mode->Interp_PL.eval_funcfuncnametypsvalues|Empty_mode->assertfalse(* Cache management *)moduleCache=structletcache_on()=Interp_AL.Cache.cache_on();Interp_SL.Cache.cache_on();Interp_PL.Cache.cache_on()letcache_off()=Interp_AL.Cache.cache_off();Interp_SL.Cache.cache_off();Interp_PL.Cache.cache_off()end(* Clear the cache *)letclear():unit=Interp_AL.clear();Interp_SL.clear();Interp_PL.clear();Extern.clear()end(* Initialization *)letinit?(cache=true)?(det=false)?(guard=false)(spec_:spec):unit=Interface.initspec_;(matchspec_with|ALspec_al->init_modeAL_mode;Interp_AL.init~cache~det~guardspec_al|SLspec_sl->init_modeSL_mode;Interp_SL.init~cache~det~guardspec_sl|PLspec_pl->init_modePL_mode;Interp_PL.init~cache~det~guardspec_pl|Empty->assertfalse);Extern.init_mode!mode(* Cache management *)letclear():unit=Extern.clear();Interp.clear()moduleCache=structletcache_on()=Interp_AL.Cache.cache_on();Interp_SL.Cache.cache_on();Interp_PL.Cache.cache_on()letcache_off()=Interp_AL.Cache.cache_off();Interp_SL.Cache.cache_off();Interp_PL.Cache.cache_off()endend