open Expression open Nodes open Analysis include Random module Calculator = struct type t = { mutable node2int : (Nodes.node, int) Hashtbl.t } let state = { node2int = Hashtbl.create 2 } let de_optionify = function (Some x) -> x | None -> failwith "tried to deoptionify None" let binop n l r f = let l1 = P (PExp (de_optionify l)) in let r1 = P (PExp (de_optionify r)) in Hashtbl.add state.node2int n (f (Hashtbl.find state.node2int l1) (Hashtbl.find state.node2int r1)) let calculating_leave parent old_child child visitor = match child with | Start (p, _) -> let e = (match p with PGrammar AGrammar x -> x | _ -> failwith "type error1").grammar_exp in begin if (List.length e > 0) then print_string (string_of_int (Hashtbl.find state.node2int (P (PExp (List.hd e))))); end; ignore (List.map (function x -> print_string ("; " ^ string_of_int (Hashtbl.find state.node2int x))) (List.tl (List.map (function x -> (P (PExp x))) e))); print_string "\n"; child | P PExp ANumberExp p -> Hashtbl.add state.node2int child (int_of_string (Tokens.getText (match p.number_exp_number with Some x -> x | None -> failwith "type error2"))); child | P PExp APlusExp p -> binop child p.plus_exp_l p.plus_exp_r (fun x y -> x + y); child | P PExp AMinusExp p -> binop child p.minus_exp_l p.minus_exp_r (fun x y -> x - y); child | P PExp AMultExp p -> binop child p.mult_exp_l p.mult_exp_r (fun x y -> x * y); child | P PExp ADivExp p -> binop child p.div_exp_l p.div_exp_r (fun x y -> x / y); child | P PTextual AT1Textual _ -> Hashtbl.add state.node2int child 1; child | P PTextual AT2Textual _ -> Hashtbl.add state.node2int child 2; child | P PTextual AT3Textual _ -> Hashtbl.add state.node2int child 3; child | P PExp ATextualExp p -> let res = ref 0 and mul = ref 1 in let acc x = res := !res + !mul * Hashtbl.find state.node2int (P (PTextual x)); mul := !mul * 10 in ignore (List.map acc (List.rev p.textual_exp_textual)); Hashtbl.add state.node2int child !res; child | P PExp ARandomX2Exp _ -> Hashtbl.add state.node2int child (Random.int 100); child | _ -> child let rec calculating_visitor = { override = (fun parent n -> n); enter = (fun _ _ -> calculating_visitor); leave = calculating_leave; finish = (fun n -> ()); start = (fun () -> calculating_visitor); } end