Skip to content

Commit dd07e23

Browse files
authored
float32 literals (#2434)
1 parent 096ffdc commit dd07e23

File tree

11 files changed

+287
-9
lines changed

11 files changed

+287
-9
lines changed

ocaml/bytecomp/bytegen.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1014,7 +1014,7 @@ let rec comp_expr stack_info env exp sz cont =
10141014
| CFnge -> Kccall("caml_ge_float", 2) :: Kboolnot :: cont
10151015
in
10161016
comp_args stack_info env args sz cont
1017-
| Lprim (Pfloatcomp (Pfloat32, cmp), args, _) ->
1017+
| Lprim (Pfloatcomp (Pfloat32, cmp), args, _) | Lprim (Punboxed_float_comp (Pfloat32, cmp), args, _) ->
10181018
let cont =
10191019
match cmp with
10201020
| CFeq -> Kccall("caml_eq_float32", 2) :: cont

ocaml/configure

-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ocaml/lambda/matching.ml

+3-3
Original file line numberDiff line numberDiff line change
@@ -2892,9 +2892,8 @@ let combine_constant value_kind loc arg cst partial ctx def
28922892
(Pfloatcomp (Pfloat64, CFlt)) arg
28932893
const_lambda_list
28942894
| Const_float32 _ ->
2895-
make_test_sequence value_kind loc fail (Pfloatcomp (Pfloat32, CFneq))
2896-
(Pfloatcomp (Pfloat32, CFlt)) arg
2897-
const_lambda_list
2895+
(* Should be caught in do_compile_matching. *)
2896+
Misc.fatal_error "Found unexpected float32 literal pattern."
28982897
| Const_unboxed_float _ ->
28992898
make_test_sequence value_kind loc fail
29002899
(Punboxed_float_comp (Pfloat64, CFneq))
@@ -3568,6 +3567,7 @@ and do_compile_matching ~scopes value_kind repr partial ctx pmh =
35683567
compile_no_test ~scopes value_kind
35693568
(divide_record ~scopes lbl.lbl_all ph)
35703569
Context.combine repr partial ctx pm
3570+
| Constant (Const_float32 _) -> Parmatch.raise_matched_float32 ()
35713571
| Constant cst ->
35723572
compile_test
35733573
(compile_match ~scopes value_kind repr partial)

ocaml/testsuite/tests/typing-small-numbers/test_disabled.ml

+107
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,110 @@ Line 1, characters 9-16:
1010
Error: Unbound type constructor float32
1111
Hint: Did you mean float, float# or float32x4?
1212
|}];;
13+
14+
let _ = 1.0s;;
15+
[%%expect{|
16+
Line 1, characters 8-12:
17+
1 | let _ = 1.0s;;
18+
^^^^
19+
Error: Found 32-bit float literal 1.0s, but float32 is not enabled. You must enable -extension small_numbers to use this feature.
20+
|}];;
21+
22+
let _ = 1.s;;
23+
[%%expect{|
24+
Line 1, characters 8-11:
25+
1 | let _ = 1.s;;
26+
^^^
27+
Error: Found 32-bit float literal 1.s, but float32 is not enabled. You must enable -extension small_numbers to use this feature.
28+
|}];;
29+
30+
let _ = 1e10s;;
31+
[%%expect{|
32+
Line 1, characters 8-13:
33+
1 | let _ = 1e10s;;
34+
^^^^^
35+
Error: Found 32-bit float literal 1e10s, but float32 is not enabled. You must enable -extension small_numbers to use this feature.
36+
|}];;
37+
38+
let _ = 1e+1s;;
39+
[%%expect{|
40+
Line 1, characters 8-13:
41+
1 | let _ = 1e+1s;;
42+
^^^^^
43+
Error: Found 32-bit float literal 1e+1s, but float32 is not enabled. You must enable -extension small_numbers to use this feature.
44+
|}];;
45+
46+
let _ = 1e-1s;;
47+
[%%expect{|
48+
Line 1, characters 8-13:
49+
1 | let _ = 1e-1s;;
50+
^^^^^
51+
Error: Found 32-bit float literal 1e-1s, but float32 is not enabled. You must enable -extension small_numbers to use this feature.
52+
|}];;
53+
54+
let _ = 0x111.000s;;
55+
[%%expect{|
56+
Line 1, characters 8-18:
57+
1 | let _ = 0x111.000s;;
58+
^^^^^^^^^^
59+
Error: Found 32-bit float literal 0x111.000s, but float32 is not enabled. You must enable -extension small_numbers to use this feature.
60+
|}];;
61+
62+
let _ = 0x1.4p+0s;;
63+
[%%expect{|
64+
Line 1, characters 8-17:
65+
1 | let _ = 0x1.4p+0s;;
66+
^^^^^^^^^
67+
Error: Found 32-bit float literal 0x1.4p+0s, but float32 is not enabled. You must enable -extension small_numbers to use this feature.
68+
|}];;
69+
70+
let _ = 0xf.ffffffffffff8p+1020s;;
71+
[%%expect{|
72+
Line 1, characters 8-32:
73+
1 | let _ = 0xf.ffffffffffff8p+1020s;;
74+
^^^^^^^^^^^^^^^^^^^^^^^^
75+
Error: Found 32-bit float literal 0xf.ffffffffffff8p+1020s, but float32 is not enabled. You must enable -extension small_numbers to use this feature.
76+
|}];;
77+
78+
let _ = 0x8p-972s;;
79+
[%%expect{|
80+
Line 1, characters 8-17:
81+
1 | let _ = 0x8p-972s;;
82+
^^^^^^^^^
83+
Error: Found 32-bit float literal 0x8p-972s, but float32 is not enabled. You must enable -extension small_numbers to use this feature.
84+
|}];;
85+
86+
let _ = 0xc.d5e6fp+1_24s;;
87+
[%%expect{|
88+
Line 1, characters 8-24:
89+
1 | let _ = 0xc.d5e6fp+1_24s;;
90+
^^^^^^^^^^^^^^^^
91+
Error: Found 32-bit float literal 0xc.d5e6fp+1_24s, but float32 is not enabled. You must enable -extension small_numbers to use this feature.
92+
|}];;
93+
94+
let () =
95+
match 0.0s with
96+
| _ -> ()
97+
;;
98+
[%%expect{|
99+
Line 2, characters 8-12:
100+
2 | match 0.0s with
101+
^^^^
102+
Error: Found 32-bit float literal 0.0s, but float32 is not enabled. You must enable -extension small_numbers to use this feature.
103+
|}];;
104+
105+
let _ = #1.0s;;
106+
[%%expect{|
107+
Line 1, characters 8-13:
108+
1 | let _ = #1.0s;;
109+
^^^^^
110+
Error: Found 32-bit float literal #1.0s, but float32 is not enabled. You must enable -extension small_numbers to use this feature.
111+
|}];;
112+
113+
let _ = -#1.0s;;
114+
[%%expect{|
115+
Line 1, characters 8-14:
116+
1 | let _ = -#1.0s;;
117+
^^^^^^
118+
Error: Found 32-bit float literal -#1.0s, but float32 is not enabled. You must enable -extension small_numbers to use this feature.
119+
|}];;

