123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384(* Yoann Padioleau
*
* Copyright (C) 2010, 2012 Facebook
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2.1 as published by the Free Software Foundation, with the
* special exception on linking described in file license.txt.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file
* license.txt for more details.
*)openCommon(*****************************************************************************)(* Prelude *)(*****************************************************************************)(*
* A Concrete Syntax Tree for OCaml.
*
*)(*****************************************************************************)(* The AST related types *)(*****************************************************************************)(* ------------------------------------------------------------------------- *)(* Token/info *)(* ------------------------------------------------------------------------- *)typetok=Parse_info.t(* a shortcut to annotate some information with token/position information *)and'awrap='a*tokand'aparen=tok*'a*tokand'abrace=tok*'a*tokand'abracket=tok*'a*tokand'acomma_list=('a,tok(* ',' *))Common.eitherlistand'aand_list=('a,tok(* 'and' *))Common.eitherlistand'astar_list=('a,tok(* '*' *))Common.eitherlist(* optional first | *)and'apipe_list=('a,tok(* '|' *))Common.eitherlist(* optional final ; *)and'asemicolon_list=('a,tok(* ';' *))Common.eitherlist(* with tarzan *)(* ------------------------------------------------------------------------- *)(* Names *)(* ------------------------------------------------------------------------- *)typename=Nameofstringwrap(* lower and uppernames aliases, just for clarity *)andlname=nameanduname=name(* with tarzan *)typelong_name=qualifier*nameandqualifier=(name*tok(*'.'*))list(* with tarzan *)(* ------------------------------------------------------------------------- *)(* Types *)(* ------------------------------------------------------------------------- *)typety=|TyNameoflong_name|TyVaroftok(* ' *)*name|TyTupleoftystar_list(* at least 2 *)|TyTuple2oftystar_listparen(* at least 1 *)|TyFunctionofty*tok(* -> *)*ty|TyAppofty_args*long_name(* todo? could be merged with TyName *)|TyTodoandty_args=|TyArg1ofty|TyArgMultioftycomma_listparen(* todo? | TyNoArg and merge TyName and TyApp ? *)(* ------------------------------------------------------------------------- *)(* Expressions *)(* ------------------------------------------------------------------------- *)andexpr=|Cofconstant|Loflong_name(* val_longident *)|Constr(*Algebric*)oflong_name(* constr_longident *)*exproption|Tupleofexprcomma_list|Listofexprsemicolon_listbracket(* can be empty; can not be singular as we use instead ParenExpr *)|Sequenceofseq_exprparen(* can also be 'begin'/'end' *)|Prefixofstringwrap*expr|Infixofexpr*stringwrap*expr|FunCallSimpleoflong_name*argumentlist|FunCallofexpr*argumentlist(* could be factorized with Prefix but it's not a usual prefix operator! *)|RefAccessoftok(* ! *)*expr|RefAssignofexpr*tok(* := *)*expr|FieldAccessofexpr*tok(* . *)*long_name|FieldAssignofexpr*tok(* . *)*long_name*tok(* <- *)*expr|Recordofrecord_exprbrace|Newoftok*long_name(* class_longident *)|ObjAccessofexpr*tok(* # *)*name|LetInoftok*rec_opt*let_bindingand_list*tok(* in *)*seq_expr|Funoftok*parameterlist(* at least one *)*match_action|Functionoftok*match_casepipe_list(* why they allow seq_expr ?? *)|Ifoftok*seq_expr*tok*expr*(tok*expr)option|Matchoftok*seq_expr*tok*match_casepipe_list|Tryoftok*seq_expr*tok*match_casepipe_list|Whileoftok*seq_expr*tok*seq_expr*tok|Foroftok*name*tok*seq_expr*for_direction*seq_expr*tok*seq_expr*tok|ParenExprofexprparen(* todo: LetOpenIn *)|ExprTodoandseq_expr=exprsemicolon_listandconstant=|Intofstringwrap|Floatofstringwrap|Charofstringwrap|Stringofstringwrapandrecord_expr=|RecordNormaloffield_and_exprsemicolon_list|RecordWithofexpr*tok(* "with" *)*field_and_exprsemicolon_listandfield_and_expr=|FieldExproflong_name*tok(* = *)*expr(* new 3.12 feature *)|FieldImplicitExproflong_nameandargument=|ArgExprofexpr|ArgLabelTildeofname(* todo: without the tilde and : ? *)*expr|ArgImplicitTildeExproftok*name(* apparently can do 'foo ?attr:1' *)|ArgLabelQuestionofname(* todo: without the tilde and : ? *)*expr|ArgImplicitQuestionExproftok*nameandmatch_case=pattern*match_actionandmatch_action=|Actionoftok(* -> *)*seq_expr|WhenActionoftok(* when *)*seq_expr*tok(* -> *)*seq_exprandfor_direction=|Tooftok|Downtooftokandrec_opt=tokoption(* ------------------------------------------------------------------------- *)(* Patterns *)(* ------------------------------------------------------------------------- *)andpattern=|PatVarofname|PatConstantofpattern_signed_constant|PatConstr(*Algebric*)oflong_name(* constr_longident *)*patternoption|PatConsInfixofpattern*tok(* :: *)*pattern|PatTupleofpatterncomma_list|PatListofpatternsemicolon_listbracket|PatUnderscoreoftok|PatRecordoffield_patternsemicolon_listbrace|PatAsofpattern*tok(* as *)*name(* ocaml disjunction patterns extension *)|PatDisjofpattern*tok(* | *)*pattern|PatTypedoftok(*'('*)*pattern*tok(*':'*)*ty*tok(*')'*)|ParenPatofpatternparen|PatTodo(* less? merge with expr, no need for too precise AST, remember ast_php.ml *)andpattern_signed_constant=|C2ofconstant(* actually only valid for the Int and Float case, not Char and String
* but don't want to introduce yet another intermediate type just for
* the Int and Float
*)|CMinusoftok*constant|CPlusoftok*constantandfield_pattern=|PatFieldoflong_name*tok(* = *)*pattern(* new 3.12 feature *)|PatImplicitFieldoflong_name(* ------------------------------------------------------------------------- *)(* Let binding (global/local/function definition) *)(* ------------------------------------------------------------------------- *)andlet_binding=|LetClassicoflet_def|LetPatternofpattern*tok(* = *)*seq_expr(* was called fun_binding in the grammar *)andlet_def={l_name:name;(* val_ident *)l_params:parameterlist;(* can be empty *)l_tok:tok;(* = *)l_body:seq_expr;(* todo: l_type: ty option *)}andparameter=|ParamPatofpattern|ParamTodoandlabeled_simple_pattern=unit(* ------------------------------------------------------------------------- *)(* Type declaration *)(* ------------------------------------------------------------------------- *)typetype_declaration=|TyAbstractofty_params*name|TyDefofty_params*name*tok(* = *)*type_def_kindandty_params=|TyNoParam|TyParam1ofty_parameter|TyParamMultiofty_parametercomma_listparenandty_parameter=tok(* ' *)*name(* a TyVar *)andtype_def_kind=|TyCoreofty(* or type *)|TyAlgebricofconstructor_declarationpipe_list(* and type *)|TyRecordoffield_declarationsemicolon_listbrace(* OR type: algebric data type *)andconstructor_declaration=name(* constr_ident *)*constructor_argumentsandconstructor_arguments=|NoConstrArg|Ofoftok*tystar_list(* AND type: record *)andfield_declaration={fld_mutable:tokoption;fld_name:name;fld_tok:tok;(* : *)fld_type:ty;(* poly_type ?? *)}(* ------------------------------------------------------------------------- *)(* Class *)(* ------------------------------------------------------------------------- *)(* ------------------------------------------------------------------------- *)(* Module *)(* ------------------------------------------------------------------------- *)typemodule_type=unit(* todo *)(* mutually recursive with item *)typemodule_expr=|ModuleNameoflong_name|ModuleStructoftok(* struct *)*itemlist*tok(* end *)|ModuleTodo(* ------------------------------------------------------------------------- *)(* Signature/Structure items *)(* ------------------------------------------------------------------------- *)(* could split in sig_item and struct_item but many constructions are
* valid in both contexts.
*)anditem=|Typeoftok*type_declarationand_list|Exceptionoftok*name*constructor_arguments|Externaloftok*name(* val_ident *)*tok(*:*)*ty*tok(* = *)*stringwraplist(* primitive declarations *)|Openoftok*long_name(* only in sig_item *)|Valoftok*name(* val_ident *)*tok(*:*)*ty(* only in struct_item *)|Letoftok*rec_opt*let_bindingand_list|Moduleoftok*uname*tok*module_expr|ItemTodooftoktypesig_item=itemtypestruct_item=item(* ------------------------------------------------------------------------- *)(* Toplevel phrases *)(* ------------------------------------------------------------------------- *)typetoplevel=|TopItemofitem(* should both be removed *)|TopSeqExprofseq_expr|ScScoftok(* ;; *)(* some ml files contain some #! or even #load directives *)|TopDirectiveoftoktypeprogram=toplevellist(* with tarzan *)(*****************************************************************************)(* Any *)(*****************************************************************************)typeany=|Tyofty|Exprofexpr|Patternofpattern|Itemofitem|Topleveloftoplevel|Programofprogram|TypeDeclarationoftype_declaration|TypeDefKindoftype_def_kind|FieldDeclarationoffield_declaration|MatchCaseofmatch_case|LetBindingoflet_binding|Constantofconstant|Argumentofargument|Bodyofseq_expr|Infooftok|InfoListoftoklist(* with tarzan *)(*****************************************************************************)(* Wrappers *)(*****************************************************************************)letstr_of_name(Name(s,_))=sletinfo_of_name(Name(_,info))=infoletuncommaxs=Common.map_filter(function|Lefte->Somee|Right_info->None)xsletunpipexs=uncommaxsletname_of_long_name(_,name)=nameletmodule_of_long_name(qu,_)=qu|>List.mapfst|>List.mapstr_of_name|>Common.join"."letmodule_infos_of_long_name(qu,_)=qu|>List.mapfst|>List.mapinfo_of_name