Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file environment.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125(*****************************************************************************
Liquidsoap, a programmable audio stream generator.
Copyright 2003-2023 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
*****************************************************************************)(** {1 Evaluation environment} *)moduleEnv=Value.Methodslettype_environment:Type.schemeEnv.tref=refEnv.emptyletvalue_environment:Value.tEnv.tref=refEnv.emptyletdefault_environment()=Env.bindings!value_environmentletdefault_typing_environment()=Env.bindings!type_environment(* Just like builtins but we register a.b under the name "a.b" (instead of
adding a field b to a). It is used only for [has_builtins] and
[get_builtins]. *)letflat_enviroment:(string*(Type.scheme*Value.t))listref=ref[]lethas_builtinname=List.mem_assocname!flat_enviromentletget_builtinname=List.assoc_optname!flat_enviromentletadd_builtin?(override=false)?(register=true)?docname((g,t),v)=ifregister&&doc<>NonethenDoc.Value.add(String.concat"."name)(Option.getdoc);flat_enviroment:=(String.concat"."name,((g,t),v))::!flat_enviroment;matchnamewith|[name]->(* Don't allow overriding builtins. *)if(notoverride)&&Env.memname!type_environmentthenfailwith("Trying to override builtin "^name);type_environment:=Env.addname(g,t)!type_environment;value_environment:=Env.addnamev!value_environment|x::ll->let(g0,t0),v0=try(Env.findx!type_environment,Env.findx!value_environment)withNot_found->failwith("Could not find builtin variable "^x)in(* x.l1.l2.l3 = v means
x = (x where l1 = (x.l1 where l2 = (x.l1.l2 where l3 = v)))
*)(* Inductive step: we compute the new type scheme and value of
x.l1...li. The variable prefix contains [li; ...; l1] and the second
argument is [li+1; ...; ln]. *)letrecaux(g0,t0)v0=function|l::[]->lett=Type.make?pos:t.Type.posType.(Meth({meth=l;optional=false;scheme=(g,t);doc="";json_name=None;},t0))in((g0,t),Value.{v0withmethods=Methods.addlvv0.methods})|l::ll->let(vg,vt),v=aux(Type.invoket0l)(Value.invokev0l)llinlett=Type.make?pos:t.Type.posType.(Meth({meth=l;optional=false;scheme=(vg,vt);doc="";json_name=None;},t0))in((g0,t),Value.{v0withmethods=Methods.addlvv0.methods})|[]->((g,t),v)inlet(g,t),v=aux(g0,t0)v0llinassert(g==g0);type_environment:=Env.addx(g0,t)!type_environment;value_environment:=Env.addxv!value_environment|[]->assertfalse(** Declare a module. *)letadd_modulename=(* Ensure that it does not already exist. *)(matchnamewith|[]->assertfalse|[x]->ifEnv.memx!type_environmentthenfailwith("Module "^String.concat"."name^" already declared")|x::mm->(letmm=List.revmminletl=List.hdmminletmm=List.rev(List.tlmm)inlete=tryValue.invokes(Env.findx!value_environment)mmwith_->failwith("Could not find the parent module of "^String.concat"."name)intryignore(Value.invokeel);failwith("Module "^String.concat"."name^" already exists")with_->()));add_builtin~register:falsename(([],Type.makeType.unit),Value.{pos=None;value=unit;methods=Methods.empty})