Add float
This commit is contained in:
parent
61b70f02f1
commit
4efb65c5cd
5 changed files with 29 additions and 12 deletions
2
ast.ml
2
ast.ml
|
@ -1,9 +1,11 @@
|
|||
type typ =
|
||||
| Int of int
|
||||
| Float of float
|
||||
| Unit
|
||||
|
||||
let typ_to_string = function
|
||||
| Int n -> Printf.sprintf "%d" n
|
||||
| Float n -> Printf.sprintf "%f" n
|
||||
| Unit -> "()"
|
||||
|
||||
type binop =
|
||||
|
|
22
eval.ml
22
eval.ml
|
@ -2,18 +2,24 @@ open Ast
|
|||
|
||||
exception Invalid_type
|
||||
|
||||
let arith intf a b =
|
||||
let arith intf floatf a b =
|
||||
match a, b with
|
||||
| Int a, Int b -> Int (intf a b)
|
||||
| Int a, Int b -> begin
|
||||
try Int (intf a b)
|
||||
with Exit -> Float (floatf (float a) (float b))
|
||||
end
|
||||
| Float a, Int b -> Float (floatf a (float b))
|
||||
| Int a, Float b -> Float (floatf (float a) b)
|
||||
| Float a, Float b -> Float (floatf a b)
|
||||
| _ -> raise Invalid_type
|
||||
|
||||
let binop_to_func = function
|
||||
| Add -> arith Int.add
|
||||
| Sub -> arith Int.sub
|
||||
| Mul -> arith Int.mul
|
||||
| Div -> arith Int.div
|
||||
| Mod -> arith Int.rem
|
||||
| _ -> assert false
|
||||
| Add -> arith Int.add Float.add
|
||||
| Sub -> arith Int.sub Float.sub
|
||||
| Mul -> arith Int.mul Float.mul
|
||||
| Div -> arith Int.div Float.div
|
||||
| Mod -> arith Int.rem Float.rem
|
||||
| Exp -> arith (fun _ _ -> raise Exit) Float.pow
|
||||
|
||||
let rec eval = function
|
||||
| Value v -> v
|
||||
|
|
12
lex.ml
12
lex.ml
|
@ -10,6 +10,7 @@ let is_digit c =
|
|||
|
||||
let is_num = function
|
||||
| 'x' -> true
|
||||
| '.' -> true
|
||||
| c -> is_digit c
|
||||
|
||||
let is_whitespace = function
|
||||
|
@ -46,9 +47,14 @@ let tokenize (str : string) : tokens =
|
|||
if is_whitespace x then
|
||||
aux s () (* skip whitespace *)
|
||||
else if is_digit x then
|
||||
let n, s = partition_while is_num seq in
|
||||
let n = int_of_string @@ String.of_seq n in
|
||||
Seq.Cons (Int n, aux s)
|
||||
let n, s = partition_while is_num s in
|
||||
let n = String.of_seq @@ Seq.cons x n in
|
||||
let n =
|
||||
if String.contains n '.' (* float *)
|
||||
then Float (float_of_string n)
|
||||
else Int (int_of_string n)
|
||||
in
|
||||
Seq.Cons (n, aux s)
|
||||
else if is_ident_start x then
|
||||
let id, s = partition_while is_ident seq in
|
||||
let id = String.of_seq id in
|
||||
|
|
|
@ -80,6 +80,7 @@ let parse ts =
|
|||
| Seq.Nil -> assert false
|
||||
| Seq.Cons (x, seq) -> begin match x with
|
||||
| Token.Int n -> Value (Int n), seq
|
||||
| Token.Float n -> Value (Float n), seq
|
||||
| LParen -> expr seq
|
||||
| _ -> unexpected_token x
|
||||
end
|
||||
|
|
4
token.ml
4
token.ml
|
@ -1,5 +1,6 @@
|
|||
type t =
|
||||
| Int of int
|
||||
| Float of float
|
||||
| Ident of string
|
||||
| Plus
|
||||
| Minus
|
||||
|
@ -37,7 +38,8 @@ let find_token seq =
|
|||
(fun (s, t) -> expect_token s t seq)
|
||||
|
||||
let to_string = function
|
||||
| Int n -> string_of_int n
|
||||
| Int n -> Printf.sprintf "[int: %d]" n
|
||||
| Float n -> Printf.sprintf "[float: %f]" n
|
||||
| Ident s -> s
|
||||
| t ->
|
||||
begin match List.find_opt (fun (_, tok) -> t = tok) !tokens with
|
||||
|
|
Loading…
Add table
Reference in a new issue