Merge Binop and Unary to Operator
This commit is contained in:
parent
bb2ee45c33
commit
282fbfa738
3 changed files with 31 additions and 39 deletions
60
ast.ml
60
ast.ml
|
@ -41,31 +41,13 @@ module Value = struct
|
||||||
| _ -> failwith "Value.promote"
|
| _ -> failwith "Value.promote"
|
||||||
end
|
end
|
||||||
|
|
||||||
module Unary = struct
|
(* operators *)
|
||||||
type t =
|
module Operator = struct
|
||||||
| Negate
|
|
||||||
|
|
||||||
let to_string = function
|
|
||||||
| Negate -> "-"
|
|
||||||
|
|
||||||
let negate = function
|
|
||||||
| Value.Int n -> Value.Int ~-n
|
|
||||||
| Float n -> Value.Float ~-.n
|
|
||||||
| _ -> failwith "Unary.negate"
|
|
||||||
|
|
||||||
let get op _typ =
|
|
||||||
match op with
|
|
||||||
| Negate -> negate
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
(* binary operator *)
|
|
||||||
(* binary operator has type 'a -> 'a -> 'b. *)
|
|
||||||
module Binop = struct
|
|
||||||
type t =
|
type t =
|
||||||
| Add | Sub | Mul | Div (* arithmetics *)
|
| Add | Sub | Mul | Div (* arithmetics *)
|
||||||
| Mod (* modular operation *)
|
| Mod (* modular operation *)
|
||||||
| Exp (* exponentation *)
|
| Exp (* exponentation *)
|
||||||
|
| Negate
|
||||||
|
|
||||||
exception Unavailable of t
|
exception Unavailable of t
|
||||||
|
|
||||||
|
@ -76,6 +58,12 @@ module Binop = struct
|
||||||
| Div -> "/"
|
| Div -> "/"
|
||||||
| Mod -> "%"
|
| Mod -> "%"
|
||||||
| Exp -> "^"
|
| Exp -> "^"
|
||||||
|
| Negate -> "-"
|
||||||
|
|
||||||
|
let negate = function
|
||||||
|
| Value.Int n -> Value.Int ~-n
|
||||||
|
| Float n -> Value.Float ~-.n
|
||||||
|
| _ -> failwith "Operator.negate"
|
||||||
|
|
||||||
let vi f a b =
|
let vi f a b =
|
||||||
let open Value in
|
let open Value in
|
||||||
|
@ -108,7 +96,11 @@ module Binop = struct
|
||||||
| None -> raise @@ Unavailable op
|
| None -> raise @@ Unavailable op
|
||||||
| Some p -> List.map fst p
|
| Some p -> List.map fst p
|
||||||
|
|
||||||
let get op typ =
|
let get_unary = function
|
||||||
|
| Negate -> negate
|
||||||
|
| op -> raise @@ Unavailable op
|
||||||
|
|
||||||
|
let get_binary op typ =
|
||||||
Hashtbl.find operators op
|
Hashtbl.find operators op
|
||||||
|> List.assoc_opt typ
|
|> List.assoc_opt typ
|
||||||
end
|
end
|
||||||
|
@ -117,12 +109,12 @@ type t =
|
||||||
| Value of Value.t
|
| Value of Value.t
|
||||||
| Var of string
|
| Var of string
|
||||||
| Let of string * t
|
| Let of string * t
|
||||||
| Unary of Unary.t * t
|
| Unary of Operator.t * t
|
||||||
| Binop of t * Binop.t * t
|
| Binop of t * Operator.t * t
|
||||||
| Set_binop_pre of Binop.t * t
|
| Set_binop_pre of Operator.t * t
|
||||||
| Get_binop_pre of Binop.t
|
| Get_binop_pre of Operator.t
|
||||||
| Set_binop_aso of Binop.t * string
|
| Set_binop_aso of Operator.t * string
|
||||||
| Get_binop_aso of Binop.t
|
| Get_binop_aso of Operator.t
|
||||||
|
|
||||||
let value v = Value v
|
let value v = Value v
|
||||||
|
|
||||||
|
@ -144,22 +136,22 @@ let print ast =
|
||||||
aux e;
|
aux e;
|
||||||
pr ")"
|
pr ")"
|
||||||
| Unary (op, t) -> begin
|
| Unary (op, t) -> begin
|
||||||
let op = Unary.to_string op in
|
let op = Operator.to_string op in
|
||||||
pr "(%s " op; aux t; pr ")";
|
pr "(%s " op; aux t; pr ")";
|
||||||
end
|
end
|
||||||
| Binop (left, op, right) -> begin
|
| Binop (left, op, right) -> begin
|
||||||
let op = Binop.to_string op in
|
let op = Operator.to_string op in
|
||||||
pr "(%s " op; aux left; pr " "; aux right; pr ")";
|
pr "(%s " op; aux left; pr " "; aux right; pr ")";
|
||||||
end
|
end
|
||||||
| Set_binop_pre (op, pre) ->
|
| Set_binop_pre (op, pre) ->
|
||||||
pr "(set_pre %s " (Binop.to_string op);
|
pr "(set_pre %s " (Operator.to_string op);
|
||||||
aux pre;
|
aux pre;
|
||||||
pr ")"
|
pr ")"
|
||||||
| Get_binop_pre op ->
|
| Get_binop_pre op ->
|
||||||
pr "(get_pre %s)" (Binop.to_string op)
|
pr "(get_pre %s)" (Operator.to_string op)
|
||||||
| Set_binop_aso (op, aso) ->
|
| Set_binop_aso (op, aso) ->
|
||||||
pr "(set_assoc %s %s)" (Binop.to_string op) aso
|
pr "(set_assoc %s %s)" (Operator.to_string op) aso
|
||||||
| Get_binop_aso op ->
|
| Get_binop_aso op ->
|
||||||
pr "(get_pre %s)" (Binop.to_string op)
|
pr "(get_pre %s)" (Operator.to_string op)
|
||||||
in
|
in
|
||||||
aux ast; pr "\n"
|
aux ast; pr "\n"
|
||||||
|
|
6
eval.ml
6
eval.ml
|
@ -5,7 +5,7 @@ exception No_operation
|
||||||
exception No_such_variable of string
|
exception No_such_variable of string
|
||||||
|
|
||||||
let resolve_type op tp =
|
let resolve_type op tp =
|
||||||
let optypes = Binop.get_types op in
|
let optypes = Operator.get_types op in
|
||||||
let q = Queue.create () in
|
let q = Queue.create () in
|
||||||
let rec aux (t1, t2) =
|
let rec aux (t1, t2) =
|
||||||
if List.mem (t1, t2) optypes then
|
if List.mem (t1, t2) optypes then
|
||||||
|
@ -30,7 +30,7 @@ let rec binop op l r =
|
||||||
in
|
in
|
||||||
let l = promote_until t1 l
|
let l = promote_until t1 l
|
||||||
and r = promote_until t2 r in
|
and r = promote_until t2 r in
|
||||||
match Binop.get op (t1, t2) with
|
match Operator.get_binary op (t1, t2) with
|
||||||
| None -> begin
|
| None -> begin
|
||||||
try binop op (promote l) (promote r)
|
try binop op (promote l) (promote r)
|
||||||
with _ -> raise No_operation
|
with _ -> raise No_operation
|
||||||
|
@ -46,7 +46,7 @@ let eval vars ast =
|
||||||
end
|
end
|
||||||
| Unary (op, t) ->
|
| Unary (op, t) ->
|
||||||
let t = aux t in
|
let t = aux t in
|
||||||
let op = Unary.get op (Value.typeof t) in
|
let op = Operator.get_unary op in
|
||||||
op t
|
op t
|
||||||
| 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
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
open Ast
|
open Ast
|
||||||
open Ast.Binop
|
open Ast.Operator
|
||||||
|
|
||||||
module S = Set.Make(String)
|
module S = Set.Make(String)
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ and unary seq =
|
||||||
| Seq.Nil -> raise End_of_tokens
|
| Seq.Nil -> raise End_of_tokens
|
||||||
| Seq.Cons (x, seq) ->
|
| Seq.Cons (x, seq) ->
|
||||||
if x = Minus
|
if x = Minus
|
||||||
then Unary.Negate, seq
|
then Negate, seq
|
||||||
else expected "minus"
|
else expected "minus"
|
||||||
in
|
in
|
||||||
let v, seq = value seq in
|
let v, seq = value seq in
|
||||||
|
|
Loading…
Add table
Reference in a new issue