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

21
main.ml
View file

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