123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899(**************************************************************************)(* This file is part of the Codex semantics library. *)(* *)(* Copyright (C) 2013-2025 *)(* CEA (Commissariat à l'énergie atomique et aux énergies *)(* alternatives) *)(* *)(* you can redistribute it and/or modify it under the terms of the GNU *)(* Lesser General Public License as published by the Free Software *)(* Foundation, version 2.1. *)(* *)(* It 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 Lesser General Public License for more details. *)(* *)(* See the GNU Lesser General Public License version 2.1 *)(* for more details (enclosed in the file LICENSE). *)(* *)(**************************************************************************)moduleVar=While_ast.VarmoduleState=structmoduleM=Map.Make(Var)typet=Z.tM.tletempty=M.emptyletfindvs=tryM.findvswithNot_found->Z.zeroletaddvns=M.addvnsletiter=M.iterletppfmts=Format.fprintffmt"{@[<hov2>%a@]}"(Format.pp_print_list~pp_sep:(funfmt()->Format.fprintffmt";@ ")(funfmt(k,v)->Format.fprintffmt"%a -> %s@,"Var.ppk(Z.to_stringv)))(M.bindingss)letof_list(l:(string*int)list):t=List.fold_left(funs(name,n)->letv=Var.of_stringnameinletz=Z.of_intninaddvzs)emptylendletinitial_state()=State.empty(* $MDX part-begin=tracelog *)moduleLog=Tracelog.Make(structletcategory="CInterpreter"end)(* $MDX part-end *)openWhile_ast(* $MDX part-begin=interp_aexp *)letrecinterp_aexp:aexp->State.t->Z.t=funexpstate->Log.trace(funp->p"interp_aexp: %a"pp_aexpexp)~pp_ret:Z.pp_print@@fun()->matchexpwith|Inti->Z.of_inti|Varv->State.findvstate|Add(e1,e2)->Z.add(interp_aexpe1state)(interp_aexpe2state)|Sub(e1,e2)->Z.sub(interp_aexpe1state)(interp_aexpe2state)|Mul(e1,e2)->Z.mul(interp_aexpe1state)(interp_aexpe2state)(* $MDX part-end *)(* $MDX part-begin=interp_bexp *)letrecinterp_bexp:bexp->State.t->bool=funbexpstate->Log.trace(funp->p"interp_bexp: %a"pp_bexpbexp)~pp_ret:Format.pp_print_bool@@fun()->matchbexpwith|True->true|False->false|Eq(e1,e2)->(interp_aexpe1state)=(interp_aexpe2state)|Le(e1,e2)->(interp_aexpe1state)<=(interp_aexpe2state)|Gt(e1,e2)->(interp_aexpe1state)>(interp_aexpe2state)|Note->interp_bexpestate|And(e1,e2)->(interp_bexpe1state)&&(interp_bexpe2state)(* $MDX part-end *)(* $MDX part-begin=interp_while *)letrecinterp_stmt:stmt->State.t->State.t=funstmtstate->Log.trace(funp->p"interp_stmt: %a"pp_stmtstmt)~pp_ret:State.pp@@fun()->matchstmtwith|Skip->state|Assign(v,e)->State.addv(interp_aexpestate)state|Seq(e1,e2)->state|>interp_stmte1|>interp_stmte2|If(b,e1,e2)->ifinterp_bexpbstatetheninterp_stmte1stateelseinterp_stmte2state|While(b,e)->ifinterp_bexpbstatethenletstate'=interp_stmtestateininterp_stmtstmtstate'elsestate(* $MDX part-end *)