123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529(*
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> *)(*
* AST for Fortran
*
* ast.ml
*
*)[%%prepare_logger]moduleBinding=Diffast_misc.BindingmoduleLayeredloc=Langs_common.LayeredlocmoduleAstloc=Langs_common.AstlocmoduleAst_base=Langs_common.Ast_baseopenPrintfopenCommonopenLabelsmoduleLoc=AstlocmoduleLLoc=LayeredlocmoduleI=PinfomoduleB=BindingmoduleBID=Binding.IDmoduleL=LabelmoduleC=Contexttypename=Label_common.nameclassnode?(lloc=LLoc.dummy)?(children=[])?(info=I.NoInfo)lab=object(self:'self)valmutablelloc=llocvalmutablelabel=(lab:L.t)valmutablechildren=(children:'selflist)valmutableinfo=infovalmutablebinding=B.NoBindingvalmutablebindings=[]methodbinding=bindingmethodset_bindingb=binding<-bmethodbindings=bindingsmethodadd_bindingb=ifnot(List.membbindings)thenbindings<-b::bindingsmethodlabel=labelmethodlloc=llocmethodloc=lloc#get_locmethodorig_loc=lloc#get_orig_locmethodchildren=childrenmethodinfo=infomethodset_infoi=info<-imethodadd_infoi=matchinfowith|I.NoInfo->info<-i|_->info<-I.mergeinfoimethodchildren_labels=List.map(funn->n,n#label)childrenmethodnchildren=List.lengthchildrenmethodset_llocl=lloc<-lmethodset_childrenc=children<-cmethodrelablab=label<-labmethodadd_children_lc=children<-c@childrenmethodadd_children_rc=children<-children@cmethodremove_rightmost_child=matchchildrenwith|[]->()|[_]->children<-[]|_->match(List.revchildren)with|_::t->children<-(List.revt)|_->assertfalsemethodremove_leftmost_child=match(List.revchildren)with|[]->()|[_]->children<-[]|_::t->children<-tmethodto_string=sprintf"<%s>%s%s%s%s"(L.to_stringlabel)(lloc#to_string?short:(Sometrue)())(matchinfowith|I.NoInfo->""|_->sprintf": <<%s>>"(I.to_stringinfo))(matchbindingwith|B.NoBinding->""|_->sprintf": %a"BID.ps(B.get_bidbinding))(matchbindingswith|[]->""|_->sprintf": %s"(String.concat";"(List.map(funb->sprintf"%a"BID.ps(B.get_bidb))bindings)))methodto_tag=L.to_taglabelmethodget_name=L.get_namelabelmethodhas_name=trylet_=self#get_nameintruewith_->falsemethodget_name_opt=L.get_name_optlabelmethodget_names=L.get_nameslabelmethodget_label=L.get_labellabelmethodget_var=L.get_varlabelmethodget_var_opt=L.get_var_optlabelmethodrelab_stmtlab=label<-L.relabstmtlabellabend(* of class Ast.node *)letnode_opt_to_name_opt=function|Somend->Somend#get_name|None->Noneletnode_list_to_name_listnds=Xlist.filter_map(funn->n#get_name_opt)ndsletdummy_node=newnodeL.DUMMYletis_dummy_nodend=nd#label=L.DUMMYletempty_node=newnodeL.EMPTYletlloc_of_locsloc0loc1=letlloc0=LLoc.of_locloc0inletlloc1=LLoc.of_locloc1inLLoc.mergelloc0lloc1letlloc_of_lexposspos0pos1=letloc0=Loc.of_lexpospos0inletloc1=Loc.of_lexpospos1inlloc_of_locsloc0loc1[%%capture_pathletmknode(*env*)_start_posend_pos?(info=I.NoInfo)labelchildren=[%debug_log"%s"(L.to_stringlabel)];letlloc=lloc_of_lexpossstart_posend_posinnewnode~lloc~children~infolabel]letmkleafenvstart_posend_pos?(info=I.NoInfo)label=mknodeenvstart_posend_pos~infolabel[][%%capture_pathletreloc(*env*)_start_posend_posnode=letlloc=lloc_of_lexpossstart_posend_posin[%debug_log"relocating %s: %s -> %s"(L.to_stringnode#label)(node#lloc#to_string?short:(Sometrue)())(lloc#to_string?short:(Sometrue)())];node#set_lloclloc]letmkstmtnodeenvstart_posend_pos?(info=I.NoInfo)labchildren=letlloc=lloc_of_lexpossstart_posend_posinletlabel=trylet(slab,_)=letloc=lloc#get_locinenv#find_label(loc.Loc.filename,loc.Loc.start_line)inL.mklabeledstmtslablabwithNot_found->L.mkstmtlabinletnd=newnode~lloc~children~infolabelin(*env#add_latest_stmt_node nd;*)ndletmkstmtleafenvstart_posend_pos?(info=I.NoInfo)lab=mkstmtnodeenvstart_posend_pos~infolab[]modulePartial=structtypespec={mutablelength:int;mutabletag:C.tag;}letspec_to_strings=sprintf"length=%d tag=%s"s.length(C.tag_to_strings.tag)letlength_of_specs=s.lengthlettag_of_specs=s.tagletmkspec?(length=0)?(tag=C.Tunknown)()={length=length;tag=tag;}typet=|Dummyofspec*nodelist|Programofspec*nodelist|ProgramUnitofspec*node|Spec_Execofspec*nodeoption*nodeoption|SpecificationPartofspec*nodelist|ExecutionPartofspec*nodelist|Subprogramsofspec*nodelist|InterfaceSpecofspec*nodelist|CaseBlockofspec*nodelist|AssignmentStmtofspec*node|TypeDeclarationStmtofspec*node|FunctionStmtofspec*node|Variableofspec*node|Exprofspec*node|Stmtsofspec*nodelist|DataStmtSetsofspec*nodelist|TypeSpecofspec*node|ActionStmtofspec*node|DerivedTypeDefPartofspec*nodelist|Onlysofspec*nodelist|TypeBoundProcPartofspec*nodelist|FunctionHeadofspec*nodelist|SubroutineHeadofspec*nodelist|SubroutineStmtHeadofspec*node|FunctionStmtHeadofspec*node|PuTailofspec*nodelistletto_string=function|Dummy(spec,_)->sprintf"Dummy(%s)"(spec_to_stringspec)|Program(spec,_)->sprintf"Program(%s)"(spec_to_stringspec)|ProgramUnit(spec,_)->sprintf"ProgramUnit(%s)"(spec_to_stringspec)|Spec_Exec(spec,_,_)->sprintf"Spec_Exec(%s)"(spec_to_stringspec)|SpecificationPart(spec,_)->sprintf"SpecificationPart(%s)"(spec_to_stringspec)|ExecutionPart(spec,_)->sprintf"ExecutionPart(%s)"(spec_to_stringspec)|Subprograms(spec,_)->sprintf"Subprograms(%s)"(spec_to_stringspec)|InterfaceSpec(spec,_)->sprintf"InterfaceSpec(%s)"(spec_to_stringspec)|CaseBlock(spec,_)->sprintf"CaseBlock(%s)"(spec_to_stringspec)|AssignmentStmt(spec,_)->sprintf"AssignmentStmt(%s)"(spec_to_stringspec)|TypeDeclarationStmt(spec,_)->sprintf"TypeDeclarationStmt(%s)"(spec_to_stringspec)|FunctionStmt(spec,_)->sprintf"FunctionStmt(%s)"(spec_to_stringspec)|Variable(spec,_)->sprintf"Variable(%s)"(spec_to_stringspec)|Expr(spec,_)->sprintf"Expr(%s)"(spec_to_stringspec)|Stmts(spec,_)->sprintf"Stmts(%s)"(spec_to_stringspec)|DataStmtSets(spec,_)->sprintf"DataStmtSets(%s)"(spec_to_stringspec)|TypeSpec(spec,_)->sprintf"TypeSpec(%s)"(spec_to_stringspec)|ActionStmt(spec,_)->sprintf"ActionStmt(%s)"(spec_to_stringspec)|DerivedTypeDefPart(spec,_)->sprintf"DerivedTypeDefPart(%s)"(spec_to_stringspec)|Onlys(spec,_)->sprintf"Onlys(%s)"(spec_to_stringspec)|TypeBoundProcPart(spec,_)->sprintf"TypeBoundProcPart(%s)"(spec_to_stringspec)|FunctionHead(spec,_)->sprintf"FunctionHead(%s)"(spec_to_stringspec)|FunctionStmtHead(spec,_)->sprintf"FunctionStmtHead(%s)"(spec_to_stringspec)|SubroutineHead(spec,_)->sprintf"SubroutineHead(%s)"(spec_to_stringspec)|SubroutineStmtHead(spec,_)->sprintf"SubroutineStmtHead(%s)"(spec_to_stringspec)|PuTail(spec,_)->sprintf"PuTail(%s)"(spec_to_stringspec)letget_spec=function|Dummy(spec,_)|Program(spec,_)|ProgramUnit(spec,_)|Spec_Exec(spec,_,_)|SpecificationPart(spec,_)|ExecutionPart(spec,_)|Subprograms(spec,_)|InterfaceSpec(spec,_)|CaseBlock(spec,_)|AssignmentStmt(spec,_)|TypeDeclarationStmt(spec,_)|FunctionStmt(spec,_)|Variable(spec,_)|Expr(spec,_)|Stmts(spec,_)|DataStmtSets(spec,_)|TypeSpec(spec,_)|ActionStmt(spec,_)|DerivedTypeDefPart(spec,_)|Onlys(spec,_)|TypeBoundProcPart(spec,_)|FunctionHead(spec,_)|FunctionStmtHead(spec,_)|SubroutineHead(spec,_)|SubroutineStmtHead(spec,_)|PuTail(spec,_)->specletset_lengthpn=(get_specp).length<-nletset_tagpt=(get_specp).tag<-tletmk_dummy?(length=0)nds=Dummy(mkspec~length(),nds)letmk_program?(length=0)nds=Program(mkspec~length~tag:C.Ttoplevel(),nds)letmk_program_unit?(length=0)nd=ProgramUnit(mkspec~length~tag:C.Tprogram_unit(),nd)letmk_spec_exec?(length=0)se=Spec_Exec(mkspec~length~tag:C.Tspec__exec(),s,e)letmk_specification_part?(length=0)nds=SpecificationPart(mkspec~length~tag:C.Tspecification_part(),nds)letmk_execution_part?(length=0)nds=ExecutionPart(mkspec~length~tag:C.Texecution_part(),nds)letmk_subprograms?(length=0)nds=Subprograms(mkspec~length~tag:C.Tsubprograms(),nds)letmk_interface_spec?(length=0)nds=InterfaceSpec(mkspec~length~tag:C.Tinterface_spec(),nds)letmk_case_block?(length=0)nds=CaseBlock(mkspec~length~tag:C.Tcase_block(),nds)letmk_assignment_stmt?(length=0)nd=AssignmentStmt(mkspec~length~tag:C.Tassignment_stmt(),nd)letmk_type_declaration_stmt?(length=0)nd=TypeDeclarationStmt(mkspec~length~tag:C.Ttype_declaration_stmt(),nd)letmk_function_stmt?(length=0)nd=FunctionStmt(mkspec~length~tag:C.Tfunction_stmt(),nd)letmk_variable?(length=0)nd=Variable(mkspec~length~tag:C.Tvariable(),nd)letmk_expr?(length=0)nd=Expr(mkspec~length~tag:C.Texpr(),nd)letmk_stmts?(length=0)nds=Stmts(mkspec~length~tag:C.Tstmts(),nds)letmk_data_stmt_sets?(length=0)nds=DataStmtSets(mkspec~length~tag:C.Tdata_stmt_sets(),nds)letmk_type_spec?(length=0)nd=TypeSpec(mkspec~length~tag:C.Ttype_spec(),nd)letmk_action_stmt?(length=0)nd=ActionStmt(mkspec~length~tag:C.Taction_stmt(),nd)letmk_derived_type_def_part?(length=0)nds=DerivedTypeDefPart(mkspec~length~tag:C.Tderived_type_def_part(),nds)letmk_onlys?(length=0)nds=Onlys(mkspec~length~tag:C.Tonlys(),nds)letmk_type_bound_proc_part?(length=0)nds=TypeBoundProcPart(mkspec~length~tag:C.Ttype_bound_proc_part(),nds)letmk_function_head?(length=0)nds=FunctionHead(mkspec~length~tag:C.Tfunction_head(),nds)letmk_function_stmt_head?(length=0)nd=FunctionStmtHead(mkspec~length~tag:C.Tfunction_stmt_head(),nd)letmk_subroutine_head?(length=0)nds=SubroutineHead(mkspec~length~tag:C.Tsubroutine_head(),nds)letmk_subroutine_stmt_head?(length=0)nd=SubroutineStmtHead(mkspec~length~tag:C.Tsubroutine_stmt_head(),nd)letmk_pu_tail?(length=0)nds=PuTail(mkspec~length~tag:C.Tpu_tail(),nds)letget_nodes=function|Dummy(_,nds)|Program(_,nds)|SpecificationPart(_,nds)|ExecutionPart(_,nds)|Subprograms(_,nds)|InterfaceSpec(_,nds)|CaseBlock(_,nds)|Stmts(_,nds)|DataStmtSets(_,nds)|DerivedTypeDefPart(_,nds)|Onlys(_,nds)|TypeBoundProcPart(_,nds)|FunctionHead(_,nds)|SubroutineHead(_,nds)|PuTail(_,nds)->nds|Spec_Exec(_,nd_opt1,nd_opt2)->(opt_to_listnd_opt1)@(opt_to_listnd_opt2)|ProgramUnit(_,nd)|AssignmentStmt(_,nd)|TypeDeclarationStmt(_,nd)|FunctionStmt(_,nd)|Variable(_,nd)|Expr(_,nd)|TypeSpec(_,nd)|ActionStmt(_,nd)|SubroutineStmtHead(_,nd)|FunctionStmtHead(_,nd)->[nd]end(* of module Ast.Partial *)letis_stmtnode=L.is_stmtnode#labelletis_constantnode=L.is_constantnode#labelletget_last_namenode_list=matchList.revnode_listwith|last::_->begintrylast#get_namewithNot_found->""end|_->""letposition_spec_to_inquire_specnd=beginmatchnd#labelwith|L.PositionSpecps->nd#relab(L.InquireSpec(PositionSpec.to_inquire_specps))|_->()end;ndletposition_spec_to_close_specnd=beginmatchnd#labelwith|L.PositionSpecps->nd#relab(L.CloseSpec(PositionSpec.to_close_specps))|_->()end;ndletposition_spec_to_io_control_specnd=beginmatchnd#labelwith|L.PositionSpecps->nd#relab(L.IoControlSpec(PositionSpec.to_io_control_specps))|_->()end;ndletposition_spec_to_wait_specnd=beginmatchnd#labelwith|L.PositionSpecps->nd#relab(L.WaitSpec(PositionSpec.to_wait_specps))|_->()end;ndletposition_spec_to_flush_specnd=beginmatchnd#labelwith|L.PositionSpecps->nd#relab(L.FlushSpec(PositionSpec.to_flush_specps))|_->()end;ndletclose_spec_to_connect_specnd=beginmatchnd#labelwith|L.CloseSpeccs->nd#relab(L.ConnectSpec(CloseSpec.to_connect_speccs))|_->()end;ndletlloc_of_nodes=function|[]->failwith"Ast.lloc_of_nodes"|[nd]->nd#lloc|nd::rest->LLoc.mergend#lloc(Xlist.lastrest)#lloc(* *)letrecvisitfnode=(* preorder traversal *)fnode;List.iter(visitf)node#childrenletrecvisit_post(f:node->unit)node=(* postorder traversal *)List.iter(visit_postf)node#children;fnodeletsizenode=letsz=ref0invisit(fun_->incrsz)node;!szclassc(root:node)=object(self)inheritAst_base.cmethodroot=rootmethodvisitf=visitfrootmethodvisit_postf=visit_postfrootmethodsize=sizerootmethodcount_ambiguous_nodes=letcount=ref0inself#visit(funnd->matchnd#labelwith|L.Ambiguous_->incrcount|_->());!countmethodcount_omp_error_nodes=letcount=ref0inself#visit(funnd->matchnd#labelwith|L.OmpDirective(OmpDirective.ERROR)->incrcount|_->());!countend(* of class Ast.c *)letspec_opt_exec_opt_to_list(sp_nd_opt,ep_nd_opt)=(opt_to_listsp_nd_opt)@(opt_to_listep_nd_opt)letspec_opt_exec_opt_to_children_pair(sp_nd_opt,ep_nd_opt)=letspecs=matchsp_nd_optwith|Somesp_nd->sp_nd#children|None->[]inletexecs=matchep_nd_optwith|Someep_nd->ep_nd#children|None->[]inspecs,execs(* end of Ast *)