Implement Ocaml-style return
This commit is contained in:
parent
7cddc45e8b
commit
1f91d214ee
3 changed files with 27 additions and 15 deletions
22
eval.ml
22
eval.ml
|
@ -213,7 +213,7 @@ let rec binop op l r =
|
|||
|
||||
exception Unbound of string
|
||||
|
||||
let rec eval env ast : value =
|
||||
let rec eval env ast : string * value =
|
||||
let rec aux = function
|
||||
| Nint n -> Int n
|
||||
| Nfloat n -> Float n
|
||||
|
@ -232,9 +232,6 @@ let rec eval env ast : value =
|
|||
| Binop (l, op, r) ->
|
||||
let l = aux l and r = aux r in
|
||||
binop op l r
|
||||
| Let (var, e) ->
|
||||
let v = aux e in
|
||||
Env.set env var v; v
|
||||
| Apply (v, args) ->
|
||||
begin match aux v with
|
||||
| Function (vars, e) ->
|
||||
|
@ -243,7 +240,7 @@ let rec eval env ast : value =
|
|||
let nenv = Env.make env in
|
||||
List.combine vars args
|
||||
|> List.iter (fun (v, a) -> Env.set nenv v a);
|
||||
eval nenv e
|
||||
snd @@ eval nenv e
|
||||
| External f ->
|
||||
let args = List.map aux args in
|
||||
External.apply f args
|
||||
|
@ -263,8 +260,15 @@ let rec eval env ast : value =
|
|||
Hashtbl.replace Parser.oper_assoc op @@ Parser.assoc_of_string a;
|
||||
Nop
|
||||
| Get_binop_aso op ->
|
||||
match Hashtbl.find_opt Parser.oper_assoc op with
|
||||
| None -> String "left"
|
||||
| Some a -> String (Parser.assoc_to_string a)
|
||||
(match Hashtbl.find_opt Parser.oper_assoc op with
|
||||
| None -> String "left"
|
||||
| Some a -> String (Parser.assoc_to_string a))
|
||||
| _ -> failwith "Eval.eval"
|
||||
in
|
||||
aux ast
|
||||
|
||||
match ast with
|
||||
| Let (var, e) ->
|
||||
let v = aux e in
|
||||
Env.set env var v;
|
||||
var, v
|
||||
| ast -> "-", aux ast
|
||||
|
|
5
main.ml
5
main.ml
|
@ -36,7 +36,7 @@ let rep env : unit =
|
|||
printf "> ";
|
||||
let line = read_line () in
|
||||
if line = "quit" then raise Exit;
|
||||
let v =
|
||||
let var, v =
|
||||
line
|
||||
|> Lex.tokenize
|
||||
|> Parser.parse
|
||||
|
@ -46,7 +46,8 @@ let rep env : unit =
|
|||
| Nop -> ()
|
||||
| _ ->
|
||||
Env.set env "ans" v;
|
||||
printf "%s\n" @@ Value.to_string v
|
||||
printf "%s: %s = %s\n"
|
||||
var (Type.to_string @@ Value.typeof v) (Value.to_string v)
|
||||
|
||||
exception Reset_line (* used to indicate ^C is pressed *)
|
||||
|
||||
|
|
15
parser.ml
15
parser.ml
|
@ -139,17 +139,24 @@ let more f seq =
|
|||
let xs, seq = aux [] seq in
|
||||
List.rev xs, seq
|
||||
|
||||
(* decl := let_value
|
||||
* | expr
|
||||
*)
|
||||
let rec decl seq =
|
||||
seq |> oneof [
|
||||
let_value;
|
||||
expr min_int;
|
||||
]
|
||||
|
||||
(* expr := level
|
||||
* | assoc
|
||||
* | let
|
||||
* | apply
|
||||
* | value binop_right
|
||||
*)
|
||||
let rec expr pre seq =
|
||||
and expr pre seq =
|
||||
seq |> oneof [
|
||||
level;
|
||||
assoc;
|
||||
let_value;
|
||||
lambda;
|
||||
extern_value;
|
||||
apply;
|
||||
|
@ -267,6 +274,6 @@ and binop pre left seq =
|
|||
|
||||
(* parse tokens *)
|
||||
let parse ts =
|
||||
let ast, rest = expr min_int ts in
|
||||
let ast, rest = decl ts in
|
||||
if rest () <> Seq.Nil then failwith "Parser.parse";
|
||||
ast
|
||||
|
|
Loading…
Add table
Reference in a new issue