Skip to content

Commit 51851c8

Browse files
committed
Require that floating-point literals write a digit after ., enables UFCS on numeric literals
(1) I find `1.0 and `1.0f` clearer than `1.` and `1.f` anyway, so that's a small plus. (2) This was the only thing in the way of using UFCS on numeric literals, so that's another maybe-medium plus. And the latter enables writing unit libraries like `42.gram()`, as proposed in #284's comment thread, which is an interesting use of UFCS on literals. So I'll mark this as closes #284.
1 parent f9ca050 commit 51851c8

File tree

4 files changed

+27
-19
lines changed

4 files changed

+27
-19
lines changed

regression-tests/mixed-float-literals.cpp2

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,28 +72,20 @@ literals_cpp2: () = {
7272
123'456LL;
7373
// float points
7474
123'456.0f;
75-
123'456.f;
7675
456.0;
77-
456.;
7876
1.0e10;
7977
1.0e+10;
8078
1.0e-10;
8179
1.0e-10f;
82-
1.e-10;
83-
1.e-10f;
8480
1e-10;
8581
1e-10f;
8682
1e-1'0;
8783
123'456.0F;
88-
123'456.F;
8984
456.0;
90-
456.;
9185
1.0E10;
9286
1.0E+10;
9387
1.0E-10;
9488
1.0E-10F;
95-
1.E-10;
96-
1.E-10F;
9789
1E-10;
9890
1E-10F;
9991
1E-1'0;
@@ -108,6 +100,15 @@ literals_cpp2: () = {
108100
// 1e - 10.0;
109101
// 1e - 10f;
110102
// 1e - 10.0f;
103+
// 123'456.f;
104+
// 123'456.f;
105+
// 456.;
106+
// 1.e-10;
107+
// 1.e-10f;
108+
// 123'456.F;
109+
// 456.;
110+
// 1.E-10;
111+
// 1.E-10F;
111112
}
112113

113114
main: ()->int = { }

regression-tests/test-results/mixed-float-literals.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ void literals_cpp1() {
6161

6262
#line 57 "mixed-float-literals.cpp2"
6363
auto literals_cpp2() -> void;
64-
#line 113 "mixed-float-literals.cpp2"
64+
#line 114 "mixed-float-literals.cpp2"
6565
[[nodiscard]] auto main() -> int;
6666

6767
//=== Cpp2 definitions ==========================================================
@@ -86,28 +86,20 @@ auto literals_cpp2() -> void{
8686
123'456LL;
8787
// float points
8888
123'456.0f;
89-
123'456.f;
9089
456.0;
91-
456.;
9290
1.0e10;
9391
1.0e+10;
9492
1.0e-10;
9593
1.0e-10f;
96-
1.e-10;
97-
1.e-10f;
9894
1e-10;
9995
1e-10f;
10096
1e-1'0;
10197
123'456.0F;
102-
123'456.F;
10398
456.0;
104-
456.;
10599
1.0E10;
106100
1.0E+10;
107101
1.0E-10;
108102
1.0E-10F;
109-
1.E-10;
110-
1.E-10F;
111103
1E-10;
112104
1E-10F;
113105
1E-1'0;
@@ -122,6 +114,15 @@ auto literals_cpp2() -> void{
122114
// 1e - 10.0;
123115
// 1e - 10f;
124116
// 1e - 10.0f;
117+
// 123'456.f;
118+
// 123'456.f;
119+
// 456.;
120+
// 1.e-10;
121+
// 1.e-10f;
122+
// 123'456.F;
123+
// 456.;
124+
// 1.E-10;
125+
// 1.E-10F;
125126
}
126127

127128
[[nodiscard]] auto main() -> int{}

source/cppfront.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2562,7 +2562,7 @@ class cppfront
25622562
}
25632563

25642564
// Going backwards if we found LeftParen it might be UFCS
2565-
// expr_list is emited to args variable for future use
2565+
// expr_list is emitted to 'args' for future use
25662566
if (i->op->type() == lexeme::LeftParen) {
25672567

25682568
assert(i->op);

source/lex.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1233,7 +1233,7 @@ auto lex_line(
12331233
auto j = 1;
12341234
while (is_separator_or(is_digit,peek(j))) { ++j; }
12351235
if (
1236-
peek(j) != '.'
1236+
(peek(j) != '.' || !is_digit(peek(j+1)))
12371237
&& peek(j) != 'f'
12381238
&& peek(j) != 'F'
12391239
&& peek(j) != 'e'
@@ -1259,6 +1259,12 @@ auto lex_line(
12591259
// slurps the digits after '.'
12601260
if (peek(j) == '.') {
12611261
++j;
1262+
if (!is_digit(peek(j))) {
1263+
errors.emplace_back(
1264+
source_position(lineno, i),
1265+
"a floating point literal must have at least one digit after the decimal point (can be '.0')"
1266+
);
1267+
}
12621268
while (is_separator_or(is_digit,peek(j))) {
12631269
++j;
12641270
}

0 commit comments

Comments
 (0)