add interp from EoC

This commit is contained in:
Tan, Kian-ting 2024-03-25 00:34:14 +08:00
parent 1ea8dfd995
commit dc89f114ae

View 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