1234567891011121314151617181920212223242526272829303132333435363738394041424344454647(** Contains functions to manipulate expressions *)openTypes(** Function that finds a nested lambda body *)letrecfindbodyl=matchlwith|Lambda(_,b)->findbodyb|other->other(** Function that finds and replaces a (nested) lambda body *)letrecreplacebodylnewbody=matchlwith|Lambda(p,b)->Lambda(p,replacebodybnewbody)|_->newbody(** Function that creates a list with the params of a nested lambda*)letrecfindparamsl=matchlwith|Lambda(p,b)->p::(findparamsb)|_->[](** Creates a nested Lambda from a list of params*)letlambda_of_paramlistlbody=List.fold_right(funpe->Lambda(p,e))lbody(** Creates a nested Lambda from an array of params*)letlambda_of_paramarrlbody=Array.fold_right(funpe->Lambda(p,e))lbody(** Creates a nested Apply from a list of expressions*)letapply_from_exprlistlf=List.fold_left(funep->Apply(e,p))fl(** Creates a list of Symbol from a list of string*)letsymbols_from_stringsl=List.map(funx->Symbolx)l(** Show a short representation of an expression (useful for stack traces) *)letrecshow_expr_shorte=matchewith|NumInti->string_of_inti|NumFloati->string_of_floati|NumComplexi->show_complexti|Booleani->string_of_booli|Stringi->"\""^i^"\""|Symbols->s|Listl->"["^(String.concat", "(List.mapshow_expr_shortl))^"]"|Dictd->"{ "^(List.fold_left(funxy->(x^" = ... , "^y))""(Util.snd3ld))^" }"|Apply(Symbolf,b)->f^" ("^show_expr_shortb^")"|Lambda(p,b)->"(fun "^(String.concat" "(p::(findparamsb)))^" -> ... )"|Let(l,_)->"let "^(String.concat" and"(List.map(funx->Util.snd3x^" = ... ")l))|Binop(kind,a,b)->show_expr_shorta^" "^(show_binopkind)^" "^show_expr_shortb|_->"<code>"