ocaml/testsuite/tests/typing-small-numbers/test_enabled.ml

+90
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,97 @@
33
expect;
44
*)
55

6+
(* Operations are tested in tests/small_numbers/float32.ml *)
7+
68
type t = float32;;
79
[%%expect{|
810
type t = float32
911
|}];;
12+
13+
let _ : float32 = 1.0s;;
14+
[%%expect{|
15+
- : float32 = <abstr>
16+
|}];;
17+
18+
let _ : float32 = 1.s;;
19+
[%%expect{|
20+
- : float32 = <abstr>
21+
|}];;
22+
23+
let _ : float32 = 1e10s;;
24+
[%%expect{|
25+
- : float32 = <abstr>
26+
|}];;
27+
28+
let _ : float32 = 1e+1s;;
29+
[%%expect{|
30+
- : float32 = <abstr>
31+
|}];;
32+
33+
let _ : float32 = 1e-1s;;
34+
[%%expect{|
35+
- : float32 = <abstr>
36+
|}];;
37+
38+
let _ : float32 = 0x111.000s;;
39+
[%%expect{|
40+
- : float32 = <abstr>
41+
|}];;
42+
43+
let _ : float32 = 0x1.4p+0s;;
44+
[%%expect{|
45+
- : float32 = <abstr>
46+
|}];;
47+
48+
let _ : float32 = 0xf.ffffffffffff8p+1020s;;
49+
[%%expect{|
50+
- : float32 = <abstr>
51+
|}];;
52+
53+
let _ : float32 = 0x8p-972s;;
54+
[%%expect{|
55+
- : float32 = <abstr>
56+
|}];;
57+
58+
let _ : float32 = 0xc.d5e6fp+1_24s;;
59+
[%%expect{|
60+
- : float32 = <abstr>
61+
|}];;
62+
63+
(* A (trivial) match with no float32 cases is allowed. *)
64+
let () =
65+
match 0.0s with
66+
| _ -> ()
67+
;;
68+
[%%expect{|
69+
|}];;
70+
71+
let () =
72+
match 0.0s with
73+
| 0.0s -> ()
74+
| _ -> ()
75+
;;
76+
[%%expect{|
77+
Line 1:
78+
Error: float32 literal patterns are not supported.
79+
|}];;
80+
81+
let () =
82+
match 0.0s with
83+
| 0.0s -> ()
84+
| 1.0s -> ()
85+
| _ -> ()
86+
;;
87+
[%%expect{|
88+
Line 1:
89+
Error: float32 literal patterns are not supported.
90+
|}];;
91+
92+
let () =
93+
match 0.0s with
94+
| 0.0s -> ()
95+
;;
96+
[%%expect{|
97+
Line 1:
98+
Error: float32 literal patterns are not supported.
99+
|}];;

