Add relation operators
This commit is contained in:
parent
a752932913
commit
edeff67edb
4 changed files with 73 additions and 1 deletions
7
ast.ml
7
ast.ml
|
@ -23,6 +23,7 @@ and operator =
|
||||||
| Add | Sub | Mul | Div (* arithmetics *)
|
| Add | Sub | Mul | Div (* arithmetics *)
|
||||||
| Mod (* modular operation *)
|
| Mod (* modular operation *)
|
||||||
| Exp (* exponentation *)
|
| Exp (* exponentation *)
|
||||||
|
| Eq | Neq | GE | LE | GT | LT
|
||||||
| Negate
|
| Negate
|
||||||
|
|
||||||
let op_to_string = function
|
let op_to_string = function
|
||||||
|
@ -32,6 +33,12 @@ let op_to_string = function
|
||||||
| Div -> "/"
|
| Div -> "/"
|
||||||
| Mod -> "%"
|
| Mod -> "%"
|
||||||
| Exp -> "^"
|
| Exp -> "^"
|
||||||
|
| Eq -> "="
|
||||||
|
| Neq -> "<>"
|
||||||
|
| GE -> ">="
|
||||||
|
| LE -> "<="
|
||||||
|
| GT -> ">"
|
||||||
|
| LT -> "<"
|
||||||
| Negate -> "-"
|
| Negate -> "-"
|
||||||
|
|
||||||
let unary op t =
|
let unary op t =
|
||||||
|
|
43
eval.ml
43
eval.ml
|
@ -33,6 +33,7 @@ module Type = struct
|
||||||
| External
|
| External
|
||||||
|
|
||||||
exception Invalid of t
|
exception Invalid of t
|
||||||
|
exception Expected of t
|
||||||
|
|
||||||
let to_string = function
|
let to_string = function
|
||||||
| Int -> "int"
|
| Int -> "int"
|
||||||
|
@ -123,11 +124,45 @@ module Operator = struct
|
||||||
let vf f a b =
|
let vf f a b =
|
||||||
match a, b with
|
match a, b with
|
||||||
| Float a, Float b -> Float (f a b)
|
| Float a, Float b -> Float (f a b)
|
||||||
| _ -> raise @@ Type.Invalid Float
|
| _ -> raise @@ Type.Expected Float
|
||||||
|
|
||||||
|
let vb intf floatf a b =
|
||||||
|
match a, b with
|
||||||
|
| Int a, Int b -> Bool (intf a b)
|
||||||
|
| Float a, Float b -> Bool (floatf a b)
|
||||||
|
| _ -> raise @@ Type.Expected Bool
|
||||||
|
|
||||||
|
let vnot = function
|
||||||
|
| Bool b -> Bool (not b)
|
||||||
|
| _ -> raise @@ Type.Expected Bool
|
||||||
|
|
||||||
|
let map ?intf ?floatf ?boolf v =
|
||||||
|
let app x f = f x in
|
||||||
|
match v with
|
||||||
|
| Int i -> Option.map (app i) intf
|
||||||
|
| Float f -> Option.map (app f) floatf
|
||||||
|
| Bool b -> Option.map (app b) boolf
|
||||||
|
| _ -> invalid_arg "Operator.map"
|
||||||
|
|
||||||
|
let eq = vb Int.equal Float.equal
|
||||||
|
let neq a b = vnot @@ eq a b
|
||||||
|
|
||||||
|
let compare a b =
|
||||||
|
match a, b with
|
||||||
|
| Int a, Int b -> Int.compare a b
|
||||||
|
| Float a, Float b -> Float.compare a b
|
||||||
|
| _ -> invalid_arg "Operator.compare"
|
||||||
|
|
||||||
|
let ge a b = Bool (compare a b >= 0)
|
||||||
|
let le a b = Bool (compare a b <= 0)
|
||||||
|
let gt a b = Bool (compare a b > 0)
|
||||||
|
let lt a b = Bool (compare a b < 0)
|
||||||
|
|
||||||
|
(* operator table *)
|
||||||
let operators =
|
let operators =
|
||||||
let open Type in
|
let open Type in
|
||||||
let ip = Int, Int and fp = Float, Float in
|
let ip = Int, Int and fp = Float, Float in
|
||||||
|
let any f = [ip, f; fp, f] in
|
||||||
[
|
[
|
||||||
Add, [ip, vi Int.add; fp, vf Float.add];
|
Add, [ip, vi Int.add; fp, vf Float.add];
|
||||||
Sub, [ip, vi Int.sub; fp, vf Float.sub];
|
Sub, [ip, vi Int.sub; fp, vf Float.sub];
|
||||||
|
@ -135,6 +170,12 @@ module Operator = struct
|
||||||
Div, [ip, vi Int.div; fp, vf Float.div];
|
Div, [ip, vi Int.div; fp, vf Float.div];
|
||||||
Mod, [ip, vi Int.rem; fp, vf Float.rem];
|
Mod, [ip, vi Int.rem; fp, vf Float.rem];
|
||||||
Exp, [fp, vf Float.pow];
|
Exp, [fp, vf Float.pow];
|
||||||
|
Eq, any eq;
|
||||||
|
Neq, any neq;
|
||||||
|
GE, any ge;
|
||||||
|
LE, any le;
|
||||||
|
GT, any gt;
|
||||||
|
LT, any lt;
|
||||||
]
|
]
|
||||||
|> List.to_seq
|
|> List.to_seq
|
||||||
|> Hashtbl.of_seq
|
|> Hashtbl.of_seq
|
||||||
|
|
12
parser.ml
12
parser.ml
|
@ -23,6 +23,12 @@ let precedence = [
|
||||||
Div, 20;
|
Div, 20;
|
||||||
Mod, 30;
|
Mod, 30;
|
||||||
Exp, 30;
|
Exp, 30;
|
||||||
|
Eq, 100;
|
||||||
|
Neq, 100;
|
||||||
|
GE, 100;
|
||||||
|
LE, 100;
|
||||||
|
GT, 100;
|
||||||
|
LT, 100;
|
||||||
] |> List.to_seq |> Hashtbl.of_seq
|
] |> List.to_seq |> Hashtbl.of_seq
|
||||||
|
|
||||||
let precedence_of op =
|
let precedence_of op =
|
||||||
|
@ -59,6 +65,12 @@ let operators = [
|
||||||
Slash, Div;
|
Slash, Div;
|
||||||
Carret, Exp;
|
Carret, Exp;
|
||||||
Percent, Mod;
|
Percent, Mod;
|
||||||
|
Equal, Eq;
|
||||||
|
Not_equal, Neq;
|
||||||
|
Greater_equal, GE;
|
||||||
|
Less_equal, LE;
|
||||||
|
Greater, GT;
|
||||||
|
Less, LT;
|
||||||
] |> List.to_seq |> Hashtbl.of_seq
|
] |> List.to_seq |> Hashtbl.of_seq
|
||||||
|
|
||||||
let token_to_op tok =
|
let token_to_op tok =
|
||||||
|
|
12
token.ml
12
token.ml
|
@ -12,11 +12,23 @@ type t =
|
||||||
| LParen
|
| LParen
|
||||||
| RParen
|
| RParen
|
||||||
| Equal
|
| Equal
|
||||||
|
| Not_equal
|
||||||
|
| Greater
|
||||||
|
| Less
|
||||||
|
| Greater_equal
|
||||||
|
| Less_equal
|
||||||
| Hash
|
| Hash
|
||||||
| Right_arrow
|
| Right_arrow
|
||||||
|
|
||||||
|
(* list of tokens. because front tokens are detected first, longer
|
||||||
|
* tokens must come earlier than shorter tokens. *)
|
||||||
let tokens = ref [
|
let tokens = ref [
|
||||||
"->", Right_arrow;
|
"->", Right_arrow;
|
||||||
|
"<>", Not_equal;
|
||||||
|
">=", Greater_equal;
|
||||||
|
"<=", Less_equal;
|
||||||
|
">", Greater;
|
||||||
|
"<", Less;
|
||||||
"+", Plus;
|
"+", Plus;
|
||||||
"-", Minus;
|
"-", Minus;
|
||||||
"*", Asterisk;
|
"*", Asterisk;
|
||||||
|
|
Loading…
Add table
Reference in a new issue