123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423(*
Copyright 2013-2018 RIKEN
Copyright 2018-2025 Chiba Institude of Technology
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*)(* Author: Masatomo Hashimoto <m.hashimoto@stair.center> *)(* context.ml *)[%%prepare_logger]moduleLoc=Langs_common.AstlocmodulePB=Langs_common.Parserlib_basetypetag=|Tunknown|Ttoplevel|Tprogram_unit|Tspec__exec|Tspecification_part|Texecution_part|Tsubprograms|Tinterface_spec|Tcase_block|Tassignment_stmt|Ttype_declaration_stmt|Tfunction_stmt|Tvariable|Texpr|Tstmts|Tdata_stmt_sets|Ttype_spec|Taction_stmt|Tderived_type_def_part|Tonlys|Ttype_bound_proc_part|Tfunction_head|Tfunction_stmt_head|Tsubroutine_head|Tsubroutine_stmt_head|Tpu_tail|Tin_stmtlettag_to_string=function|Tunknown->"unknown"|Ttoplevel->"toplevel"|Tprogram_unit->"program_unit"|Tspec__exec->"spec__exec"|Tspecification_part->"specification_part"|Texecution_part->"execution_part"|Tsubprograms->"subprograms"|Tinterface_spec->"interface_spec"|Tcase_block->"case_block"|Tassignment_stmt->"assignment_stmt"|Ttype_declaration_stmt->"type_declaration_stmt"|Tfunction_stmt->"function_stmt"|Tvariable->"variable"|Texpr->"expr"|Tstmts->"stmts"|Tdata_stmt_sets->"data_stmt_sets"|Ttype_spec->"type_spec"|Taction_stmt->"action_stmt"|Tderived_type_def_part->"derived_type_def_part"|Tonlys->"onlys"|Ttype_bound_proc_part->"type_bound_procedure_part"|Tfunction_head->"function_head"|Tfunction_stmt_head->"function_stmt_head"|Tsubroutine_head->"subroutine_head"|Tsubroutine_stmt_head->"subroutine_stmt_head"|Tpu_tail->"pu_tail"|Tin_stmt->"in_stmt"typet={mutabletag:tag;mutableis_active:bool;}letmktb={tag=t;is_active=b;}letcopy_contextc={tag=c.tag;is_active=c.is_active}letdeactivate_contextc=c.is_active<-falseletresolve_into_specc=c.tag<-Tspecification_partletresolve_into_execc=c.tag<-Texecution_partletto_string{tag=tag;is_active=is_active}=Printf.sprintf"%s[%sACTIVE]"(tag_to_stringtag)(ifis_activethen""else"IN")letunknown()=mkTunknownfalselettoplevel()=mkTtopleveltrueletprogram_unit()=mkTprogram_unittrueletspec__exec()=mkTspec__exectrueletspecification_part()=mkTspecification_parttrueletexecution_part()=mkTexecution_parttrueletsubprograms()=mkTsubprogramstrueletinterface_spec()=mkTinterface_spectrueletcase_block()=mkTcase_blocktrueletassignment_stmt()=mkTassignment_stmttruelettype_declaration_stmt()=mkTtype_declaration_stmttrueletfunction_stmt()=mkTfunction_stmttrueletvariable()=mkTvariabletrueletexpr()=mkTexprtrueletstmts()=mkTstmtstrueletdata_stmt_sets()=mkTdata_stmt_setstruelettype_spec()=mkTtype_spectrueletaction_stmt()=mkTaction_stmttrueletderived_type_def_part()=mkTderived_type_def_parttrueletonlys()=mkTonlystruelettype_bound_proc_part()=mkTtype_bound_proc_parttrueletfunction_head()=mkTfunction_headtrueletfunction_stmt_head()=mkTfunction_stmt_headtrueletsubroutine_head()=mkTsubroutine_headtrueletsubroutine_stmt_head()=mkTsubroutine_stmt_headtrueletpu_tail()=mkTpu_tailtrueletin_stmt()=mkTin_stmttrueletget_tag{tag=tag;is_active=_;}=tagletis_active{tag=_;is_active=b;}=bletset_tagctag=c.tag<-tagletis_unknownc=c.tag=Tunknownletis_toplevelc=c.tag=Ttoplevelletis_program_unitc=c.tag=Tprogram_unitletis_spec__execc=c.tag=Tspec__execletis_specification_partc=c.tag=Tspecification_partletis_execution_partc=c.tag=Texecution_partletis_subprogramsc=c.tag=Tsubprogramsletis_interface_specc=c.tag=Tinterface_specletis_case_blockc=c.tag=Tcase_blockletis_assignment_stmtc=c.tag=Tassignment_stmtletis_type_declaration_stmtc=c.tag=Ttype_declaration_stmtletis_function_stmtc=c.tag=Tfunction_stmtletis_variablec=c.tag=Tvariableletis_exprc=c.tag=Texprletis_stmtsc=c.tag=Tstmtsletis_data_stmt_setsc=c.tag=Tdata_stmt_setsletis_type_specc=c.tag=Ttype_specletis_action_stmtc=c.tag=Taction_stmtletis_derived_type_def_partc=c.tag=Tderived_type_def_partletis_onlysc=c.tag=Tonlysletis_type_bound_proc_partc=c.tag=Ttype_bound_proc_partletis_function_headc=c.tag=Tfunction_headletis_function_stmt_headc=c.tag=Tfunction_stmt_headletis_subroutine_headc=c.tag=Tsubroutine_headletis_subroutine_stmt_headc=c.tag=Tsubroutine_stmt_headletis_pu_tailc=c.tag=Tpu_tailletis_in_stmtc=c.tag=Tin_stmtletdummy=unknown()exceptionNot_activetypekey_t={k_level:int;k_loc:Loc.t;}letmkkeylvloc=letloc'=Loc.get_strippedlocin{k_level=lv;k_loc=loc';}letkey_to_string{k_level=lv;k_loc=loc;}=letloc_str=ifloc=Loc.dummytheniflv<0then"TEMP"else"TOP"elseLoc.to_stringlocinPrintf.sprintf"<%d:%s>"lvloc_strletmktopkeylv=mkkeylvLoc.dummylettempkey=mkkey(-1)Loc.dummy[%%capture_pathclassstackenv=object(self)valcheckpoint_tbl=Hashtbl.create0(* key_t -> t Stack.t *)valmutablestack:tStack.t=Stack.create()valmutablesuspended=falsevalpush_callback_stack:(t->unit)Stack.t=Stack.create()valpop_callback_stack:(t->unit)Stack.t=Stack.create()valactivate_callback_stack:(t->unit)Stack.t=Stack.create()valdeactivate_callback_stack:(t->unit)Stack.t=Stack.create()methodsize=Stack.lengthstackmethodregister_push_callbackf=Stack.pushfpush_callback_stackmethodregister_pop_callbackf=Stack.pushfpop_callback_stackmethodregister_activate_callbackf=Stack.pushfactivate_callback_stackmethodregister_deactivate_callbackf=Stack.pushfdeactivate_callback_stackmethodunregister_push_callback=(beginignore(Stack.poppush_callback_stack)end)[@warning"-5"]methodunregister_pop_callback=(beginignore(Stack.poppop_callback_stack)end)[@warning"-5"]methodunregister_activate_callback=(beginignore(Stack.popactivate_callback_stack)end)[@warning"-5"]methodunregister_deactivate_callback=(beginignore(Stack.popdeactivate_callback_stack)end)[@warning"-5"]methodclear=Stack.clearstackmethodtop=Stack.topstackmethodprivatecall_callbacksstkc=Stack.iter(funf->fc)stkmethodpush_callbackc=self#call_callbackspush_callback_stackcmethodpop_callbackc=self#call_callbackspop_callback_stackcmethodactivate_callbackc=self#call_callbacksactivate_callback_stackcmethoddeactivate_callbackc=self#call_callbacksdeactivate_callback_stackcmethodsuspended=suspendedmethodsuspend=[%debug_log"called"];suspended<-true;methodresume=[%debug_log"called"];suspended<-false;(*
method _force_pop n stack =
for i = 1 to n do
ignore (Stack.pop stack)
done
*)methodcheckpoint(key:key_t)=[%debug_log"key=%s\n%s"(key_to_stringkey)self#to_string];(*
if Hashtbl.mem checkpoint_tbl key then
[%debug_log "already checkpointed: key=%s" (key_to_string key)];
*)letcopy=self#_copy_stackstackinHashtbl.replacecheckpoint_tblkeycopymethodrecover?(remove=false)key=[%debug_log"key=%s\nBEFORE:\n%s"(key_to_stringkey)self#to_string];trystack<-self#_copy_stack(Hashtbl.findcheckpoint_tblkey);ifremovethenHashtbl.removecheckpoint_tblkey;[%debug_log"AFTER:\n%s"self#to_string];withNot_found->[%fatal_log"stack not found: key=%s"(key_to_stringkey)];raise(Common.Internal_error"Context.stack#recover")method_copy_stacks=letcopy=Stack.create()inletcs=ref[]inStack.iter(func->cs:=(copy_contextc)::!cs)s;List.iter(func->Stack.pushccopy)!cs;copymethodto_string=letbuf=Buffer.create0inStack.iter(func->Buffer.add_stringbuf(Printf.sprintf"%s\n"(to_stringc)))stack;Buffer.contentsbufmethodpushc=[%debug_log"pushing %s"(to_stringc)];[%debug_log"stack:\n%s"self#to_string];ifsuspendedthen[%debug_log"suspended"]elsebeginStack.pushcstack;self#push_callbackcend;env#set_context_enter_flag;()methodpop=[%debug_log"stack:\n%s"self#to_string];ifsuspendedthen[%debug_log"suspended"]elsebeginignore(Stack.popstack);letnew_top=tryStack.topstackwithStack.Empty->assertfalsein[%debug_log"(new top: %s)"(to_stringnew_top)];self#pop_callbacknew_topendmethodactivate_top=[%debug_log"suspended=%B"suspended];ifnotsuspendedthenbeginletc=self#topinifnotc.is_activethen[%debug_log"%s"(to_stringc)];c.is_active<-trueend;env#set_context_activate_flag;()methodactivate_top_no_delay=[%debug_log"suspended=%B"suspended];ifnotsuspendedthenbeginletc=self#topinifnotc.is_activethen[%debug_log"%s"(to_stringc)];c.is_active<-true;self#activate_callbackcendmethoddeactivate_top=[%debug_log"suspended=%B"suspended];ifnotsuspendedthenbeginletc=self#topinifc.is_activethen[%debug_log"%s"(to_stringc)];c.is_active<-falseendmethoddeactivate_top_no_delay=[%debug_log"suspended=%B"suspended];ifnotsuspendedthenbeginletc=self#topinifc.is_activethen[%debug_log"%s"(to_stringc)];c.is_active<-false;self#deactivate_callbackcendmethodtop_is_active=letc=self#topinc.is_activemethodtop_is_unknown=letc=self#topinis_unknowncmethodreset=self#clear;Hashtbl.clearcheckpoint_tbl;self#push(toplevel());self#push(program_unit())initializerself#resetend(* of class Context.stack *)]