ocaml/typing/parmatch.ml

+20-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ open Asttypes
2020
open Types
2121
open Typedtree
2222

23+
type error = Float32_match
24+
25+
exception Error of error
26+
27+
let raise_matched_float32 () = raise (Error Float32_match)
28+
2329
type 'pattern parmatch_case =
2430
{ pattern : 'pattern;
2531
has_guard : bool;
@@ -271,13 +277,15 @@ let const_compare x y =
271277
| Const_unboxed_float f1, Const_unboxed_float f2
272278
| Const_float f1, Const_float f2 ->
273279
Stdlib.compare (float_of_string f1) (float_of_string f2)
280+
| Const_float32 _, _ ->
281+
(* CR mslater: (float32) pattern matching (needs float32 lib) *)
282+
raise_matched_float32 ()
274283
| Const_string (s1, _, _), Const_string (s2, _, _) ->
275284
String.compare s1 s2
276285
| (Const_int _
277286
|Const_char _
278287
|Const_string (_, _, _)
279288
|Const_float _
280-
|Const_float32 _
281289
|Const_unboxed_float _
282290
|Const_int32 _
283291
|Const_int64 _
@@ -1102,6 +1110,9 @@ let build_other ext env =
11021110
| _ -> assert false)
11031111
(function f -> Tpat_constant(Const_float (string_of_float f)))
11041112
0.0 (fun f -> f +. 1.0) d env
1113+
| Constant Const_float32 _ ->
1114+
(* CR mslater: (float32) pattern matching (needs float32 lib) *)
1115+
raise_matched_float32 ()
11051116
| Constant Const_unboxed_float _ ->
11061117
build_other_constant
11071118
(function Constant(Const_unboxed_float f) -> float_of_string f
@@ -2454,3 +2465,11 @@ let check_ambiguous_bindings =
24542465
ns
24552466
in
24562467
ignore (List.fold_left check_case [] cases)
2468+
2469+
let report_error ppf = function
2470+
| Float32_match -> Format.pp_print_string ppf "float32 literal patterns are not supported."
2471+
2472+
let () =
2473+
Location.register_error_of_exn (function
2474+
| Error err -> Some (Location.error_of_printer_file report_error err)
2475+
| _ -> None)

ocaml/typing/parmatch.mli

+3
Original file line numberDiff line numberDiff line change
@@ -135,3 +135,6 @@ val check_ambiguous_bindings : value case list -> unit
135135

136136
(* The tag used for open polymorphic variant types with an abstract row *)
137137
val some_private_tag : label
138+
139+
(* Raise an error due to matching on a float32. *)
140+
val raise_matched_float32 : unit -> 'a

ocaml/typing/typecore.ml

+13-1
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ type error =
202202
| Extension_not_enabled : _ Language_extension.t -> error
203203
| Literal_overflow of string
204204
| Unknown_literal of string * char
205+
| Float32_literal of string
205206
| Illegal_letrec_pat
206207
| Illegal_letrec_expr
207208
| Illegal_class_expr
@@ -680,6 +681,9 @@ let constant : Parsetree.constant -> (Typedtree.constant, error) result =
680681
| Pconst_char c -> Ok (Const_char c)
681682
| Pconst_string (s,loc,d) -> Ok (Const_string (s,loc,d))
682683
| Pconst_float (f,None)-> Ok (Const_float f)
684+
| Pconst_float (f,Some 's') ->
685+
if Language_extension.is_enabled Small_numbers then Ok (Const_float32 f)
686+
else Error (Float32_literal f)
683687
| Pconst_float (f,Some c) -> Error (Unknown_literal (f, c))
684688

685689
let constant_or_raise env loc cst =
@@ -690,7 +694,12 @@ let constant_or_raise env loc cst =
690694
let unboxed_constant : Jane_syntax.Layouts.constant -> (Typedtree.constant, error) result
691695
= function
692696
| Float (f, None) -> Ok (Const_unboxed_float f)
693-
| Float (x, Some c) -> Error (Unknown_literal (Misc.format_as_unboxed_literal x, c))
697+
| Float (f, Some 's') ->
698+
(* CR mslater: (float32) unboxed *)
699+
if Language_extension.is_enabled Small_numbers then assert false
700+
else Error (Float32_literal (Misc.format_as_unboxed_literal f))
701+
| Float (x, Some c) ->
702+
Error (Unknown_literal (Misc.format_as_unboxed_literal x, c))
694703
| Integer (i, suffix) ->
695704
begin match constant_integer i ~suffix with
696705
| Ok (Int32 v) -> Ok (Const_unboxed_int32 v)
@@ -10079,6 +10088,9 @@ let report_error ~loc env = function
1007910088
ty
1008010089
| Unknown_literal (n, m) ->
1008110090
Location.errorf ~loc "Unknown modifier '%c' for literal %s%c" m n m
10091+
| Float32_literal f ->
10092+
Location.errorf ~loc "Found 32-bit float literal %ss, but float32 is not enabled. \
10093+
You must enable -extension small_numbers to use this feature." f
1008210094
| Illegal_letrec_pat ->
1008310095
Location.errorf ~loc
1008410096
"Only variables are allowed as left-hand side of `let rec'"

ocaml/typing/typecore.mli

+2-1
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ type error =
268268
| Extension_not_enabled : _ Language_extension.t -> error
269269
| Literal_overflow of string
270270
| Unknown_literal of string * char
271+
| Float32_literal of string
271272
| Illegal_letrec_pat
272273
| Illegal_letrec_expr
273274
| Illegal_class_expr
@@ -330,4 +331,4 @@ val check_recursive_bindings : Env.t -> Typedtree.value_binding list -> unit
330331
val check_recursive_class_bindings :
331332
Env.t -> Ident.t list -> Typedtree.class_expr list -> unit
332333

333-
val src_pos : Location.t -> Typedtree.attributes -> Env.t -> Typedtree.expression
334+
val src_pos : Location.t -> Typedtree.attributes -> Env.t -> Typedtree.expression

ocaml/typing/typeopt.ml

+1
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,7 @@ let classify_lazy_argument : Typedtree.expression ->
740740
fun e -> match e.exp_desc with
741741
| Texp_constant
742742
( Const_int _ | Const_char _ | Const_string _
743+
| Const_float32 _ (* There is no float32 array optimization *)
743744
| Const_int32 _ | Const_int64 _ | Const_nativeint _ )
744745
| Texp_function _
745746
| Texp_construct (_, {cstr_arity = 0}, _, _) ->

0 commit comments

Comments
 (0)