Skip to content

Commit d8189c6

Browse files
0xflotusjoshgoebel
andauthored
enh(java) added support for hexadecimal floating point literals (#2509)
- Added support for many additional types of floating point literals - Added related tests There still may be a few gaps, but this is a pretty large improvement. Co-authored-by: Josh Goebel <[email protected]>
1 parent 1bfe834 commit d8189c6

File tree

4 files changed

+119
-25
lines changed

4 files changed

+119
-25
lines changed

src/languages/java.js

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ Category: common, enterprise
55
Website: https://www.java.com/
66
*/
77

8+
import * as regex from "../lib/regex";
9+
810
export default function(hljs) {
911
var JAVA_IDENT_RE = '[\u00C0-\u02B8a-zA-Z_$][\u00C0-\u02B8a-zA-Z_$0-9]*';
1012
var GENERIC_IDENT_RE = JAVA_IDENT_RE + '(<' + JAVA_IDENT_RE + '(\\s*,\\s*' + JAVA_IDENT_RE + ')*>)?';
11-
var KEYWORDS =
12-
'false synchronized int abstract float private char boolean var static null if const ' +
13+
var KEYWORDS = 'false synchronized int abstract float private char boolean var static null if const ' +
1314
'for true while long strictfp finally protected import native final void ' +
1415
'enum else break transient catch instanceof byte super volatile case assert short ' +
1516
'package default double public try this switch continue throws protected public private ' +
@@ -18,32 +19,53 @@ export default function(hljs) {
1819
var ANNOTATION = {
1920
className: 'meta',
2021
begin: '@' + JAVA_IDENT_RE,
21-
contains:[
22+
contains: [
2223
{
2324
begin: /\(/,
2425
end: /\)/,
2526
contains: ["self"] // allow nested () inside our annotation
2627
},
2728
]
28-
}
29-
// https://docs.oracle.com/javase/7/docs/technotes/guides/language/underscores-literals.html
30-
var JAVA_NUMBER_RE = '\\b' +
31-
'(' +
32-
'0[bB]([01]+[01_]+[01]+|[01]+)' + // 0b...
33-
'|' +
34-
'0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)' + // 0x...
35-
'|' +
36-
'(' +
37-
'([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?' +
38-
'|' +
39-
'\\.([\\d]+[\\d_]+[\\d]+|[\\d]+)' +
40-
')' +
41-
'([eE][-+]?\\d+)?' + // octal, decimal, float
42-
')' +
43-
'[lLfF]?';
29+
};
30+
/**
31+
* A given sequence, possibly with underscores
32+
* @type {(s: string | RegExp) => string} */
33+
var SEQUENCE_ALLOWING_UNDERSCORES = (seq) => regex.concat('[', seq, ']+([', seq, '_]*[', seq, ']+)?');
4434
var JAVA_NUMBER_MODE = {
4535
className: 'number',
46-
begin: JAVA_NUMBER_RE,
36+
variants: [
37+
{ begin: `\\b(0[bB]${SEQUENCE_ALLOWING_UNDERSCORES('01')})[lL]?` }, // binary
38+
{ begin: `\\b(0${SEQUENCE_ALLOWING_UNDERSCORES('0-7')})[dDfFlL]?` }, // octal
39+
{
40+
begin: regex.concat(
41+
/\b0[xX]/,
42+
regex.either(
43+
regex.concat(SEQUENCE_ALLOWING_UNDERSCORES('a-fA-F0-9'), /\./, SEQUENCE_ALLOWING_UNDERSCORES('a-fA-F0-9')),
44+
regex.concat(SEQUENCE_ALLOWING_UNDERSCORES('a-fA-F0-9'), /\.?/),
45+
regex.concat(/\./, SEQUENCE_ALLOWING_UNDERSCORES('a-fA-F0-9')),
46+
),
47+
/([pP][+-]?(\d+))?/,
48+
/[fFdDlL]?/ // decimal & fp mixed for simplicity
49+
)
50+
},
51+
// scientific notation
52+
{ begin: regex.concat(
53+
/\b/,
54+
regex.either(
55+
regex.concat(/\d*\./, SEQUENCE_ALLOWING_UNDERSCORES("\\d")), // .3, 3.3, 3.3_3
56+
SEQUENCE_ALLOWING_UNDERSCORES("\\d") // 3, 3_3
57+
),
58+
/[eE][+-]?[\d]+[dDfF]?/)
59+
},
60+
// decimal & fp mixed for simplicity
61+
{ begin: regex.concat(
62+
/\b/,
63+
SEQUENCE_ALLOWING_UNDERSCORES(/\d/),
64+
regex.optional(/\.?/),
65+
regex.optional(SEQUENCE_ALLOWING_UNDERSCORES(/\d/)),
66+
/[dDfFlL]?/)
67+
}
68+
],
4769
relevance: 0
4870
};
4971

@@ -57,15 +79,15 @@ export default function(hljs) {
5779
'/\\*\\*',
5880
'\\*/',
5981
{
60-
relevance : 0,
61-
contains : [
82+
relevance: 0,
83+
contains: [
6284
{
6385
// eat up @'s in emails to prevent them to be recognized as doctags
6486
begin: /\w+@/, relevance: 0
6587
},
6688
{
67-
className : 'doctag',
68-
begin : '@[A-Za-z]+'
89+
className: 'doctag',
90+
begin: '@[A-Za-z]+'
6991
}
7092
]
7193
}
@@ -80,7 +102,7 @@ export default function(hljs) {
80102
keywords: 'class interface',
81103
illegal: /[:"\[\]]/,
82104
contains: [
83-
{beginKeywords: 'extends implements'},
105+
{ beginKeywords: 'extends implements' },
84106
hljs.UNDERSCORE_TITLE_MODE
85107
]
86108
},

src/lib/regex.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ export function lookahead(re) {
2525
return concat('(?=', re, ')');
2626
}
2727

28+
/**
29+
* @param {RegExp | string } re
30+
* @returns {string}
31+
*/
32+
export function optional(re) {
33+
return concat('(', re, ')?');
34+
}
35+
2836
/**
2937
* @param {...(RegExp | string) } args
3038
* @returns {string}
@@ -34,6 +42,18 @@ export function concat(...args) {
3442
return joined;
3543
}
3644

45+
/**
46+
* Any of the passed expresssions may match
47+
*
48+
* Creates a huge this | this | that | that match
49+
* @param {(RegExp | string)[] } args
50+
* @returns {string}
51+
*/
52+
export function either(...args) {
53+
const joined = '(' + args.map((x) => source(x)).join("|") + ")";
54+
return joined;
55+
}
56+
3757
/**
3858
* @param {RegExp} re
3959
* @returns {number}

test/markup/java/numbers.expect.txt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,29 @@
77
<span class="hljs-keyword">byte</span> nybbles = <span class="hljs-number">0b0010_0101</span>;
88
<span class="hljs-keyword">long</span> bytes = <span class="hljs-number">0b11010010_01101001_10010100_10010010</span>;
99
<span class="hljs-keyword">int</span> n = <span class="hljs-number">1234</span> + Contacts._ID;
10+
<span class="hljs-keyword">float</span> f = <span class="hljs-number">0x1.4p2f</span>;
11+
<span class="hljs-keyword">double</span> d = <span class="hljs-number">0x.ep-6</span>;
12+
<span class="hljs-keyword">int</span> octal = <span class="hljs-number">0777</span>;
13+
<span class="hljs-keyword">float</span> f = <span class="hljs-number">2e3f</span>;
14+
<span class="hljs-keyword">double</span> d = <span class="hljs-number">1.2e4D</span>;
15+
a = <span class="hljs-number">0x4fa6p2</span>;
16+
b = <span class="hljs-number">0x.4p2</span>;
17+
c = <span class="hljs-number">0xa.ffp3f</span>;
18+
d = <span class="hljs-number">0x1.0p2F</span>;
19+
e = <span class="hljs-number">0x1.0p2f</span>;
20+
f = <span class="hljs-number">0x1p1</span>;
21+
g = <span class="hljs-number">0x.3p4d</span>;
22+
h = <span class="hljs-number">0x1.2ep5D</span>;
23+
i = <span class="hljs-number">0x1.p2</span>;
24+
<span class="hljs-keyword">int</span> i = <span class="hljs-number">23</span>;
25+
<span class="hljs-keyword">byte</span> mask = <span class="hljs-number">0x0f</span>;
26+
<span class="hljs-keyword">int</span> i = <span class="hljs-number">4</span>;
27+
<span class="hljs-keyword">byte</span> mask = <span class="hljs-number">0xa</span>;
28+
<span class="hljs-keyword">float</span> f = <span class="hljs-number">5.4</span>;
29+
<span class="hljs-keyword">float</span> f = <span class="hljs-number">2e3</span>;
30+
<span class="hljs-keyword">int</span> n = <span class="hljs-number">0b1</span>;
31+
<span class="hljs-keyword">float</span> f = <span class="hljs-number">3.</span>;
32+
f = <span class="hljs-number">3_3.</span>;
33+
<span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> in the future</span>
34+
<span class="hljs-comment">// float f = .2;</span>
35+
<span class="hljs-comment">// f = .2_022;</span>

test/markup/java/numbers.txt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,29 @@ long maxLong = 0x7fff_ffff_ffff_ffffL;
77
byte nybbles = 0b0010_0101;
88
long bytes = 0b11010010_01101001_10010100_10010010;
99
int n = 1234 + Contacts._ID;
10+
float f = 0x1.4p2f;
11+
double d = 0x.ep-6;
12+
int octal = 0777;
13+
float f = 2e3f;
14+
double d = 1.2e4D;
15+
a = 0x4fa6p2;
16+
b = 0x.4p2;
17+
c = 0xa.ffp3f;
18+
d = 0x1.0p2F;
19+
e = 0x1.0p2f;
20+
f = 0x1p1;
21+
g = 0x.3p4d;
22+
h = 0x1.2ep5D;
23+
i = 0x1.p2;
24+
int i = 23;
25+
byte mask = 0x0f;
26+
int i = 4;
27+
byte mask = 0xa;
28+
float f = 5.4;
29+
float f = 2e3;
30+
int n = 0b1;
31+
float f = 3.;
32+
f = 3_3.;
33+
// TODO: in the future
34+
// float f = .2;
35+
// f = .2_022;

0 commit comments

Comments
 (0)