+exception Exc of string
+
(* File calc.ml *)
let rec ast_to_string ast = match ast with
| Ast.Leaf s -> s
+| Ast.Int i -> string_of_int i
| Ast.Node ls -> "[" ^ String.concat " " (List.map ast_to_string ls) ^ "]"
;;
+(** interpreter for interp_int*)
+class interp_int x_init =
+ object (self)
+ val mutable x = x_init
+ method interp code = match code with
+ | Ast.Int x -> x
+ | Ast.Node [Ast.Leaf "+"; lhs; rhs] ->
+ let x1 = self#interp lhs in
+ let x2 = self#interp rhs in
+ x1+x2
+ | Ast.Node [Ast.Leaf "-"; lhs; rhs] ->
+ let x1 = self#interp lhs in
+ let x2 = self#interp rhs in
+ x1-x2
+ | Ast.Node [Ast.Leaf "-"; x] ->
+ let x1 = self#interp x in
+ 0-x1
+ | Ast.Node [Ast.Leaf "%apply" ; Ast.Leaf "read"; Ast.Int 0] ->
+ let input = read_int_opt () in
+ match input with
+ | Some(y) -> y
+ | _ -> raise (Exc "input invalid number")
+ | _ -> raise (Exc "unsupported")
+ end;;
+
+
+
+
+(**main body*)
let _ =
try
let lexbuf = Lexing.from_channel stdin in
+ let interp = new interp_int 0 in
while true do
let result = Parser.main Lexer.token lexbuf in
- Printf.printf "%s" (ast_to_string result); print_newline(); flush stdout
+ Printf.printf "%d" (interp#interp result); print_newline(); flush stdout
done
with Lexer.Eof ->
exit 0