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