(* Data structures for representing the state of a system *) open Util open Ast exception Combinatorial_cycle of string exception No_variable of string exception Type_error of string let type_error e = raise (Type_error e) exception Not_implemented of string let not_implemented e = raise (Not_implemented e) type scope = string type svalue = | VInt of int | VBool of bool | VReal of float | VState of id | VPrevious of value | VBusy (* intermediate value : calculating ! for detection of cycles *) and value = svalue list type state = svalue VarMap.t (* functions for recursively getting variables *) type calc_fun = | F of (state -> calc_map -> state) and calc_map = calc_fun VarMap.t let get_var (st: state) (c: calc_map) (id: id) : (state * svalue) = let st = if VarMap.mem id st then st else try match VarMap.find id c with | F f -> Format.printf "%s[ " id; let r = f (VarMap.add id VBusy st) c in Format.printf "]%s " id; r with Not_found -> raise (No_variable id) in match VarMap.find id st with | VBusy -> raise (Combinatorial_cycle id) | v -> st, v (* pretty-printing *) let rec str_of_value = function | VInt i -> string_of_int i | VReal r -> string_of_float r | VBool b -> if b then "true" else "false" | VState s -> "state " ^ s | VPrevious p -> "[" ^ List.fold_left (fun s v -> (if s = "" then "" else s ^ ", ") ^ str_of_value v) "" p ^ "]" | VBusy -> "#" let print_state st = VarMap.iter (fun id v -> Format.printf "%s = %s@." id (str_of_value v)) st