Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file evaluator.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112letfind_rule~programf=tryHashtbl.findprogramfwith|Not_found->Util.panic"No such function %s"(Symbol.verbatimf);;letfind_case~ccases=matchList.find_map(fun((c',c_params),t)->ifc=c'thenSome(c_params,t)elseNone)caseswith|Some(c_params,t)->c_params,t|None->Util.panic"No such case %s"(Symbol.verbatimc);;letto_const=function|Raw_term.Constconst->Term.Constconst|t->Util.panic"Expected a constant: %s"(Raw_term.verbatimt);;letof_const=function|Term.Constconst->Raw_term.Constconst|Term.Call(c,[])when(Symbol.op_kindc=`CCall)[@coverageoff]->Raw_term.Call(c,[])[@coverageoff]|Term.(Call(c,[Const(Const.Strings)]))whenc=Symbol.of_string"Panic"->Raw_term.(Call(c,[strings]))|t->Util.panic"Cannot reduce: %s"(Term.verbatimt);;letto_c_call=function|Raw_term.Call(c,args)whenSymbol.op_kindc=`CCall->c,args|t->Util.panic"Expected a constructor call: %s"(Raw_term.verbatimt);;letfind_var~envx=matchSymbol_map.findxenvwith|exceptionNot_found->Util.panic"Unbound variable %s"(Symbol.verbatimx)|t->t;;letrecsubst~env=function|Raw_term.Varx->find_var~envx|Raw_term.Const_ast->t|Raw_term.Call(op,args)->Raw_term.Call(op,List.map(subst~env)args)|Raw_term.Match(t,cases)->Raw_term.Match(subst~envt,List.map(fun(pattern,t)->pattern,subst~envt)cases)|Raw_term.Let(x,t,u)->Raw_term.Let(x,subst~envt,subst~envu)[@@coverageoff];;letinvalid_arg_list~opargs=Util.panic"Unexpected argument list for %s: %s"(Symbol.verbatimop)(args|>List.mapRaw_term.verbatim|>String.concat",");;(* We could use OCaml's exceptions for that, but let us keep the style as close as
possible to the language definition. *)let(let$)tk=matchtwith|Raw_term.Call(c,[_])whenc=Symbol.of_string"Panic"->t|_->kt;;letrun_exn(input:Raw_program.t)=letprogram=input|>List.map(fun(_attrs,f,params,body)->f,(params,body))|>List.to_seq|>Hashtbl.of_seqinletrecgo~env=function|Raw_term.Varx->go~env:Symbol_map.empty(find_var~envx)|Raw_term.Const_ast->t|Raw_term.Call(c,args)whenSymbol.op_kindc=`CCall->Raw_term.Call(c,List.map(subst~env)args)|Raw_term.Call(op,[t])whenSymbol.is_op1op->(let$t_val=go~envtinof_const(Simplifier.handle_op1~op(to_constt_val)))[@coverageoff]|Raw_term.Call(op,[t1;t2])whenSymbol.is_op2op->let$t1_val=go~envt1inlet$t2_val=go~envt2inof_const(Simplifier.handle_op2~op(to_constt1_val,to_constt2_val))|Raw_term.Call(op,args)whenSymbol.is_primitive_opop->invalid_arg_list~opargs|Raw_term.Call(f,args)->go_args~env~f~acc:Fun.idargs|Raw_term.Match(t,cases)->let$t_val=go~envtinletc,c_args=to_c_callt_valinletc_params,body=find_case~ccasesinletenv=Symbol_map.extend2~keys:c_params~values:c_argsenvingo~envbody|Raw_term.Let(x,t,u)->(let$t_val=go~envtingo~env:(Symbol_map.addxt_valenv)u)[@coverageoff]andgo_args~env~f~acc=function|[]->go_call~f(acc[])|t::rest->let$t_val=go~envtingo_args~env~f~acc:(funxs->acc(t_val::xs))restandgo_call~fargs=letparams,body=find_rule~programfinletenv=Symbol_map.setup2(params,args)ingo~envbodyinletmain_params,t=find_rule~program(Symbol.of_string"main")inifnot(List.is_emptymain_params)then(Util.panic[@coverageoff])"The main function cannot accept parameters";go~env:Symbol_map.emptyt;;