]> git.kianting.info Git - uann/blob - ocaml_yacc/calc.ml
edb18d4e0d0fb7ee89823830f1c155c0d1f65bf7
[uann] / ocaml_yacc / calc.ml
1 exception Exc of string
2
3 (* File calc.ml *)
4 let rec ast_to_string ast = match ast with
5 | Ast.Leaf s -> s
6 | Ast.Int i -> string_of_int i
7 | Ast.Node ls -> "[" ^ String.concat " " (List.map ast_to_string ls) ^ "]"
8 ;;
9
10 (** interpreter for interp_int*)
11 class interp_int x_init =
12 object (self)
13 val mutable x = x_init
14 method interp code = match code with
15 | Ast.Int x -> x
16 | Ast.Node [Ast.Leaf "+"; lhs; rhs] ->
17 let x1 = self#interp lhs in
18 let x2 = self#interp rhs in
19 x1+x2
20 | Ast.Node [Ast.Leaf "-"; lhs; rhs] ->
21 let x1 = self#interp lhs in
22 let x2 = self#interp rhs in
23 x1-x2
24 | Ast.Node [Ast.Leaf "-"; x] ->
25 let x1 = self#interp x in
26 0-x1
27 | Ast.Node [Ast.Leaf "%apply" ; Ast.Leaf "read"; Ast.Int 0] ->
28 let input = read_int_opt () in
29 match input with
30 | Some(y) -> y
31 | _ -> raise (Exc "input invalid number")
32 | _ -> raise (Exc "unsupported")
33 end;;
34
35
36
37
38 (**main body*)
39 let _ =
40 try
41 let lexbuf = Lexing.from_channel stdin in
42 let interp = new interp_int 0 in
43 while true do
44 let result = Parser.main Lexer.token lexbuf in
45 Printf.printf "%d" (interp#interp result); print_newline(); flush stdout
46 done
47 with Lexer.Eof ->
48 exit 0
49
50