]> luflow.net public git repositories - flow-web.git/blob - static/highlight/es/languages/haskell.js
Initial commit.
[flow-web.git] / static / highlight / es / languages / haskell.js
1 /*! `haskell` grammar compiled for Highlight.js 11.11.1 */
2 var hljsGrammar = (function () {
3 'use strict';
4
5 /*
6 Language: Haskell
7 Author: Jeremy Hull <sourdrums@gmail.com>
8 Contributors: Zena Treep <zena.treep@gmail.com>
9 Website: https://www.haskell.org
10 Category: functional
11 */
12
13 function haskell(hljs) {
14
15 /* See:
16 - https://www.haskell.org/onlinereport/lexemes.html
17 - https://downloads.haskell.org/ghc/9.0.1/docs/html/users_guide/exts/binary_literals.html
18 - https://downloads.haskell.org/ghc/9.0.1/docs/html/users_guide/exts/numeric_underscores.html
19 - https://downloads.haskell.org/ghc/9.0.1/docs/html/users_guide/exts/hex_float_literals.html
20 */
21 const decimalDigits = '([0-9]_*)+';
22 const hexDigits = '([0-9a-fA-F]_*)+';
23 const binaryDigits = '([01]_*)+';
24 const octalDigits = '([0-7]_*)+';
25 const ascSymbol = '[!#$%&*+.\\/<=>?@\\\\^~-]';
26 const uniSymbol = '(\\p{S}|\\p{P})'; // Symbol or Punctuation
27 const special = '[(),;\\[\\]`|{}]';
28 const symbol = `(${ascSymbol}|(?!(${special}|[_:"']))${uniSymbol})`;
29
30 const COMMENT = { variants: [
31 // Double dash forms a valid comment only if it's not part of legal lexeme.
32 // See: Haskell 98 report: https://www.haskell.org/onlinereport/lexemes.html
33 //
34 // The commented code does the job, but we can't use negative lookbehind,
35 // due to poor support by Safari browser.
36 // > hljs.COMMENT(`(?<!${symbol})--+(?!${symbol})`, '$'),
37 // So instead, we'll add a no-markup rule before the COMMENT rule in the rules list
38 // to match the problematic infix operators that contain double dash.
39 hljs.COMMENT('--+', '$'),
40 hljs.COMMENT(
41 /\{-/,
42 /-\}/,
43 { contains: [ 'self' ] }
44 )
45 ] };
46
47 const PRAGMA = {
48 className: 'meta',
49 begin: /\{-#/,
50 end: /#-\}/
51 };
52
53 const PREPROCESSOR = {
54 className: 'meta',
55 begin: '^#',
56 end: '$'
57 };
58
59 const CONSTRUCTOR = {
60 className: 'type',
61 begin: '\\b[A-Z][\\w\']*', // TODO: other constructors (build-in, infix).
62 relevance: 0
63 };
64
65 const LIST = {
66 begin: '\\(',
67 end: '\\)',
68 illegal: '"',
69 contains: [
70 PRAGMA,
71 PREPROCESSOR,
72 {
73 className: 'type',
74 begin: '\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?'
75 },
76 hljs.inherit(hljs.TITLE_MODE, { begin: '[_a-z][\\w\']*' }),
77 COMMENT
78 ]
79 };
80
81 const RECORD = {
82 begin: /\{/,
83 end: /\}/,
84 contains: LIST.contains
85 };
86
87 const NUMBER = {
88 className: 'number',
89 relevance: 0,
90 variants: [
91 // decimal floating-point-literal (subsumes decimal-literal)
92 { match: `\\b(${decimalDigits})(\\.(${decimalDigits}))?` + `([eE][+-]?(${decimalDigits}))?\\b` },
93 // hexadecimal floating-point-literal (subsumes hexadecimal-literal)
94 { match: `\\b0[xX]_*(${hexDigits})(\\.(${hexDigits}))?` + `([pP][+-]?(${decimalDigits}))?\\b` },
95 // octal-literal
96 { match: `\\b0[oO](${octalDigits})\\b` },
97 // binary-literal
98 { match: `\\b0[bB](${binaryDigits})\\b` }
99 ]
100 };
101
102 return {
103 name: 'Haskell',
104 aliases: [ 'hs' ],
105 keywords:
106 'let in if then else case of where do module import hiding '
107 + 'qualified type data newtype deriving class instance as default '
108 + 'infix infixl infixr foreign export ccall stdcall cplusplus '
109 + 'jvm dotnet safe unsafe family forall mdo proc rec',
110 unicodeRegex: true,
111 contains: [
112 // Top-level constructions.
113 {
114 beginKeywords: 'module',
115 end: 'where',
116 keywords: 'module where',
117 contains: [
118 LIST,
119 COMMENT
120 ],
121 illegal: '\\W\\.|;'
122 },
123 {
124 begin: '\\bimport\\b',
125 end: '$',
126 keywords: 'import qualified as hiding',
127 contains: [
128 LIST,
129 COMMENT
130 ],
131 illegal: '\\W\\.|;'
132 },
133 {
134 className: 'class',
135 begin: '^(\\s*)?(class|instance)\\b',
136 end: 'where',
137 keywords: 'class family instance where',
138 contains: [
139 CONSTRUCTOR,
140 LIST,
141 COMMENT
142 ]
143 },
144 {
145 className: 'class',
146 begin: '\\b(data|(new)?type)\\b',
147 end: '$',
148 keywords: 'data family type newtype deriving',
149 contains: [
150 PRAGMA,
151 CONSTRUCTOR,
152 LIST,
153 RECORD,
154 COMMENT
155 ]
156 },
157 {
158 beginKeywords: 'default',
159 end: '$',
160 contains: [
161 CONSTRUCTOR,
162 LIST,
163 COMMENT
164 ]
165 },
166 {
167 beginKeywords: 'infix infixl infixr',
168 end: '$',
169 contains: [
170 hljs.C_NUMBER_MODE,
171 COMMENT
172 ]
173 },
174 {
175 begin: '\\bforeign\\b',
176 end: '$',
177 keywords: 'foreign import export ccall stdcall cplusplus jvm '
178 + 'dotnet safe unsafe',
179 contains: [
180 CONSTRUCTOR,
181 hljs.QUOTE_STRING_MODE,
182 COMMENT
183 ]
184 },
185 {
186 className: 'meta',
187 begin: '#!\\/usr\\/bin\\/env\ runhaskell',
188 end: '$'
189 },
190 // "Whitespaces".
191 PRAGMA,
192 PREPROCESSOR,
193
194 // Literals and names.
195
196 // Single characters.
197 {
198 scope: 'string',
199 begin: /'(?=\\?.')/,
200 end: /'/,
201 contains: [
202 {
203 scope: 'char.escape',
204 match: /\\./,
205 },
206 ]
207 },
208 hljs.QUOTE_STRING_MODE,
209 NUMBER,
210 CONSTRUCTOR,
211 hljs.inherit(hljs.TITLE_MODE, { begin: '^[_a-z][\\w\']*' }),
212 // No markup, prevents infix operators from being recognized as comments.
213 { begin: `(?!-)${symbol}--+|--+(?!-)${symbol}`},
214 COMMENT,
215 { // No markup, relevance booster
216 begin: '->|<-' }
217 ]
218 };
219 }
220
221 return haskell;
222
223 })();
224 ;
225 export default hljsGrammar;