123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601(*****************************************************************************
Liquidsoap, a programmable stream generator.
Copyright 2003-2024 Savonet team
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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
GNU General Public License for more details, fully stated in the COPYING
file at the root of the liquidsoap distribution.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************)openLiquidsoap_langopenParsed_termletjson_of_position{Lexing.pos_fname;pos_lnum;pos_bol;pos_cnum}:Json.t=`Assoc[("fname",`Stringpos_fname);("lnum",`Intpos_lnum);("bol",`Intpos_bol);("cnum",`Intpos_cnum);]letjson_of_positions(p,p')=`Tuple[json_of_positionp;json_of_positionp']letjson_of_if_def~to_json{if_def_negative;if_def_condition;if_def_then;if_def_else}=[("negative",`Boolif_def_negative);("condition",`Stringif_def_condition);("then",to_jsonif_def_then);("else",matchif_def_elsewithNone->`Null|Somet->to_jsont);]letjson_of_if_encoder~to_json{if_encoder_negative;if_encoder_condition;if_encoder_then;if_encoder_else;}=[("negative",`Boolif_encoder_negative);("condition",`Stringif_encoder_condition);("then",to_jsonif_encoder_then);("else",matchif_encoder_elsewithNone->`Null|Somet->to_jsont);]letjson_of_if_version~to_json{if_version_op;if_version_version;if_version_then;if_version_else}=[("opt",`String(matchif_version_opwith|`Eq->"=="|`Geq->">="|`Leq->"<="|`Gt->">"|`Lt->"<"));("version",`String(Lang_string.Version.to_stringif_version_version));("then",to_jsonif_version_then);("else",matchif_version_elsewithNone->`Null|Somet->to_jsont);]letjson_of_while~to_json{while_condition;while_loop}=[("condition",to_jsonwhile_condition);("loop",to_jsonwhile_loop)]letjson_of_for~to_json{for_variable;for_from;for_to;for_loop}=[("variable",`Stringfor_variable);("from",to_jsonfor_from);("to",to_jsonfor_to);("loop",to_jsonfor_loop);]letjson_of_iterable_for~to_json{iterable_for_variable;iterable_for_iterator;iterable_for_loop}=[("variable",`Stringiterable_for_variable);("iterator",to_jsoniterable_for_iterator);("loop",to_jsoniterable_for_loop);]letjson_of_try~to_json{try_body;try_variable;try_errors_list;try_handler;try_finally}=[("body",to_jsontry_body);("variable",`Stringtry_variable);("errors_list",matchtry_errors_listwithNone->`Null|Sometm->to_jsontm);("handler",matchtry_handlerwithNone->`Null|Sometm->to_jsontm);("finally",matchtry_finallywithNone->`Null|Sometm->to_jsontm);]lettype_node~typ?(extra=[])value=`Assoc([("type",`String"type_annotation");("subtype",`Stringtyp);("value",value);]@extra)letast_node~typvalue=("type",`Stringtyp)::valueletjson_of_annotated_string=function|`Verbatims->ast_node~typ:"var"[("value",`Strings)]|`String(_,(sep,s))->ast_node~typ:"ground"[("value",`String(Printf.sprintf"%c%s%c"sepssep))]letrecjson_of_type_annotation=function|`Namedn->type_node~typ:"named"(`Stringn)|`Nullablet->type_node~typ:"nullable"(json_of_type_annotationt)|`Listt->type_node~typ:"list"(json_of_type_annotationt)|`Json_objectt->type_node~typ:"json_object"(json_of_type_annotationt)|`Tuplel->type_node~typ:"tuple"(`Tuple(List.mapjson_of_type_annotationl))|`Arrow(args,t)->type_node~typ:"arrow"~extra:[("args",`Tuple(List.mapjson_of_type_fun_argargs))](json_of_type_annotationt)|`Recordl->type_node~typ:"record"(`Tuple(List.mapjson_of_meth_annotationl))|`Method(t,l)->type_node~typ:"method"~extra:[("base",json_of_type_annotationt)](`Tuple(List.mapjson_of_meth_annotationl))|`Invoke(t,s)->type_node~typ:"invoke"~extra:[("method",`Strings)](json_of_type_annotationt)|`Source(n,t)->type_node~typ:"source"~extra:[("base",`Stringn)](json_of_source_annotationt)andjson_of_type_fun_arg(b,s,t)=type_node~typ:"fun_arg"~extra:[("optional",`Boolb);("label",`Strings)](json_of_type_annotationt)andjson_of_meth_annotation{optional;name;typ;json_name}=type_node~typ:"method_annotation"~extra:[("optional",`Booloptional);("name",`Stringname);("json_name",matchjson_namewithNone->`Null|Somen->`Stringn);](json_of_type_annotationtyp)andjson_of_source_annotation{extensible;tracks}=type_node~typ:"source_annotation"~extra:[("extensible",`Boolextensible)](`Tuple(List.mapjson_of_source_track_annotationtracks))andjson_of_source_track_annotation{track_name;track_type;track_params}=type_node~typ:"source_track_annotation"~extra:[("name",`Stringtrack_name);("params",`Tuple(List.map(fun(l,v)->`Assoc(ast_node~typ:"app_arg"[("label",`Stringl);("value",`Assoc(json_of_annotated_stringv));]))track_params));](`Stringtrack_type)letjson_of_if~to_json{if_condition;if_then;if_elsif;if_else}=[("condition",to_jsonif_condition);("then",to_jsonif_then);("elsif",`Tuple(List.map(fun(t,t')->`Assoc(ast_node~typ:"elsif"[("condition",to_jsont);("then",to_jsont')]))if_elsif));("else",matchif_elsewithNone->`Null|Someif_else->to_jsonif_else);]letrecbase_json_of_pat=function|`PVarl->ast_node~typ:"pvar"[("value",`Tuple(List.map(funv->`Stringv)l))]|`PTuplel->ast_node~typ:"ptuple"[("value",`Tuple(List.mapjson_of_patl))]|`PList(l,v,l')->ast_node~typ:"plist"[("left",`Tuple(List.mapjson_of_patl));("middle",matchvwithNone->`Null|Some(_,s)->`Strings);("right",`Tuple(List.mapjson_of_patl'));]|`PMeth(ellipsis,methods)->ast_node~typ:"pmeth"[("value",`Tuple(List.map(function|var,`None->`Assoc(ast_node~typ:"var"[("value",`Stringvar)])|var,`Nullable->`Assoc(ast_node~typ:"var"[("value",`String(var^"?"))])|var,`Patternpat->`Assoc(ast_node~typ:"infix"[("left",`Assoc(ast_node~typ:"var"[("value",`Stringvar)]));("op",`String"=");("right",json_of_patpat);]))methods@matchellipsiswith|None->[]|Somepat->[`Assoc(ast_node~typ:"ellipsis"[("value",json_of_patpat)]);]));]andjson_of_patp=`Assoc(base_json_of_patp.pat_entry)letjson_of_of{only;except;source}=[("only",`Tuple(List.map(funs->`Strings)only));("except",`Tuple(List.map(funs->`Strings)except));("source",`Stringsource);]letjson_of_fun_arg~to_json:Parsed_term.fun_arg->(string*Json.t)list=function|`Argsof_of->ast_node~typ:"argsof"(json_of_of_of)|`Term{Term_base.label;as_variable;typ;default}->ast_node~typ:"term"[("value",`Assoc(ast_node~typ:"fun_arg"[("label",`Stringlabel);("as_variable",matchas_variablewith|None->`Null|Somev->`Stringv);("typ",matchtypwith|None->`Null|Sometyp->json_of_type_annotationtyp);("default",matchdefaultwithNone->`Null|Somed->to_jsond);]));]letjson_of_fun~to_jsonargumentsbody=[("arguments",`Tuple(List.map(funarg->`Assoc(json_of_fun_arg~to_jsonarg))arguments));("body",to_jsonbody);]letjson_of_let_decoration~to_json:Parsed_term.let_decoration->Json.t=function|`None->`Null|`Recursive->`Assoc(ast_node~typ:"var"[("value",`String"rec")])|`Replaces->`Assoc(ast_node~typ:"var"[("value",`String"replaces")])|`Eval->`Assoc(ast_node~typ:"var"[("value",`String"eval")])|`Sqlite_query->`Assoc(ast_node~typ:"var"[("value",`String"sqlite.query")])|`Sqlite_row->`Assoc(ast_node~typ:"var"[("value",`String"sqlite.row")])|`Yaml_parse->`Assoc(ast_node~typ:"var"[("value",`String"yaml.parse")])|`Json_parse[]->`Assoc(ast_node~typ:"var"[("value",`String"json.parse")])|`Json_parseargs->`Assoc(ast_node~typ:"app"[("op",`Assoc(ast_node~typ:"var"[("value",`String"json.parse")]));("args",`Tuple(List.map(fun(l,t)->`Assoc(ast_node~typ:"term"[("value",`Assoc(ast_node~typ:"app_arg"[("label",`Stringl);("value",to_jsont)]));]))args));])letargs_of_json_let~to_json{decoration;pat;arglist;cast;def}=[("decoration",json_of_let_decoration~to_jsondecoration);("pat",json_of_patpat);("arglist",matcharglistwith|None->`Null|Somearglist->`Tuple(List.map(funarg->`Assoc(json_of_fun_arg~to_jsonarg))arglist));("cast",matchcastwithNone->`Null|Somet->json_of_type_annotationt);("definition",to_jsondef);]letjson_of_let~to_jsonast=lettyp,args,body=matchastwith|`Def(p,body)->("def",args_of_json_let~to_jsonp,body)|`Let(p,body)->("let",args_of_json_let~to_jsonp,body)|`Binding(p,body)->("binding",args_of_json_let~to_jsonp,body)inast_node~typ(("body",to_jsonbody)::args)letjson_of_app_arg~to_json=function|`Term(l,v)->ast_node~typ:"term"[("value",`Assoc(ast_node~typ:"app_arg"[("label",`Stringl);("value",to_jsonv)]));]|`Argsof_of->ast_node~typ:"argsof"(json_of_of_of)letjson_of_app_args~to_jsonargs=`Tuple(List.map(funarg->`Assoc(json_of_app_arg~to_jsonarg))args)letjson_of_invoke_meth~to_json=function|`Strings->ast_node~typ:"var"[("value",`Strings)]|`App(s,args)->ast_node~typ:"app"[("op",`Assoc(ast_node~typ:"var"[("value",`Strings)]));("args",json_of_app_args~to_jsonargs);]letjson_of_list_el~to_json=function|`Termt->ast_node~typ:"term"[("value",to_jsont)]|`Ellipsist->ast_node~typ:"ellipsis"[("value",to_jsont)]letjson_of_time_el{week;hours;minutes;seconds}=letto_int=functionNone->`Null|Somei->`Intiin[("week",to_intweek);("hours",to_inthours);("minutes",to_intminutes);("seconds",to_intseconds);]letrecto_ast_json~to_json=function|`Gett->ast_node~typ:"get"[("value",to_jsont)]|`Set(t,t')->ast_node~typ:"infix"[("left",to_jsont);("op",`String":=");("right",to_jsont')]|`Inline_ifp->ast_node~typ:"inline_if"(json_of_if~to_jsonp)|`Ifp->ast_node~typ:"if"(json_of_if~to_jsonp)|`If_defp->ast_node~typ:"if_def"(json_of_if_def~to_jsonp)|`If_versionp->ast_node~typ:"if_version"(json_of_if_version~to_jsonp)|`If_encoderp->ast_node~typ:"if_encoder"(json_of_if_encoder~to_jsonp)|`Whilep->ast_node~typ:"while"(json_of_while~to_jsonp)|`Forp->ast_node~typ:"for"(json_of_for~to_jsonp)|`Iterable_forp->ast_node~typ:"iterable_for"(json_of_iterable_for~to_jsonp)|`Nott->ast_node~typ:"not"[("value",to_jsont)]|`Negativet->ast_node~typ:"negative"[("value",to_jsont)]|`String_interpolation(c,l)->letl=`String(Printf.sprintf"%c"c)::(l@[`String(Printf.sprintf"%c"c)])inletl=List.map(function|`Strings->`Assoc(ast_node~typ:"interpolated_string"[("value",`Strings)])|`Termtm->`Assoc(ast_node~typ:"interpolated_term"[("value",to_jsontm)]))linast_node~typ:"string_interpolation"[("value",`Tuplel)]|`Append(t,t')->ast_node~typ:"append"[("left",to_jsont);("right",to_jsont')]|`Assoc(t,t')->ast_node~typ:"assoc"[("left",to_jsont);("right",to_jsont')]|`Infix(t,op,t')->ast_node~typ:"infix"[("left",to_jsont);("op",`Stringop);("right",to_jsont')]|`BoolOp(op,l)->ast_node~typ:"bool"[("op",`Stringop);("value",`Tuple(List.mapto_jsonl))]|`Simple_funt->ast_node~typ:"simple_fun"[("value",to_jsont)]|`Timet->ast_node~typ:"time"(json_of_time_elt)|`Time_interval(t,t')->ast_node~typ:"time_interval"[("left",`Assoc(ast_node~typ:"time"(json_of_time_elt)));("right",`Assoc(ast_node~typ:"time"(json_of_time_elt')));]|`Regexp(name,flags)->ast_node~typ:"regexp"[("name",`Stringname);("flags",`Tuple(List.sortStdlib.compare(List.map(func->`String(Char.escapedc))flags)));]|`Tryp->ast_node~typ:"try"(json_of_try~to_jsonp)|`Customg->ast_node~typ:"ground"[("value",`String(Json.to_string(Term_base.Custom.to_json~pos:[]g)));]|`Boolb->ast_node~typ:"ground"[("value",`String(string_of_boolb))]|`Inti->ast_node~typ:"ground"[("value",`Stringi)]|`Floatv->ast_node~typ:"ground"[("value",`Stringv)]|`Parenthesistm->ast_node~typ:"parenthesis"[("value",to_jsontm)]|`Blocktm->ast_node~typ:"block"[("value",to_jsontm)]|`String(c,s)->ast_node~typ:"string"[("value",`String(Printf.sprintf"%c%s%c"csc))]|`Encodere->ast_node~typ:"encoder"(to_encoder_json~to_jsone)|`Listl->ast_node~typ:"list"[("value",`Tuple(List.map(funp->`Assoc(json_of_list_el~to_jsonp))l));]|`Tuplel->ast_node~typ:"tuple"[("value",`Tuple(List.mapto_jsonl))]|`Null->ast_node~typ:"null"[]|`Cast{cast=t;typ}->ast_node~typ:"cast"[("left",to_jsont);("right",json_of_type_annotationtyp)]|`Invoke{invoked;optional;meth}->ast_node~typ:"invoke"[("invoked",to_jsoninvoked);("optional",`Booloptional);("meth",`Assoc(json_of_invoke_meth~to_jsonmeth));]|`Methods(base,methods)->letbase,base_methods=matchbasewithNone->(`Null,[])|Somet->(to_jsont,[])inast_node~typ:"methods"[("base",base);("methods",`Tuple(List.map(function|`Ellipsisv->`Assoc(ast_node~typ:"ellipsis"[("value",to_jsonv)])|`Method(k,v)->`Assoc(ast_node~typ:"method"[("name",`Stringk);("value",to_jsonv)]))methods@base_methods));]|`Eof->ast_node~typ:"eof"[]|`Open(t,t')->ast_node~typ:"open"[("left",to_jsont);("right",to_jsont')]|`Let_asast->json_of_let~to_jsonast|`Def_asast->json_of_let~to_jsonast|`Binding_asast->json_of_let~to_jsonast|`Include{inc_type=`Lib;inc_name}->ast_node~typ:"include_lib"[("value",`Stringinc_name)]|`Include{inc_type=`Default;inc_name}->ast_node~typ:"include"[("value",`Stringinc_name)]|`Include{inc_type=`Extra;inc_name}->ast_node~typ:"include_extra"[("value",`Stringinc_name)]|`Coalesce(t,t')->ast_node~typ:"coalesce"[("left",to_jsont);("right",to_jsont')]|`At(t,t')->ast_node~typ:"infix"[("left",to_jsont);("op",`String"@");("right",to_jsont')]|`Vars->ast_node~typ:"var"[("value",`Strings)]|`Seq(t,t')->ast_node~typ:"seq"[("left",to_jsont);("right",to_jsont')]|`App(t,args)->ast_node~typ:"app"[("op",to_jsont);("args",json_of_app_args~to_jsonargs)]|`Fun(args,body)->ast_node~typ:"fun"(json_of_fun~to_jsonargsbody)|`RFun(lbl,args,body)->ast_node~typ:"rfun"(("name",`Stringlbl)::json_of_fun~to_jsonargsbody)andto_encoder_json~to_json(lbl,params)=[("label",`Stringlbl);("params",`Tuple(List.map(to_encoder_param_json~to_json)params));]andto_encoder_param_json~to_json=function|`Encodere->`Assoc(ast_node~typ:"encoder"(to_encoder_json~to_jsone))|`Labelled(lbl,v)->`Assoc(ast_node~typ:"infix"[("left",`Assoc(json_of_annotated_stringlbl));("op",`String"=");("right",to_jsonv);])|`Anonymouss->`Assoc(json_of_annotated_strings)letrecto_json{pos;term;comments}:Json.t=letbefore_comments,after_comments=List.fold_left(fun(before_comments,after_comments)->function|p,`Beforec->((p,c)::before_comments,after_comments)|p,`Afterc->(before_comments,(p,c)::after_comments))([],[])commentsinletast_comments=`Assoc[("before",`Tuple(List.map(fun(p,c)->`Assoc(ast_node~typ:"comment"[("position",json_of_positionsp);("value",`Tuple(List.map(func->`Stringc)c));]))(List.revbefore_comments)));("after",`Tuple(List.map(fun(p,c)->`Assoc(ast_node~typ:"comment"[("position",json_of_positionsp);("value",`Tuple(List.map(func->`Stringc)c));]))(List.revafter_comments)));]in`Assoc([("ast_comments",ast_comments);("position",json_of_positionspos)]@to_ast_json~to_jsonterm)letparse_string?(formatter=Format.err_formatter)content=letlexbuf=Sedlexing.Utf8.from_stringcontentinletthrow=Runtime.throw~formatter~lexbuf()intrylettokenizer=Preprocessor.mk_tokenizerlexbufinletterm=Runtime.programtokenizerinParser_helper.attach_commentsterm;to_jsontermwithexn->throwexn;exit1