1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889(** A value identifier*)typeide=string[@@derivingshow](** The type representing Abstract Syntax Tree expressions *)typeexpr=|Unit|Integerofint|Booleanofbool|Symbolofide|Listoflist_pattern(* List operations *)|Headofexpr|Tailofexpr|Consofexpr*expr(* Numerical Operations *)|Sumofexpr*expr|Subofexpr*expr|Multofexpr*expr|Eqofexpr*expr|Gtofexpr*expr|Ltofexpr*expr(* Boolean operations *)|Andofexpr*expr|Orofexpr*expr|Notofexpr(* Control flow and functions *)|IfThenElseofexpr*expr*expr|Letofide*expr*expr|Letlazyofide*expr*expr|Letrecofide*expr*expr|Lambdaofidelist*expr|LazyLambdaofidelist*expr|Applyofexpr*exprlist[@@derivingshow{with_path=false}]andlist_pattern=EmptyList|ListValueofexpr*list_pattern[@@derivingshow{with_path=false}](** A type to build lists, mutually recursive with `expr` *)(** A purely functional environment type, parametrized *)type'aenv_t=(string*'a)list[@@derivingshow{with_path=false}](** A type that represents an evaluated (reduced) value *)typeevt=|EvtUnit|EvtIntofint|EvtBoolofbool|EvtListofevtlist|Closureofidelist*expr*(type_wrapperenv_t)|LazyClosureofidelist*expr*(type_wrapperenv_t)(** RecClosure keeps the function name in the environment for recursion *)|RecClosureofide*idelist*expr*(type_wrapperenv_t)|RecLazyClosureofide*idelist*expr*(type_wrapperenv_t)[@@derivingshow{with_path=false}]andtype_wrapper=|LazyExpressionofexpr|AlreadyEvaluatedofevt[@@derivingshow](** Wrapper type that allows both AST expressions and
evaluated expression for lazy evaluation *)(** An environment of already evaluated values *)typeenv_type=type_wrapperenv_t(** A recursive type representing a stacktrace frame *)typestackframe=|StackValueofint*expr*stackframe|EmptyStack[@@derivingshow{with_path=false}](** Convert a native list to an AST list *)letrecexpand_listl=matchlwith|[]->EmptyList|x::xs->ListValue(x,expand_listxs)(** Push an AST expression into a stack *)letpush_stack(s:stackframe)(e:expr)=matchswith|StackValue(d,ee,ss)->StackValue(d+1,e,StackValue(d,ee,ss))|EmptyStack->StackValue(1,e,EmptyStack)(** Pop an AST expression from a stack *)letpop_stack(s:stackframe)=matchswith|StackValue(_,_,ss)->ss|EmptyStack->failwith"STACK UNDERFLOW"exceptionUnboundVariableofstringexceptionWrongBindListexceptionTypeErrorofstringexceptionListErrorofstringexceptionSyntaxErrorofstring