UNPKG

7.24 kBJavaScriptView Raw
1/*
2Language: ReasonML
3Description: Reason lets you write simple, fast and quality type safe code while leveraging both the JavaScript & OCaml ecosystems.
4Website: https://reasonml.github.io
5Author: Gidi Meir Morris <oss@gidi.io>
6Category: functional
7*/
8function reasonml(hljs) {
9 function orReValues(ops) {
10 return ops
11 .map(function(op) {
12 return op
13 .split('')
14 .map(function(char) {
15 return '\\' + char;
16 })
17 .join('');
18 })
19 .join('|');
20 }
21
22 const RE_IDENT = '~?[a-z$_][0-9a-zA-Z$_]*';
23 const RE_MODULE_IDENT = '`?[A-Z$_][0-9a-zA-Z$_]*';
24
25 const RE_PARAM_TYPEPARAM = '\'?[a-z$_][0-9a-z$_]*';
26 const RE_PARAM_TYPE = '\\s*:\\s*[a-z$_][0-9a-z$_]*(\\(\\s*(' + RE_PARAM_TYPEPARAM + '\\s*(,' + RE_PARAM_TYPEPARAM + '\\s*)*)?\\))?';
27 const RE_PARAM = RE_IDENT + '(' + RE_PARAM_TYPE + '){0,2}';
28 const RE_OPERATOR = "(" + orReValues([
29 '||',
30 '++',
31 '**',
32 '+.',
33 '*',
34 '/',
35 '*.',
36 '/.',
37 '...'
38 ]) + "|\\|>|&&|==|===)";
39 const RE_OPERATOR_SPACED = "\\s+" + RE_OPERATOR + "\\s+";
40
41 const KEYWORDS = {
42 keyword:
43 'and as asr assert begin class constraint do done downto else end exception external ' +
44 'for fun function functor if in include inherit initializer ' +
45 'land lazy let lor lsl lsr lxor match method mod module mutable new nonrec ' +
46 'object of open or private rec sig struct then to try type val virtual when while with',
47 built_in:
48 'array bool bytes char exn|5 float int int32 int64 list lazy_t|5 nativeint|5 ref string unit ',
49 literal:
50 'true false'
51 };
52
53 const RE_NUMBER = '\\b(0[xX][a-fA-F0-9_]+[Lln]?|' +
54 '0[oO][0-7_]+[Lln]?|' +
55 '0[bB][01_]+[Lln]?|' +
56 '[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)';
57
58 const NUMBER_MODE = {
59 className: 'number',
60 relevance: 0,
61 variants: [
62 {
63 begin: RE_NUMBER
64 },
65 {
66 begin: '\\(-' + RE_NUMBER + '\\)'
67 }
68 ]
69 };
70
71 const OPERATOR_MODE = {
72 className: 'operator',
73 relevance: 0,
74 begin: RE_OPERATOR
75 };
76 const LIST_CONTENTS_MODES = [
77 {
78 className: 'identifier',
79 relevance: 0,
80 begin: RE_IDENT
81 },
82 OPERATOR_MODE,
83 NUMBER_MODE
84 ];
85
86 const MODULE_ACCESS_CONTENTS = [
87 hljs.QUOTE_STRING_MODE,
88 OPERATOR_MODE,
89 {
90 className: 'module',
91 begin: "\\b" + RE_MODULE_IDENT,
92 returnBegin: true,
93 relevance: 0,
94 end: "\.",
95 contains: [
96 {
97 className: 'identifier',
98 begin: RE_MODULE_IDENT,
99 relevance: 0
100 }
101 ]
102 }
103 ];
104
105 const PARAMS_CONTENTS = [
106 {
107 className: 'module',
108 begin: "\\b" + RE_MODULE_IDENT,
109 returnBegin: true,
110 end: "\.",
111 relevance: 0,
112 contains: [
113 {
114 className: 'identifier',
115 begin: RE_MODULE_IDENT,
116 relevance: 0
117 }
118 ]
119 }
120 ];
121
122 const PARAMS_MODE = {
123 begin: RE_IDENT,
124 end: '(,|\\n|\\))',
125 relevance: 0,
126 contains: [
127 OPERATOR_MODE,
128 {
129 className: 'typing',
130 begin: ':',
131 end: '(,|\\n)',
132 returnBegin: true,
133 relevance: 0,
134 contains: PARAMS_CONTENTS
135 }
136 ]
137 };
138
139 const FUNCTION_BLOCK_MODE = {
140 className: 'function',
141 relevance: 0,
142 keywords: KEYWORDS,
143 variants: [
144 {
145 begin: '\\s(\\(\\.?.*?\\)|' + RE_IDENT + ')\\s*=>',
146 end: '\\s*=>',
147 returnBegin: true,
148 relevance: 0,
149 contains: [
150 {
151 className: 'params',
152 variants: [
153 {
154 begin: RE_IDENT
155 },
156 {
157 begin: RE_PARAM
158 },
159 {
160 begin: /\(\s*\)/
161 }
162 ]
163 }
164 ]
165 },
166 {
167 begin: '\\s\\(\\.?[^;\\|]*\\)\\s*=>',
168 end: '\\s=>',
169 returnBegin: true,
170 relevance: 0,
171 contains: [
172 {
173 className: 'params',
174 relevance: 0,
175 variants: [ PARAMS_MODE ]
176 }
177 ]
178 },
179 {
180 begin: '\\(\\.\\s' + RE_IDENT + '\\)\\s*=>'
181 }
182 ]
183 };
184 MODULE_ACCESS_CONTENTS.push(FUNCTION_BLOCK_MODE);
185
186 const CONSTRUCTOR_MODE = {
187 className: 'constructor',
188 begin: RE_MODULE_IDENT + '\\(',
189 end: '\\)',
190 illegal: '\\n',
191 keywords: KEYWORDS,
192 contains: [
193 hljs.QUOTE_STRING_MODE,
194 OPERATOR_MODE,
195 {
196 className: 'params',
197 begin: '\\b' + RE_IDENT
198 }
199 ]
200 };
201
202 const PATTERN_MATCH_BLOCK_MODE = {
203 className: 'pattern-match',
204 begin: '\\|',
205 returnBegin: true,
206 keywords: KEYWORDS,
207 end: '=>',
208 relevance: 0,
209 contains: [
210 CONSTRUCTOR_MODE,
211 OPERATOR_MODE,
212 {
213 relevance: 0,
214 className: 'constructor',
215 begin: RE_MODULE_IDENT
216 }
217 ]
218 };
219
220 const MODULE_ACCESS_MODE = {
221 className: 'module-access',
222 keywords: KEYWORDS,
223 returnBegin: true,
224 variants: [
225 {
226 begin: "\\b(" + RE_MODULE_IDENT + "\\.)+" + RE_IDENT
227 },
228 {
229 begin: "\\b(" + RE_MODULE_IDENT + "\\.)+\\(",
230 end: "\\)",
231 returnBegin: true,
232 contains: [
233 FUNCTION_BLOCK_MODE,
234 {
235 begin: '\\(',
236 end: '\\)',
237 relevance: 0,
238 skip: true
239 }
240 ].concat(MODULE_ACCESS_CONTENTS)
241 },
242 {
243 begin: "\\b(" + RE_MODULE_IDENT + "\\.)+\\{",
244 end: /\}/
245 }
246 ],
247 contains: MODULE_ACCESS_CONTENTS
248 };
249
250 PARAMS_CONTENTS.push(MODULE_ACCESS_MODE);
251
252 return {
253 name: 'ReasonML',
254 aliases: [ 're' ],
255 keywords: KEYWORDS,
256 illegal: '(:-|:=|\\$\\{|\\+=)',
257 contains: [
258 hljs.COMMENT('/\\*', '\\*/', {
259 illegal: '^(#,\\/\\/)'
260 }),
261 {
262 className: 'character',
263 begin: '\'(\\\\[^\']+|[^\'])\'',
264 illegal: '\\n',
265 relevance: 0
266 },
267 hljs.QUOTE_STRING_MODE,
268 {
269 className: 'literal',
270 begin: '\\(\\)',
271 relevance: 0
272 },
273 {
274 className: 'literal',
275 begin: '\\[\\|',
276 end: '\\|\\]',
277 relevance: 0,
278 contains: LIST_CONTENTS_MODES
279 },
280 {
281 className: 'literal',
282 begin: '\\[',
283 end: '\\]',
284 relevance: 0,
285 contains: LIST_CONTENTS_MODES
286 },
287 CONSTRUCTOR_MODE,
288 {
289 className: 'operator',
290 begin: RE_OPERATOR_SPACED,
291 illegal: '-->',
292 relevance: 0
293 },
294 NUMBER_MODE,
295 hljs.C_LINE_COMMENT_MODE,
296 PATTERN_MATCH_BLOCK_MODE,
297 FUNCTION_BLOCK_MODE,
298 {
299 className: 'module-def',
300 begin: "\\bmodule\\s+" + RE_IDENT + "\\s+" + RE_MODULE_IDENT + "\\s+=\\s+\\{",
301 end: /\}/,
302 returnBegin: true,
303 keywords: KEYWORDS,
304 relevance: 0,
305 contains: [
306 {
307 className: 'module',
308 relevance: 0,
309 begin: RE_MODULE_IDENT
310 },
311 {
312 begin: /\{/,
313 end: /\}/,
314 relevance: 0,
315 skip: true
316 }
317 ].concat(MODULE_ACCESS_CONTENTS)
318 },
319 MODULE_ACCESS_MODE
320 ]
321 };
322}
323
324export { reasonml as default };