open List open Mo exception ParseError of string (* Teil a) *) type var = string type expr = Const of int | Var of var | Add of expr * expr | Sub of expr * expr | Mul of expr * expr | Div of expr * expr (* Teil b) *) let rec get_expr t = match t with Node("Const", [Node(x,[])]) -> Const(int_of_string x) | Node("Var", [Node(x,[])]) -> Var(x) | Node("Add", [a1;a2]) -> Add(get_expr a1, get_expr a2) | Node("Sub", [a1;a2]) -> Sub(get_expr a1, get_expr a2) | Node("Mul", [a1;a2]) -> Mul(get_expr a1, get_expr a2) | Node("Div", [a1;a2]) -> Div(get_expr a1, get_expr a2) | _ -> raise (ParseError (string_from_term t)) (* Teil c) *) let rec eval = function Add (e1,e2) -> (eval e1) + (eval e2) | Sub (e1,e2) -> (eval e1) - (eval e2) | Mul (e1,e2) -> (eval e1) * (eval e2) | Div (e1,e2) -> (eval e1) / (eval e2) | Const i -> i | Var v -> 0 (* Teil d) *) let update rho x v y = if x = y then v else rho y (* Teil e) *) let rec eval rho = function Add (e1,e2) -> (eval rho e1) + (eval rho e2) | Sub (e1,e2) -> (eval rho e1) - (eval rho e2) | Mul (e1,e2) -> (eval rho e1) * (eval rho e2) | Div (e1,e2) -> (eval rho e1) / (eval rho e2) | Const i -> i | Var v -> rho v (* Teil f) *) (* Variante 1 *) let union a b = fold_left (fun m x -> if mem x m then m else x::m) a b let rec vars = function Add(e1,e2) | Sub(e1,e2) | Mul(e1,e2) | Div(e1,e2) -> union (vars e1) (vars e2) | Var(x) -> [x] | _ -> [] (*-- Variante 1 *) (* Variante 2 *) let rec vars vs = function Add(e1,e2) | Sub(e1,e2) | Mul(e1,e2) | Div(e1,e2) -> let vs = vars vs e1 in vars vs e2 | Var(v) -> if mem v vs then vs else v::vs | _ -> vs let vars = vars [] (*-- Variante 2 *) let read_rho vars = fold_left (fun rho x -> let v = print_string (x ^ " = "); read_int () in update rho x v) (fun _ -> 0) vars let term = term_from_file Sys.argv.(1) let ausdruck = get_expr term let _ = print_string ("Eingelesener Ausdruck : " ^ (string_from_term term) ^ "\n") let rho = read_rho (vars ausdruck) let _ = print_string "Der Wert des Ausdrucks ist " let _ = print_int (eval rho ausdruck) let _ = print_string ".\n"