]> git.kianting.info Git - uann/commitdiff
add interp from EoC
authorTan Kian-ting <chenjt30@gmail.com>
Sun, 24 Mar 2024 16:34:14 +0000 (00:34 +0800)
committerTan Kian-ting <chenjt30@gmail.com>
Sun, 24 Mar 2024 16:34:14 +0000 (00:34 +0800)
ocaml_yacc/calc.ml

index 049297dc9d88cebbc2ab7da3539bce2c02f88e49..edb18d4e0d0fb7ee89823830f1c155c0d1f65bf7 100644 (file)
@@ -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