Add var table

This commit is contained in:
백현웅 2022-01-20 01:35:18 +09:00
parent 7fd3917572
commit 7b9ccd1328
2 changed files with 17 additions and 14 deletions

10
eval.ml
View file

@ -21,13 +21,13 @@ let rec binop op l r =
end end
| Some f -> f l r | Some f -> f l r
let eval ans ast = let eval vars ast =
let rec aux = function let rec aux = function
| Value v -> v | Value v -> v
| Var v -> | Var v -> begin match Hashtbl.find_opt vars v with
if v = "ans" | None -> raise @@ No_such_variable v
then ans | Some v -> v
else raise @@ No_such_variable v end
| Binop (l, op, r) -> | Binop (l, op, r) ->
let l = aux l and r = aux r in let l = aux l and r = aux r in
binop op l r binop op l r

21
main.ml
View file

@ -18,8 +18,10 @@ let error_to_string e =
let print_error e = let print_error e =
printf "error: %s\n" @@ error_to_string e printf "error: %s\n" @@ error_to_string e
let vars = Hashtbl.create 100
(* read-eval-print *) (* read-eval-print *)
let rep ans : unit = let rep vars : unit =
printf "> "; printf "> ";
let line = read_line () in let line = read_line () in
if line = "quit" then raise Exit; if line = "quit" then raise Exit;
@ -27,27 +29,28 @@ let rep ans : unit =
line line
|> Lex.tokenize |> Lex.tokenize
|> Parser.parse |> Parser.parse
|> Eval.eval !ans |> Eval.eval vars
in in
match v with match v with
| Nop -> () | Nop -> ()
| _ -> | _ ->
ans := v; Hashtbl.replace vars "ans" v;
printf "%s\n" @@ Ast.Value.to_string v printf "%s\n" @@ Ast.Value.to_string v
let init_repl () = let init_repl () =
Hashtbl.replace vars "ans" (Ast.Value.Int 0);
(* treat Ctrl-C as to reset line *)
let sigintf _ = raise Reset_line in let sigintf _ = raise Reset_line in
Sys.(set_signal sigint (Signal_handle sigintf)) Sys.(set_signal sigint (Signal_handle sigintf))
(* simple REPL with error handling *) (* simple REPL with error handling *)
let rec repl ans : unit = let rec repl vars : unit =
try rep ans; repl ans with try rep vars; repl vars with
| Exit | End_of_file -> () | Exit | End_of_file -> ()
| Reset_line -> printf "\n"; repl ans | Reset_line -> printf "\n"; repl vars
| e -> print_error e; repl ans | e -> print_error e; repl vars
let () = let () =
let ans = ref @@ Ast.Value.Int 0 in
init_repl (); init_repl ();
printf "Configurable Evaluator %s\n" version; (* banner *) printf "Configurable Evaluator %s\n" version; (* banner *)
repl ans repl vars