diff --git a/ocaml/boot/menhir/parser.ml b/ocaml/boot/menhir/parser.ml index 7350b9b6ef6..eb61b720129 100644 --- a/ocaml/boot/menhir/parser.ml +++ b/ocaml/boot/menhir/parser.ml @@ -1166,7 +1166,7 @@ end = struct let assert_unboxed_literals ~loc = Language_extension.( - Jane_syntax_parsing.assert_extension_enabled ~loc Layouts Beta) + Jane_syntax_parsing.assert_extension_enabled ~loc Layouts Alpha) let unboxed ~loc x = assert_unboxed_literals ~loc:(make_loc loc); diff --git a/ocaml/lambda/matching.ml b/ocaml/lambda/matching.ml index f74f3abf4d7..9a5cf59384d 100644 --- a/ocaml/lambda/matching.ml +++ b/ocaml/lambda/matching.ml @@ -1171,6 +1171,7 @@ let can_group discr pat = | Constant (Const_char _), Constant (Const_char _) | Constant (Const_string _), Constant (Const_string _) | Constant (Const_float _), Constant (Const_float _) + | Constant (Const_unboxed_float _), Constant (Const_unboxed_float _) | Constant (Const_int32 _), Constant (Const_int32 _) | Constant (Const_int64 _), Constant (Const_int64 _) | Constant (Const_nativeint _), Constant (Const_nativeint _) -> @@ -1194,7 +1195,7 @@ let can_group discr pat = ( Any | Constant ( Const_int _ | Const_char _ | Const_string _ | Const_float _ - | Const_int32 _ | Const_int64 _ | Const_nativeint _ ) + | Const_unboxed_float _ | Const_int32 _ | Const_int64 _ | Const_nativeint _ ) | Construct _ | Tuple _ | Record _ | Array _ | Variant _ | Lazy ) ) -> false @@ -2536,7 +2537,7 @@ let rec do_tests_fail value_kind loc fail tst arg = function | [] -> fail | (c, act) :: rem -> Lifthenelse - ( Lprim (tst, [ arg; Lconst (Const_base c) ], loc), + ( Lprim (tst, [ arg; c ], loc), do_tests_fail value_kind loc fail tst arg rem, act, value_kind ) @@ -2545,15 +2546,16 @@ let rec do_tests_nofail value_kind loc tst arg = function | [ (_, act) ] -> act | (c, act) :: rem -> Lifthenelse - ( Lprim (tst, [ arg; Lconst (Const_base c) ], loc), + ( Lprim (tst, [ arg; c ], loc), do_tests_nofail value_kind loc tst arg rem, act, value_kind ) -let make_test_sequence value_kind loc fail tst lt_tst arg const_lambda_list = +let make_test_sequence value_kind loc fail tst lt_tst arg const_lambda_list transl_const = let const_lambda_list = sort_lambda_list const_lambda_list in let hs, const_lambda_list, fail = share_actions_tree value_kind const_lambda_list fail in + let const_lambda_list = List.map (fun (c, l) -> transl_const c, l) const_lambda_list in let rec make_test_sequence const_lambda_list = if List.length const_lambda_list >= 4 && lt_tst <> Pignore then split_sequence const_lambda_list @@ -2566,7 +2568,7 @@ let make_test_sequence value_kind loc fail tst lt_tst arg const_lambda_list = rev_split_at (List.length const_lambda_list / 2) const_lambda_list in Lifthenelse - ( Lprim (lt_tst, [ arg; Lconst (Const_base (fst (List.hd list2))) ], loc), + ( Lprim (lt_tst, [ arg; fst (List.hd list2) ], loc), make_test_sequence list1, make_test_sequence list2, value_kind ) in @@ -2963,6 +2965,16 @@ let mk_failaction_pos partial seen ctx defs = let combine_constant value_kind loc arg cst partial ctx def (const_lambda_list, total, _pats) = let fail, local_jumps = mk_failaction_neg partial ctx def in + let transl_const = function + | Const_int c -> Lconst(Const_base (Const_int c)) + | Const_char c -> Lconst(Const_base (Const_char c)) + | Const_string (s,loc,d) -> Lconst(Const_base (Const_string (s,loc,d))) + | Const_float c -> Lconst(Const_base (Const_float c)) + | Const_int32 c -> Lconst(Const_base (Const_int32 c)) + | Const_int64 c -> Lconst(Const_base (Const_int64 c)) + | Const_nativeint c -> Lconst(Const_base (Const_nativeint c)) + | Const_unboxed_float f -> Lconst (Const_base (Const_float f)) + in let lambda1 = match cst with | Const_int _ -> @@ -3002,22 +3014,28 @@ let combine_constant value_kind loc arg cst partial ctx def | Const_float _ -> make_test_sequence value_kind loc fail (Pfloatcomp CFneq) (Pfloatcomp CFlt) arg - const_lambda_list + const_lambda_list transl_const + | Const_unboxed_float _ -> + make_test_sequence value_kind loc fail + (Pfloatcomp CFneq) + (Pfloatcomp CFlt) + (Lprim (Pbox_float Lambda.alloc_local, [arg], loc)) + const_lambda_list transl_const | Const_int32 _ -> make_test_sequence value_kind loc fail (Pbintcomp (Pint32, Cne)) (Pbintcomp (Pint32, Clt)) - arg const_lambda_list + arg const_lambda_list transl_const | Const_int64 _ -> make_test_sequence value_kind loc fail (Pbintcomp (Pint64, Cne)) (Pbintcomp (Pint64, Clt)) - arg const_lambda_list + arg const_lambda_list transl_const | Const_nativeint _ -> make_test_sequence value_kind loc fail (Pbintcomp (Pnativeint, Cne)) (Pbintcomp (Pnativeint, Clt)) - arg const_lambda_list + arg const_lambda_list transl_const in (lambda1, Jumps.union local_jumps total) diff --git a/ocaml/lambda/translcore.ml b/ocaml/lambda/translcore.ml index 6a84c44d9e8..c5ae7452213 100644 --- a/ocaml/lambda/translcore.ml +++ b/ocaml/lambda/translcore.ml @@ -390,7 +390,18 @@ and transl_exp0 ~in_new_scope ~scopes sort e = transl_ident (of_location ~scopes e.exp_loc) e.exp_env e.exp_type path desc kind | Texp_constant cst -> - Lconst(Const_base cst) + begin match cst with + | Const_int c -> Lconst(Const_base (Const_int c)) + | Const_char c -> Lconst(Const_base (Const_char c)) + | Const_string (s,loc,d) -> Lconst(Const_base (Const_string (s,loc,d))) + | Const_float c -> Lconst(Const_base (Const_float c)) + | Const_int32 c -> Lconst(Const_base (Const_int32 c)) + | Const_int64 c -> Lconst(Const_base (Const_int64 c)) + | Const_nativeint c -> Lconst(Const_base (Const_nativeint c)) + | Const_unboxed_float f -> + Lprim (Punbox_float, [Lconst (Const_base (Const_float f))], + of_location ~scopes e.exp_loc) + end | Texp_let(rec_flag, pat_expr_list, body) -> let return_layout = layout_exp sort body in transl_let ~scopes ~return_layout rec_flag pat_expr_list diff --git a/ocaml/parsing/parser.mly b/ocaml/parsing/parser.mly index 6468bd06495..470d7bd9728 100644 --- a/ocaml/parsing/parser.mly +++ b/ocaml/parsing/parser.mly @@ -941,7 +941,7 @@ end = struct let assert_unboxed_literals ~loc = Language_extension.( - Jane_syntax_parsing.assert_extension_enabled ~loc Layouts Beta) + Jane_syntax_parsing.assert_extension_enabled ~loc Layouts Alpha) let unboxed ~loc x = assert_unboxed_literals ~loc:(make_loc loc); diff --git a/ocaml/testsuite/tests/typing-layouts-float64/alloc.ml b/ocaml/testsuite/tests/typing-layouts-float64/alloc.ml index 3587110852b..5252eb85930 100644 --- a/ocaml/testsuite/tests/typing-layouts-float64/alloc.ml +++ b/ocaml/testsuite/tests/typing-layouts-float64/alloc.ml @@ -1,6 +1,6 @@ (* TEST * flambda2 - flags = "-extension layouts_beta" + flags = "-extension layouts_alpha" ** native *) @@ -167,3 +167,18 @@ let _ = let _ = measure_alloc_value (fun () -> cse_test false r) in let allocs = get_exact_allocations () in Printf.printf "CSE test (0 bytes):\n allocated bytes: %.2f\n" allocs + +let[@inline never] literal_test x y = + let open Float_u in + (#1. + x) * (y - #4.) / (#3. ** #1.) + +let print_allocs s = + let allocs = get_exact_allocations () in + Printf.printf + "%s:\n allocated bytes: %.2f\n" + s allocs + +let _ = + let r = measure_alloc (fun () -> literal_test #2. #3.) in + assert (Float_u.equal r (-#1.)); + print_allocs "Float literals"; diff --git a/ocaml/testsuite/tests/typing-layouts-float64/alloc.reference b/ocaml/testsuite/tests/typing-layouts-float64/alloc.reference index 8cd7f847e22..23a3a02bf88 100644 --- a/ocaml/testsuite/tests/typing-layouts-float64/alloc.reference +++ b/ocaml/testsuite/tests/typing-layouts-float64/alloc.reference @@ -18,3 +18,5 @@ Manipulation (0 bytes): d: 45.14 CSE test (0 bytes): allocated bytes: 0.00 +Float literals: + allocated bytes: 0.00 diff --git a/ocaml/testsuite/tests/typing-layouts/literals.ml b/ocaml/testsuite/tests/typing-layouts/literals.ml index 125c9b9890c..bb9541234c1 100644 --- a/ocaml/testsuite/tests/typing-layouts/literals.ml +++ b/ocaml/testsuite/tests/typing-layouts/literals.ml @@ -3,87 +3,70 @@ * expect *) +(*****************************************) +(* Prelude: Functions on unboxed floats. *) + +module Float_u = Stdlib__Float_u + +let test s f = Format.printf "%s: %f\n" s (Float_u.to_float f); Format.print_flush () + +[%%expect{| +module Float_u = Stdlib__Float_u +val test : string -> float# -> unit = +|}] + (*****************************************) (* Expressions *) -let e = #2.718281828459045 +let () = test "e" #2.718281828459045 + [%%expect{| -Line 1, characters 8-26: -1 | let e = #2.718281828459045 - ^^^^^^^^^^^^^^^^^^ -Error: Unboxed float literals aren't supported yet. +e: 2.718282 |}] -let negative_one_half = -#0.5 +let () = test "negative_one_half" (-#0.5) [%%expect{| -Line 1, characters 24-29: -1 | let negative_one_half = -#0.5 - ^^^^^ -Error: Unboxed float literals aren't supported yet. +negative_one_half: -0.500000 |}] -let negative_one_half = - #0.5 +let () = test "negative_one_half" (- #0.5) [%%expect{| -Line 1, characters 24-30: -1 | let negative_one_half = - #0.5 - ^^^^^^ -Error: Unboxed float literals aren't supported yet. +negative_one_half: -0.500000 |}] -let negative_one_half = -.#0.5 +let () = test "negative_one_half" (-.#0.5) [%%expect{| -Line 1, characters 24-30: -1 | let negative_one_half = -.#0.5 - ^^^^^^ -Error: Unboxed float literals aren't supported yet. +negative_one_half: -0.500000 |}] -let negative_one_half = -. #0.5 +let () = test "negative_one_half" (-. #0.5) [%%expect{| -Line 1, characters 24-31: -1 | let negative_one_half = -. #0.5 - ^^^^^^^ -Error: Unboxed float literals aren't supported yet. +negative_one_half: -0.500000 |}] -let positive_one_dot = +#1. +let () = test "positive_one_dot" (+#1.) [%%expect{| -Line 1, characters 23-27: -1 | let positive_one_dot = +#1. - ^^^^ -Error: Unboxed float literals aren't supported yet. +positive_one_dot: 1.000000 |}] -let positive_one_dot = + #1. +let () = test "positive_one_dot" (+ #1.) [%%expect{| -Line 1, characters 23-28: -1 | let positive_one_dot = + #1. - ^^^^^ -Error: Unboxed float literals aren't supported yet. +positive_one_dot: 1.000000 |}] -let positive_one_dot = +.#1. +let () = test "positive_one_dot" (+.#1.) [%%expect{| -Line 1, characters 23-28: -1 | let positive_one_dot = +.#1. - ^^^^^ -Error: Unboxed float literals aren't supported yet. +positive_one_dot: 1.000000 |}] -let positive_one_dot = +. #1. +let () = test "positive_one_dot" (+. #1.) [%%expect{| -Line 1, characters 23-29: -1 | let positive_one_dot = +. #1. - ^^^^^^ -Error: Unboxed float literals aren't supported yet. +positive_one_dot: 1.000000 |}] -let one_billion = #1e9 +let () = test "one_billion" (#1e9) [%%expect{| -Line 1, characters 18-22: -1 | let one_billion = #1e9 - ^^^^ -Error: Unboxed float literals aren't supported yet. +one_billion: 1000000000.000000 |}] let zero = #0n @@ -150,28 +133,22 @@ Line 1, characters 26-36: Error: Unboxed int literals aren't supported yet. |}] -let one_twenty_seven_point_two_five_in_floating_hex = #0x7f.4 +let () = test "one_twenty_seven_point_two_five_in_floating_hex" (#0x7f.4) [%%expect{| -Line 1, characters 54-61: -1 | let one_twenty_seven_point_two_five_in_floating_hex = #0x7f.4 - ^^^^^^^ -Error: Unboxed float literals aren't supported yet. +one_twenty_seven_point_two_five_in_floating_hex: 127.250000 |}] -let five_point_three_seven_five_in_floating_hexponent = #0xa.cp-1 +let () = test "five_point_three_seven_five_in_floating_hexponent" (#0xa.cp-1) [%%expect{| -Line 1, characters 56-65: -1 | let five_point_three_seven_five_in_floating_hexponent = #0xa.cp-1 - ^^^^^^^^^ -Error: Unboxed float literals aren't supported yet. +five_point_three_seven_five_in_floating_hexponent: 5.375000 |}] -let unknown_floating_point_suffix = #0.P +let () = test "unknown_floating_point_suffix" (#0.P) [%%expect{| -Line 1, characters 36-40: -1 | let unknown_floating_point_suffix = #0.P - ^^^^ -Error: Unboxed float literals aren't supported yet. +Line 1, characters 46-52: +1 | let () = test "unknown_floating_point_suffix" (#0.P) + ^^^^^^ +Error: Unknown modifier 'P' for literal #0.P |}] (*****************************************) @@ -201,17 +178,51 @@ let f x = f #5.;; [%%expect {| -Line 3, characters 4-7: -3 | | #4. -> `Four - ^^^ -Error: Unboxed float literals aren't supported yet. +val f : float# -> [> `Five | `Four | `Other ] = +- : [> `Five | `Four | `Other ] = `Five +|}];; + +let f x = + match x with + | #4. -> #0. + | #5. -> #1. + | x -> x +;; + +test "result" (f #7.);; +[%%expect {| +val f : float# -> float# = +result: 7.000000 +- : unit = () |}];; +let f x = + match x with + | #4. -> #0. + | #5. -> #1. +;; + +test "result" (f #7.);; +(* This is here to test the [partial-match] warning *) +[%%expect {| +Lines 2-4, characters 2-14: +2 | ..match x with +3 | | #4. -> #0. +4 | | #5. -> #1. +Warning 8 [partial-match]: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +#0. + +val f : float# -> float# = +Exception: Match_failure ("", 2, 2). +|}];; + + (*****************************************) (* Lexing edge cases *) (* Unboxed literals at the beginning of the line aren't directives. *) -let f _ _ = ();; +let f (_ : float#) _ = ();; let () = f #2. #2L @@ -222,13 +233,14 @@ let () = f ;; [%%expect{| -val f : 'a -> 'b -> unit = -Line 3, characters 0-3: -3 | #2. +val f : float# -> 'a -> unit = +Line 4, characters 0-3: +4 | #2L ^^^ -Error: Unboxed float literals aren't supported yet. +Error: Unboxed int literals aren't supported yet. |}];; +let f _ _ = ();; let () = f (* This lexes as a directive. #2 is not a valid unboxed int literal anyway, as it lacks a suffix. @@ -239,4 +251,5 @@ let () = f ;; [%%expect{| +val f : 'a -> 'b -> unit = |}];; diff --git a/ocaml/testsuite/tests/typing-layouts/literals_native.ml b/ocaml/testsuite/tests/typing-layouts/literals_native.ml new file mode 100644 index 00000000000..a59fcbdd62b --- /dev/null +++ b/ocaml/testsuite/tests/typing-layouts/literals_native.ml @@ -0,0 +1,61 @@ +(* TEST + flags = "-extension layouts_alpha" + * native + * bytecode +*) + +(*****************************************) +(* Prelude: Functions on unboxed floats. *) + +module Float_u = struct + include Stdlib__Float_u + + let ( + ) = add + let ( - ) = sub + let ( * ) = mul + let ( / ) = div + let ( ** ) = pow + let ( > ) x y = (compare x y) > 0 +end + +let test s f = Format.printf "%s: %f\n%!" s (Float_u.to_float f) + +(*****************************************) +(* Expressions *) + +let () = test "e" #2.718281828459045 +let () = test "negative_one_half" (-#0.5) +let () = test "negative_one_half" (- #0.5) +let () = test "negative_one_half" (-.#0.5) +let () = test "negative_one_half" (-. #0.5) +let () = test "positive_one_dot" (+#1.) +let () = test "positive_one_dot" (+ #1.) +let () = test "positive_one_dot" (+.#1.) +let () = test "positive_one_dot" (+. #1.) +let () = test "one_billion" (#1e9) +let () = test "one_twenty_seven_point_two_five_in_floating_hex" (#0x7f.4) +let () = test "five_point_three_seven_five_in_floating_hexponent" (#0xa.cp-1) + +(*****************************************) +(* Patterns *) + +let f x = + match x with + | #4. -> `Four + | #5. -> `Five + | _ -> `Other +;; + +let () = + match f #5. with + | `Five -> () + | _ -> assert false;; + +let f x = + match x with + | #4. -> #0. + | #5. -> #1. + | x -> x +;; + +test "result" (f #7.);; diff --git a/ocaml/testsuite/tests/typing-layouts/literals_native.reference b/ocaml/testsuite/tests/typing-layouts/literals_native.reference new file mode 100644 index 00000000000..153a1973dd3 --- /dev/null +++ b/ocaml/testsuite/tests/typing-layouts/literals_native.reference @@ -0,0 +1,13 @@ +e: 2.718282 +negative_one_half: -0.500000 +negative_one_half: -0.500000 +negative_one_half: -0.500000 +negative_one_half: -0.500000 +positive_one_dot: 1.000000 +positive_one_dot: 1.000000 +positive_one_dot: 1.000000 +positive_one_dot: 1.000000 +one_billion: 1000000000.000000 +one_twenty_seven_point_two_five_in_floating_hex: 127.250000 +five_point_three_seven_five_in_floating_hexponent: 5.375000 +result: 7.000000 diff --git a/ocaml/typing/parmatch.ml b/ocaml/typing/parmatch.ml index 1346b6e95ca..c77dd63991a 100644 --- a/ocaml/typing/parmatch.ml +++ b/ocaml/typing/parmatch.ml @@ -131,6 +131,7 @@ let all_coherent column = | Const_int64 _, Const_int64 _ | Const_nativeint _, Const_nativeint _ | Const_float _, Const_float _ + | Const_unboxed_float _, Const_unboxed_float _ | Const_string _, Const_string _ -> true | ( Const_char _ | Const_int _ @@ -138,6 +139,7 @@ let all_coherent column = | Const_int64 _ | Const_nativeint _ | Const_float _ + | Const_unboxed_float _ | Const_string _), _ -> false end | Tuple l1, Tuple l2 -> l1 = l2 @@ -240,6 +242,7 @@ let is_absent_pat d = let const_compare x y = match x,y with + | Const_unboxed_float f1, Const_unboxed_float f2 | Const_float f1, Const_float f2 -> Stdlib.compare (float_of_string f1) (float_of_string f2) | Const_string (s1, _, _), Const_string (s2, _, _) -> @@ -248,6 +251,7 @@ let const_compare x y = |Const_char _ |Const_string (_, _, _) |Const_float _ + |Const_unboxed_float _ |Const_int32 _ |Const_int64 _ |Const_nativeint _ @@ -1044,6 +1048,12 @@ let build_other ext env = | _ -> assert false) (function f -> Tpat_constant(Const_float (string_of_float f))) 0.0 (fun f -> f +. 1.0) d env + | Constant Const_unboxed_float _ -> + build_other_constant + (function Constant(Const_unboxed_float f) -> float_of_string f + | _ -> assert false) + (function f -> Tpat_constant(Const_unboxed_float (string_of_float f))) + 0.0 (fun f -> f +. 1.0) d env | Array (am, arg_sort, _) -> let all_lengths = List.map @@ -2074,7 +2084,7 @@ let inactive ~partial pat = | Tpat_constant c -> begin match c with | Const_string _ - | Const_int _ | Const_char _ | Const_float _ + | Const_int _ | Const_char _ | Const_float _ | Const_unboxed_float _ | Const_int32 _ | Const_int64 _ | Const_nativeint _ -> true end | Tpat_tuple ps | Tpat_construct (_, _, ps, _) diff --git a/ocaml/typing/printpat.ml b/ocaml/typing/printpat.ml index 846de53c87a..aaebd504a2d 100644 --- a/ocaml/typing/printpat.ml +++ b/ocaml/typing/printpat.ml @@ -29,6 +29,14 @@ let pretty_const c = match c with | Const_char c -> Printf.sprintf "%C" c | Const_string (s, _, _) -> Printf.sprintf "%S" s | Const_float f -> Printf.sprintf "%s" f +| Const_unboxed_float f -> + let s = + match String.split_on_char '-' f with + | [""; f] -> "-#" ^ f + | [f] -> "#" ^ f + | _ -> assert false + in + Printf.sprintf "%s" s | Const_int32 i -> Printf.sprintf "%ldl" i | Const_int64 i -> Printf.sprintf "%LdL" i | Const_nativeint i -> Printf.sprintf "%ndn" i diff --git a/ocaml/typing/printpat.mli b/ocaml/typing/printpat.mli index 1865a2ab298..7334f588ce6 100644 --- a/ocaml/typing/printpat.mli +++ b/ocaml/typing/printpat.mli @@ -16,7 +16,7 @@ val pretty_const - : Asttypes.constant -> string + : Typedtree.constant -> string val top_pretty : Format.formatter -> 'k Typedtree.general_pattern -> unit val pretty_pat diff --git a/ocaml/typing/printtyped.ml b/ocaml/typing/printtyped.ml index 4202676fbb2..b9cfbdf2503 100644 --- a/ocaml/typing/printtyped.ml +++ b/ocaml/typing/printtyped.ml @@ -67,6 +67,7 @@ let fmt_constant f x = | Const_string (s, strloc, Some delim) -> fprintf f "Const_string (%S,%a,Some %S)" s fmt_location strloc delim | Const_float (s) -> fprintf f "Const_float %s" s + | Const_unboxed_float (s) -> fprintf f "Const_unboxed_float %s" s | Const_int32 (i) -> fprintf f "Const_int32 %ld" i | Const_int64 (i) -> fprintf f "Const_int64 %Ld" i | Const_nativeint (i) -> fprintf f "Const_nativeint %nd" i diff --git a/ocaml/typing/typecore.ml b/ocaml/typing/typecore.ml index 527e75b90ee..ebb54d2b800 100644 --- a/ocaml/typing/typecore.ml +++ b/ocaml/typing/typecore.ml @@ -201,7 +201,6 @@ type error = | Exclave_in_nontail_position | Exclave_returns_not_local | Unboxed_int_literals_not_supported - | Unboxed_float_literals_not_supported | Function_type_not_rep of type_expr * Jkind.Violation.t exception Error of Location.t * Env.t * error @@ -589,22 +588,17 @@ let optimise_allocations () = (* Typing of constants *) -let type_constant = function +let type_constant: Typedtree.constant -> type_expr = function Const_int _ -> instance Predef.type_int | Const_char _ -> instance Predef.type_char | Const_string _ -> instance Predef.type_string | Const_float _ -> instance Predef.type_float + | Const_unboxed_float _ -> instance Predef.type_unboxed_float | Const_int32 _ -> instance Predef.type_int32 | Const_int64 _ -> instance Predef.type_int64 | Const_nativeint _ -> instance Predef.type_nativeint -let type_constant_unboxed env loc - : Jane_syntax.Layouts.constant -> _ = function - | Float _ -> raise (Error (loc, env, Unboxed_float_literals_not_supported)) - (* CR layouts v2.5: This should be [instance Predef.type_unboxed_float] *) - | Integer _ -> raise (Error (loc, env, Unboxed_int_literals_not_supported)) - -let constant_integer i ~suffix : (Asttypes.constant, error) result = +let constant_integer i ~suffix : (Typedtree.constant, error) result = match suffix with | 'l' -> begin @@ -623,7 +617,7 @@ let constant_integer i ~suffix : (Asttypes.constant, error) result = end | c -> Error (Unknown_literal (i, c)) -let constant : Parsetree.constant -> (Asttypes.constant, error) result = +let constant : Parsetree.constant -> (Typedtree.constant, error) result = function | Pconst_integer (i, Some suffix) -> constant_integer i ~suffix | Pconst_integer (i,None) -> @@ -641,22 +635,15 @@ let constant_or_raise env loc cst = | Ok c -> c | Error err -> raise (Error (loc, env, err)) -let unboxed_constant : - type a. Jane_syntax.Layouts.constant -> (a, error) result +let unboxed_constant : Jane_syntax.Layouts.constant -> (Typedtree.constant, error) result = function - | Float (_, None) -> Error Unboxed_float_literals_not_supported + | Float (f, None) -> Ok (Const_unboxed_float f) | Float (x, Some c) -> Error (Unknown_literal ("#" ^ x, c)) | Integer (_, _) -> Error Unboxed_int_literals_not_supported -(* CR layouts v2.5: this is missing the part where we actually typecheck - unboxed literals. -*) let unboxed_constant_or_raise env loc cst = - let open struct - type nothing = | - end in match unboxed_constant cst with - | Ok (_ : nothing) -> . + | Ok c -> c | Error err -> raise (Error (loc, env, err)) (* Specific version of type_option, using newty rather than newgenty *) @@ -2307,11 +2294,11 @@ and type_pat_aux | Jpat_immutable_array (Iapat_immutable_array spl) -> type_pat_array Immutable spl attrs | Jpat_layout (Lpat_constant cst) -> - let desc = unboxed_constant_or_raise !env loc cst in + let cst = unboxed_constant_or_raise !env loc cst in rvp @@ solve_expected { - pat_desc = desc; + pat_desc = Tpat_constant cst; pat_loc = loc; pat_extra=[]; - pat_type = type_constant_unboxed !env loc cst; + pat_type = type_constant cst; pat_attributes = attrs; pat_env = !env } end @@ -3021,7 +3008,11 @@ let rec check_counter_example_pat end | Tpat_alias (p, _, _, _, _) -> check_rec ~info p expected_ty k | Tpat_constant cst -> - let cst = constant_or_raise !env loc (Untypeast.constant cst) in + let cst = + match Untypeast.constant cst with + | `Parsetree cst -> constant_or_raise !env loc cst + | `Jane_syntax cst -> unboxed_constant_or_raise !env loc cst + in k @@ solve_expected (mp (Tpat_constant cst) ~pat_type:(type_constant cst)) | Tpat_tuple tpl -> let tpl_ann = @@ -8343,11 +8334,12 @@ and type_jkind_expr name (Some jkind_annot) sbody and type_unboxed_constant ~loc ~env ~rue ~attributes cst = + let cst = unboxed_constant_or_raise env loc cst in rue { - exp_desc = unboxed_constant_or_raise env loc cst; + exp_desc = Texp_constant cst; exp_loc = loc; exp_extra = []; - exp_type = type_constant_unboxed env loc cst; + exp_type = type_constant cst; exp_attributes = attributes; exp_env = env } @@ -9274,9 +9266,6 @@ let report_error ~loc env = function | Unboxed_int_literals_not_supported -> Location.errorf ~loc "@[Unboxed int literals aren't supported yet.@]" - | Unboxed_float_literals_not_supported -> - Location.errorf ~loc - "@[Unboxed float literals aren't supported yet.@]" | Function_type_not_rep (ty,violation) -> Location.errorf ~loc "@[Function arguments and returns must be representable.@]@ %a" diff --git a/ocaml/typing/typecore.mli b/ocaml/typing/typecore.mli index dc2416ef24d..01b62aa0ba0 100644 --- a/ocaml/typing/typecore.mli +++ b/ocaml/typing/typecore.mli @@ -282,7 +282,6 @@ type error = | Exclave_in_nontail_position | Exclave_returns_not_local | Unboxed_int_literals_not_supported - | Unboxed_float_literals_not_supported | Function_type_not_rep of type_expr * Jkind.Violation.t exception Error of Location.t * Env.t * error @@ -312,7 +311,7 @@ val type_package: (Env.t -> Parsetree.module_expr -> Path.t -> (Longident.t * type_expr) list -> Typedtree.module_expr * (Longident.t * type_expr) list) ref -val constant: Parsetree.constant -> (Asttypes.constant, error) result +val constant: Parsetree.constant -> (Typedtree.constant, error) result val check_recursive_bindings : Env.t -> Typedtree.value_binding list -> unit val check_recursive_class_bindings : diff --git a/ocaml/typing/typedtree.ml b/ocaml/typing/typedtree.ml index e7a600ef614..7518a5d1af2 100644 --- a/ocaml/typing/typedtree.ml +++ b/ocaml/typing/typedtree.ml @@ -18,6 +18,16 @@ open Asttypes open Types +type constant = + Const_int of int + | Const_char of char + | Const_string of string * Location.t * string option + | Const_float of string + | Const_unboxed_float of string + | Const_int32 of int32 + | Const_int64 of int64 + | Const_nativeint of nativeint + module Uid = Shape.Uid (* Value expressions for the core language *) diff --git a/ocaml/typing/typedtree.mli b/ocaml/typing/typedtree.mli index 95162da0c9f..c816d216615 100644 --- a/ocaml/typing/typedtree.mli +++ b/ocaml/typing/typedtree.mli @@ -23,6 +23,20 @@ open Asttypes +(* We define a new constant type that can represent unboxed values. + This is currently used only in [Typedtree], but the long term goal + is to share this definition with [Lambda] and completely replace the + usage of [Asttypes.constant] *) +type constant = + Const_int of int + | Const_char of char + | Const_string of string * Location.t * string option + | Const_float of string + | Const_unboxed_float of string + | Const_int32 of int32 + | Const_int64 of int64 + | Const_nativeint of nativeint + module Uid = Shape.Uid (* Value expressions for the core language *) diff --git a/ocaml/typing/untypeast.ml b/ocaml/typing/untypeast.ml index 3cf255df765..3d8817853fa 100644 --- a/ocaml/typing/untypeast.ml +++ b/ocaml/typing/untypeast.ml @@ -131,13 +131,14 @@ let rec extract_letop_patterns n pat = (** Mapping functions. *) let constant = function - | Const_char c -> Pconst_char c - | Const_string (s,loc,d) -> Pconst_string (s,loc,d) - | Const_int i -> Pconst_integer (Int.to_string i, None) - | Const_int32 i -> Pconst_integer (Int32.to_string i, Some 'l') - | Const_int64 i -> Pconst_integer (Int64.to_string i, Some 'L') - | Const_nativeint i -> Pconst_integer (Nativeint.to_string i, Some 'n') - | Const_float f -> Pconst_float (f,None) + | Const_char c -> `Parsetree (Pconst_char c) + | Const_string (s,loc,d) -> `Parsetree (Pconst_string (s,loc,d)) + | Const_int i -> `Parsetree (Pconst_integer (Int.to_string i, None)) + | Const_int32 i -> `Parsetree (Pconst_integer (Int32.to_string i, Some 'l')) + | Const_int64 i -> `Parsetree (Pconst_integer (Int64.to_string i, Some 'L')) + | Const_nativeint i -> `Parsetree (Pconst_integer (Nativeint.to_string i, Some 'n')) + | Const_float f -> `Parsetree (Pconst_float (f,None)) + | Const_unboxed_float f -> `Jane_syntax (Jane_syntax.Layouts.Float (f, None)) let attribute sub a = { attr_name = map_loc sub a.attr_name; @@ -358,7 +359,12 @@ let pattern : type k . _ -> k T.general_pattern -> _ = fun sub pat -> | Tpat_alias (pat, _id, name, _uid, _mode) -> Ppat_alias (sub.pat sub pat, name) - | Tpat_constant cst -> Ppat_constant (constant cst) + | Tpat_constant cst -> + begin match constant cst with + | `Parsetree cst -> Ppat_constant cst + | `Jane_syntax cst -> + Jane_syntax.Layouts.pat_of ~loc (Lpat_constant cst) |> add_jane_syntax_attributes + end | Tpat_tuple list -> Ppat_tuple (List.map (sub.pat sub) list) | Tpat_construct (lid, _, args, vto) -> @@ -494,7 +500,12 @@ let expression sub exp = let desc = match exp.exp_desc with Texp_ident (_path, lid, _, _, _) -> Pexp_ident (map_loc sub lid) - | Texp_constant cst -> Pexp_constant (constant cst) + | Texp_constant cst -> + begin match constant cst with + | `Parsetree cst -> Pexp_constant cst + | `Jane_syntax cst -> + Jane_syntax.Layouts.expr_of ~loc (Lexp_constant cst) |> add_jane_syntax_attributes + end | Texp_let (rec_flag, list, exp) -> Pexp_let (rec_flag, List.map (sub.value_binding sub) list, diff --git a/ocaml/typing/untypeast.mli b/ocaml/typing/untypeast.mli index 809df9ad086..f4999384124 100644 --- a/ocaml/typing/untypeast.mli +++ b/ocaml/typing/untypeast.mli @@ -84,4 +84,5 @@ val untype_signature : ?mapper:mapper -> Typedtree.signature -> signature val untype_expression : ?mapper:mapper -> Typedtree.expression -> expression val untype_pattern : ?mapper:mapper -> _ Typedtree.general_pattern -> pattern -val constant : Asttypes.constant -> Parsetree.constant +val constant : Typedtree.constant -> + [ `Parsetree of Parsetree.constant | `Jane_syntax of Jane_syntax.Layouts.constant ]