Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enh(haskell) BinaryLiterals, NumericUnderscores, HexFloatLiterals #3150

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ Grammars:
- enh(c) Update keyword list for C11/C18 (#3010) [Josh Goebel][]
- enh(parser) highlight object properties (#3072) [Josh Goebel][]
- enh(javascript/typescript) highlight object properties (#3072) [Josh Goebel][]
- enh(haskell) add support for BinaryLiterals (#3150) [Martijn Bastiaan][]
- enh(haskell) add support for NumericUnderscores (#3150) [Martijn Bastiaan][]
- enh(haskell) add support for HexFloatLiterals (#3150) [Martijn Bastiaan][]

New Languages:

Expand All @@ -99,6 +102,7 @@ Dev Improvements:

- (chore) greatly improve match scope visualization in dev tool (#3126) [NullVoxPopuli][]

[Martijn Bastiaan]: https://github.com/martijnbastiaan
[Bradley Mackey]: https://github.com/bradleymackey
[Dylan McBean]: https://github.com/DylanMcBean
[Josh Goebel]: https://github.com/joshgoebel
Expand Down
38 changes: 37 additions & 1 deletion src/languages/haskell.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,42 @@ export default function(hljs) {
contains: LIST.contains
};

/* See:

- https://www.haskell.org/onlinereport/lexemes.html
- https://downloads.haskell.org/ghc/9.0.1/docs/html/users_guide/exts/binary_literals.html
- https://downloads.haskell.org/ghc/9.0.1/docs/html/users_guide/exts/numeric_underscores.html
- https://downloads.haskell.org/ghc/9.0.1/docs/html/users_guide/exts/hex_float_literals.html

*/
const decimalDigits = '([0-9]_*)+';
const hexDigits = '([0-9a-fA-F]_*)+';
const binaryDigits = '([01]_*)+';
const octalDigits = '([0-7]_*)+';

const NUMBER = {
className: 'number',
relevance: 0,
variants: [
// decimal floating-point-literal (subsumes decimal-literal)
{
match: `\\b(${decimalDigits})(\\.(${decimalDigits}))?` + `([eE][+-]?(${decimalDigits}))?\\b`
},
// hexadecimal floating-point-literal (subsumes hexadecimal-literal)
{
match: `\\b0[xX]_*(${hexDigits})(\\.(${hexDigits}))?` + `([pP][+-]?(${decimalDigits}))?\\b`
},
// octal-literal
{
match: `\\b0[oO](${octalDigits})\\b`
},
// binary-literal
{
match: `\\b0[bB](${binaryDigits})\\b`
}
]
};

return {
name: 'Haskell',
aliases: ['hs'],
Expand Down Expand Up @@ -157,7 +193,7 @@ export default function(hljs) {

// TODO: characters.
hljs.QUOTE_STRING_MODE,
hljs.C_NUMBER_MODE,
NUMBER,
CONSTRUCTOR,
hljs.inherit(hljs.TITLE_MODE, {
begin: '^[_a-z][\\w\']*'
Expand Down
64 changes: 64 additions & 0 deletions test/markup/haskell/numbers.expect.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<span class="hljs-comment">-- decimal</span>
<span class="hljs-title">million</span> = <span class="hljs-number">1_000_000</span>
<span class="hljs-title">billion</span> = <span class="hljs-number">1_000_000_000</span>
<span class="hljs-title">lightspeed</span> = <span class="hljs-number">299_792_458</span>
<span class="hljs-title">version</span> = <span class="hljs-number">8_04_1</span>
<span class="hljs-title">date</span> = <span class="hljs-number">2017_12_31</span>
<span class="hljs-title">the_answer</span> = <span class="hljs-number">42</span>

<span class="hljs-comment">-- hexadecimal</span>
<span class="hljs-title">red_mask</span> = <span class="hljs-number">0xff_00_00</span>
<span class="hljs-title">size1G</span> = <span class="hljs-number">0x3fff_fff</span>
<span class="hljs-title">bigX</span> = <span class="hljs-number">0Xffff</span>

<span class="hljs-comment">-- octal</span>
<span class="hljs-title">world</span> = <span class="hljs-number">0o777</span>
<span class="hljs-title">me</span> = <span class="hljs-number">0o700</span>
<span class="hljs-title">bigO</span> = <span class="hljs-number">0O700</span>

<span class="hljs-comment">-- binary</span>
<span class="hljs-title">bit8th</span> = <span class="hljs-number">0b01_0000_0000</span>
<span class="hljs-title">packbits</span> = <span class="hljs-number">0b1_11_01_0000_0_111</span>
<span class="hljs-title">bigbits</span> = <span class="hljs-number">0b1100_1011__1110_1111__0101_0011</span>
<span class="hljs-title">bigB</span> = <span class="hljs-number">0B10</span>

<span class="hljs-comment">-- float</span>
<span class="hljs-title">pi</span> = <span class="hljs-number">3.141_592_653_589_793</span>
<span class="hljs-title">faraday</span> = <span class="hljs-number">96_485.332_89</span>
<span class="hljs-title">avogadro</span> = <span class="hljs-number">6.022_140_857e+23</span>

<span class="hljs-comment">-- Negative numbers. Note: `-` is an unary operator or infix binary operator</span>
<span class="hljs-comment">-- depending on context. This is complex to parse, so we&#x27;ve settled on never</span>
<span class="hljs-comment">-- considering it part of the number across hightlight.js. If this test ever</span>
<span class="hljs-comment">-- breaks, be sure to check whether `5-3` still highlights as expected.</span>
<span class="hljs-title">n0</span> = -<span class="hljs-number">1</span>
<span class="hljs-title">n1</span> = -<span class="hljs-number">1.0</span>
<span class="hljs-title">n2</span> = -<span class="hljs-number">0xFF0</span>
<span class="hljs-title">n3</span> = -<span class="hljs-number">0o123</span>
<span class="hljs-title">n4</span> = -<span class="hljs-number">0b001</span>

<span class="hljs-comment">-- Numeric underscores</span>
<span class="hljs-title">x0</span> = <span class="hljs-number">1_000_000</span>
<span class="hljs-title">x1</span> = <span class="hljs-number">1__000000</span>

<span class="hljs-title">e0</span> = <span class="hljs-number">0.0001</span>
<span class="hljs-title">e1</span> = <span class="hljs-number">0.000_1</span>

<span class="hljs-title">f0</span> = <span class="hljs-number">1e+23</span>
<span class="hljs-title">f1</span> = <span class="hljs-number">1_e+23</span>
<span class="hljs-title">f2</span> = <span class="hljs-number">1__e+23</span>

<span class="hljs-title">g0</span> = <span class="hljs-number">1e+23</span>

<span class="hljs-title">h0</span> = <span class="hljs-number">0xffff</span>
<span class="hljs-title">h1</span> = <span class="hljs-number">0xff_ff</span>
<span class="hljs-title">h2</span> = <span class="hljs-number">0x_ffff</span>
<span class="hljs-title">h3</span> = <span class="hljs-number">0x__ffff</span>

<span class="hljs-comment">-- hex float</span>
<span class="hljs-title">hf0</span> = <span class="hljs-number">0x0.1</span>
<span class="hljs-title">hf1</span> = <span class="hljs-number">0x0.01</span>
<span class="hljs-title">hf2</span> = <span class="hljs-number">0xF.FF</span>
<span class="hljs-title">hf3</span> = <span class="hljs-number">0x0.1p41</span>
<span class="hljs-title">hf4</span> = <span class="hljs-number">0x0.1p-4</span>
<span class="hljs-title">hf5</span> = <span class="hljs-number">0x0.1p12</span>
64 changes: 64 additions & 0 deletions test/markup/haskell/numbers.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
-- decimal
million = 1_000_000
billion = 1_000_000_000
lightspeed = 299_792_458
version = 8_04_1
date = 2017_12_31
the_answer = 42

-- hexadecimal
red_mask = 0xff_00_00
size1G = 0x3fff_fff
bigX = 0Xffff

-- octal
world = 0o777
me = 0o700
bigO = 0O700

-- binary
bit8th = 0b01_0000_0000
packbits = 0b1_11_01_0000_0_111
bigbits = 0b1100_1011__1110_1111__0101_0011
bigB = 0B10

-- float
pi = 3.141_592_653_589_793
faraday = 96_485.332_89
avogadro = 6.022_140_857e+23

-- Negative numbers. Note: `-` is an unary operator or infix binary operator
-- depending on context. This is complex to parse, so we've settled on never
-- considering it part of the number across hightlight.js. If this test ever
-- breaks, be sure to check whether `5-3` still highlights as expected.
n0 = -1
n1 = -1.0
n2 = -0xFF0
n3 = -0o123
n4 = -0b001

-- Numeric underscores
x0 = 1_000_000
x1 = 1__000000

e0 = 0.0001
e1 = 0.000_1

f0 = 1e+23
f1 = 1_e+23
f2 = 1__e+23

g0 = 1e+23

h0 = 0xffff
h1 = 0xff_ff
h2 = 0x_ffff
h3 = 0x__ffff

-- hex float
hf0 = 0x0.1
hf1 = 0x0.01
hf2 = 0xF.FF
hf3 = 0x0.1p41
hf4 = 0x0.1p-4
hf5 = 0x0.1p12