This commit is contained in:
백현웅 2022-01-21 00:17:01 +09:00
parent 5aaa261198
commit 2be0b7f794
4 changed files with 28 additions and 0 deletions

5
ast.ml
View file

@ -99,6 +99,7 @@ end
type t = type t =
| Value of Value.t | Value of Value.t
| Var of string | Var of string
| Let of string * t
| Binop of t * Binop.t * t | Binop of t * Binop.t * t
| Set_binop_pre of Binop.t * t | Set_binop_pre of Binop.t * t
| Get_binop_pre of Binop.t | Get_binop_pre of Binop.t
@ -117,6 +118,10 @@ let print ast =
let rec aux = function let rec aux = function
| Value n -> pv n | Value n -> pv n
| Var v -> pr "%s" v | Var v -> pr "%s" v
| Let (v, e) ->
pr "(let %s " v;
aux e;
pr ")"
| Binop (left, op, right) -> begin | Binop (left, op, right) -> begin
let op = Binop.to_string op in let op = Binop.to_string op in
pr "(%s " op; aux left; pr " "; aux right; pr ")"; pr "(%s " op; aux left; pr " "; aux right; pr ")";

View file

@ -31,6 +31,10 @@ let eval vars ast =
| 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
| Let (var, e) ->
let v = aux e in
Hashtbl.replace vars var v;
v
| Set_binop_pre (op, l) -> | Set_binop_pre (op, l) ->
let l = let l =
match aux l with match aux l with

View file

@ -78,6 +78,14 @@ let token tok seq =
if x = tok then x, seq if x = tok then x, seq
else expected @@ Token.to_string tok else expected @@ Token.to_string tok
let any_ident seq =
match seq () with
| Seq.Nil -> expected "ident"
| Seq.Cons (x, seq) -> begin match x with
| Token.Ident id -> id, seq
| _ -> unexpected_token x
end
let idents set seq = let idents set seq =
match seq () with match seq () with
| Seq.Nil -> | Seq.Nil ->
@ -122,6 +130,7 @@ let rec expr pre seq =
seq |> oneof [ seq |> oneof [
level; level;
assoc; assoc;
let_value;
value @> binop pre; value @> binop pre;
] ]
@ -151,6 +160,14 @@ and assoc seq =
else else
failwith "Parser.assoc" failwith "Parser.assoc"
(* let_value := "let" ident "=" expr *)
and let_value seq =
let _, seq = ident "let" seq in
let id, seq = any_ident seq in
let _, seq = token Token.Equal seq in
let e, seq = expr min_int seq in
Let (id, e), seq
(* value := int | float | ( expr ) *) (* value := int | float | ( expr ) *)
and value seq = and value seq =
match seq () with match seq () with

View file

@ -10,6 +10,7 @@ type t =
| Percent | Percent
| LParen | LParen
| RParen | RParen
| Equal
let tokens = ref [ let tokens = ref [
"+", Plus; "+", Plus;
@ -20,6 +21,7 @@ let tokens = ref [
"%", Percent; "%", Percent;
"(", LParen; "(", LParen;
")", RParen; ")", RParen;
"=", Equal;
] ]
let to_string = function let to_string = function