Add float

This commit is contained in:
백현웅 2022-01-18 15:33:56 +09:00
parent 61b70f02f1
commit 4efb65c5cd
5 changed files with 29 additions and 12 deletions

2
ast.ml
View file

@ -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
View file

@ -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
View file

@ -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

View file

@ -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

View file

@ -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