// identificatori type ide = string type aexp = | AEint of int | AEplus of (aexp * aexp) | AEminus of (aexp * aexp) | AElet of (ide * aexp * aexp) | AEide of ide let rec aexp_to_string : aexp -> string = fun e -> match e with AEint i -> sprintf "%d" i | AEplus (e,f) -> sprintf "(%s + %s)" (aexp_to_string e) (aexp_to_string f) | AEminus (e,f) -> sprintf "(%s - %s)" (aexp_to_string e) (aexp_to_string f) | AElet (x, e, f) -> Printf.sprintf "(let %s = %s in %s)" x (aexp_to_string e) (aexp_to_string f) | AEide (x) -> x // error handling let unbound_identifier_error ide = failwith (Printf.sprintf "unbound identifier %s" ide) // semantic domains type eval = int type dval = eval // denotable and expressible values coincide let eval_to_string : eval -> string = fun e -> Printf.sprintf "%d" e // ambiente type env = ide -> dval let empty = fun v -> unbound_identifier_error v