Skip to content

Commit a03de20

Browse files
authored
flambda-backend: Parse unboxed literals, treating them as boxed (#1437)
* Parse `#0`, `-#1`, `#2.7`, and `-#3.1`, treating them as boxed * Fix parsing of unsuffixed unboxed int literals * Rewrite CR comment * Update comment * promote-menhir * Unboxed literal tests * Adjust error for unsuffixed unboxed integers
1 parent 5283047 commit a03de20

File tree

7 files changed

+6616
-6199
lines changed

7 files changed

+6616
-6199
lines changed

boot/menhir/parser.ml

Lines changed: 6480 additions & 6181 deletions
Large diffs are not rendered by default.

parsing/parser.mly

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,40 @@ let check_layout loc id =
780780
let loc = make_loc loc in
781781
Attr.mk ~loc (mkloc id loc) (PStr [])
782782

783+
(* Unboxed literals *)
784+
785+
let unboxed_literals_extension : Language_extension.t = Layouts Alpha
786+
787+
type sign = Positive | Negative
788+
789+
let with_sign sign num =
790+
match sign with
791+
| Positive -> num
792+
| Negative -> "-" ^ num
793+
794+
(* CR layouts ASZ: The [unboxed_*] functions will both be improved and lose
795+
their explicit assert once we have real unboxed literals in Jane syntax; they
796+
may also get re-inlined at that point *)
797+
798+
let unboxed_int sloc int_loc sign (n, m) =
799+
match m with
800+
| Some _ ->
801+
Jane_syntax_parsing.assert_extension_enabled
802+
~loc:(make_loc sloc) unboxed_literals_extension;
803+
Pconst_integer (with_sign sign n, m)
804+
| None ->
805+
if Language_extension.is_enabled unboxed_literals_extension then
806+
expecting int_loc "integer literal with type-specifying suffix"
807+
else
808+
not_expecting sloc "line number directive"
809+
810+
let unboxed_float sloc sign (f, m) =
811+
Jane_syntax_parsing.assert_extension_enabled
812+
~loc:(make_loc sloc) unboxed_literals_extension;
813+
Pconst_float (with_sign sign f, m)
814+
815+
(* Jane syntax *)
816+
783817
let mkexp_jane_syntax
784818
~loc
785819
{ Jane_syntax_parsing.With_attributes.jane_syntax_attributes; desc }
@@ -2063,7 +2097,7 @@ formal_class_parameters:
20632097
(* Class expressions. *)
20642098

20652099
class_expr:
2066-
class_simple_expr
2100+
class_simple_expr %prec below_HASH
20672101
{ $1 }
20682102
| FUN attributes class_fun_def
20692103
{ wrap_class_attrs ~loc:$sloc $3 $2 }
@@ -2076,7 +2110,7 @@ class_expr:
20762110
| class_expr attribute
20772111
{ Cl.attr $1 $2 }
20782112
| mkclass(
2079-
class_simple_expr nonempty_llist(labeled_simple_expr)
2113+
class_simple_expr nonempty_llist(labeled_simple_expr) %prec below_HASH
20802114
{ Pcl_apply($1, $2) }
20812115
| extension
20822116
{ Pcl_extension $1 }
@@ -2556,7 +2590,7 @@ expr:
25562590
{ Pexp_lazy $3, $2 }
25572591
;
25582592
%inline expr_:
2559-
| simple_expr nonempty_llist(labeled_simple_expr)
2593+
| simple_expr nonempty_llist(labeled_simple_expr) %prec below_HASH
25602594
{ Pexp_apply($1, $2) }
25612595
| expr_comma_list %prec below_COMMA
25622596
{ Pexp_tuple($1) }
@@ -3932,17 +3966,25 @@ meth_list:
39323966
/* Constants */
39333967

39343968
constant:
3935-
| INT { let (n, m) = $1 in Pconst_integer (n, m) }
3936-
| CHAR { Pconst_char $1 }
3937-
| STRING { let (s, strloc, d) = $1 in Pconst_string (s, strloc, d) }
3938-
| FLOAT { let (f, m) = $1 in Pconst_float (f, m) }
3969+
| INT { let (n, m) = $1 in Pconst_integer (n, m) }
3970+
| CHAR { Pconst_char $1 }
3971+
| STRING { let (s, strloc, d) = $1 in Pconst_string (s, strloc, d) }
3972+
| FLOAT { let (f, m) = $1 in Pconst_float (f, m) }
3973+
(* The unboxed literals have to be composed of multiple lexemes so we can
3974+
handle line number directives properly *)
3975+
| HASH INT { unboxed_int $sloc $loc($2) Positive $2 }
3976+
| HASH FLOAT { unboxed_float $sloc Positive $2 }
39393977
;
39403978
signed_constant:
3941-
constant { $1 }
3942-
| MINUS INT { let (n, m) = $2 in Pconst_integer("-" ^ n, m) }
3943-
| MINUS FLOAT { let (f, m) = $2 in Pconst_float("-" ^ f, m) }
3944-
| PLUS INT { let (n, m) = $2 in Pconst_integer (n, m) }
3945-
| PLUS FLOAT { let (f, m) = $2 in Pconst_float(f, m) }
3979+
constant { $1 }
3980+
| MINUS INT { let (n, m) = $2 in Pconst_integer("-" ^ n, m) }
3981+
| MINUS FLOAT { let (f, m) = $2 in Pconst_float("-" ^ f, m) }
3982+
| MINUS HASH INT { unboxed_int $sloc $loc($3) Negative $3 }
3983+
| MINUS HASH FLOAT { unboxed_float $sloc Negative $3 }
3984+
| PLUS INT { let (n, m) = $2 in Pconst_integer (n, m) }
3985+
| PLUS FLOAT { let (f, m) = $2 in Pconst_float(f, m) }
3986+
| PLUS HASH INT { unboxed_int $sloc $loc($3) Positive $3 }
3987+
| PLUS HASH FLOAT { unboxed_float $sloc Negative $3 }
39463988
;
39473989

39483990
/* Identifiers and long identifiers */
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
File "pr6604.ml", line 9, characters 0-1:
1+
File "pr6604.ml", line 9, characters 0-2:
22
9 | #1
3-
^
4-
Error: Syntax error
3+
^^
4+
Error: Syntax error: line number directive not expected.
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
File "pr6604_2.ml", line 9, characters 1-2:
1+
File "pr6604_2.ml", line 9, characters 1-3:
22
9 | #1 "pr6604.ml"
3-
^
4-
Error: Syntax error
3+
^^
4+
Error: Syntax error: line number directive not expected.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
Line 6, characters 45-47:
3+
6 | let unboxed_integers_must_have_a_modifier = #42
4+
^^
5+
Error: Syntax error: integer literal with type-specifying suffix expected.
6+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
(* TEST
2+
flags = "-extension layouts_alpha"
3+
* toplevel
4+
*)
5+
6+
let unboxed_integers_must_have_a_modifier = #42
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
(* TEST
2+
flags = "-extension layouts_alpha"
3+
* expect
4+
*)
5+
6+
let e = #2.718281828459045
7+
[%%expect{|
8+
val e : float = 2.71828182845904509
9+
|}]
10+
11+
let negative_one_half = -#0.5
12+
[%%expect{|
13+
val negative_one_half : float = -0.5
14+
|}]
15+
16+
let positive_one_dot = +#1.
17+
[%%expect{|
18+
val positive_one_dot : float = 1.
19+
|}]
20+
21+
let one_billion = #1e9
22+
[%%expect{|
23+
val one_billion : float = 1000000000.
24+
|}]
25+
26+
let zero = #0n
27+
[%%expect{|
28+
val zero : nativeint = 0n
29+
|}]
30+
31+
let positive_one = +#1l
32+
[%%expect{|
33+
val positive_one : int32 = 1l
34+
|}]
35+
36+
let negative_one = -#1L
37+
[%%expect{|
38+
val negative_one : int64 = -1L
39+
|}]
40+
41+
let two_fifty_five_in_hex = #0xFFn
42+
[%%expect{|
43+
val two_fifty_five_in_hex : nativeint = 255n
44+
|}]
45+
46+
let twenty_five_in_octal = #0o31l
47+
[%%expect{|
48+
val twenty_five_in_octal : int32 = 25l
49+
|}]
50+
51+
let forty_two_in_binary = #0b101010L
52+
[%%expect{|
53+
val forty_two_in_binary : int64 = 42L
54+
|}]
55+
56+
let one_twenty_seven_point_two_five_in_floating_hex = #0x7f.4
57+
[%%expect{|
58+
val one_twenty_seven_point_two_five_in_floating_hex : float = 127.25
59+
|}]
60+
61+
let five_point_three_seven_five_in_floating_hexponent = #0xa.cp-1
62+
[%%expect{|
63+
val five_point_three_seven_five_in_floating_hexponent : float = 5.375
64+
|}]

0 commit comments

Comments
 (0)