add interp from EoC
This commit is contained in:
parent
1ea8dfd995
commit
dc89f114ae
1 changed files with 34 additions and 1 deletions
|
@ -1,15 +1,48 @@
|
||||||
|
exception Exc of string
|
||||||
|
|
||||||
(* File calc.ml *)
|
(* File calc.ml *)
|
||||||
let rec ast_to_string ast = match ast with
|
let rec ast_to_string ast = match ast with
|
||||||
| Ast.Leaf s -> s
|
| Ast.Leaf s -> s
|
||||||
|
| Ast.Int i -> string_of_int i
|
||||||
| Ast.Node ls -> "[" ^ String.concat " " (List.map ast_to_string ls) ^ "]"
|
| 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 _ =
|
let _ =
|
||||||
try
|
try
|
||||||
let lexbuf = Lexing.from_channel stdin in
|
let lexbuf = Lexing.from_channel stdin in
|
||||||
|
let interp = new interp_int 0 in
|
||||||
while true do
|
while true do
|
||||||
let result = Parser.main Lexer.token lexbuf in
|
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
|
done
|
||||||
with Lexer.Eof ->
|
with Lexer.Eof ->
|
||||||
exit 0
|
exit 0
|
||||||
|
|
Loading…
Reference in a new issue