X-Git-Url: https://git.kianting.info/?a=blobdiff_plain;f=ocaml_yacc%2Fcalc.ml;fp=ocaml_yacc%2Fcalc.ml;h=edb18d4e0d0fb7ee89823830f1c155c0d1f65bf7;hb=dc89f114ae00fcae1f8cd0bb5eae9977f15c3582;hp=049297dc9d88cebbc2ab7da3539bce2c02f88e49;hpb=1ea8dfd99517fdfe98c81aa206ad2615c1113426;p=uann diff --git a/ocaml_yacc/calc.ml b/ocaml_yacc/calc.ml index 049297d..edb18d4 100644 --- a/ocaml_yacc/calc.ml +++ b/ocaml_yacc/calc.ml @@ -1,15 +1,48 @@ +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