1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | function source(re) {
|
11 | if (!re) return null;
|
12 | if (typeof re === "string") return re;
|
13 |
|
14 | return re.source;
|
15 | }
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 | function lookahead(re) {
|
22 | return concat('(?=', re, ')');
|
23 | }
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 | function concat(...args) {
|
30 | const joined = args.map((x) => source(x)).join("");
|
31 | return joined;
|
32 | }
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 | function stripOptionsFromArgs(args) {
|
39 | const opts = args[args.length - 1];
|
40 |
|
41 | if (typeof opts === 'object' && opts.constructor === Object) {
|
42 | args.splice(args.length - 1, 1);
|
43 | return opts;
|
44 | } else {
|
45 | return {};
|
46 | }
|
47 | }
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 | function either(...args) {
|
57 |
|
58 | const opts = stripOptionsFromArgs(args);
|
59 | const joined = '('
|
60 | + (opts.capture ? "" : "?:")
|
61 | + args.map((x) => source(x)).join("|") + ")";
|
62 | return joined;
|
63 | }
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 | function fsharp(hljs) {
|
75 | const KEYWORDS = [
|
76 | "abstract",
|
77 | "and",
|
78 | "as",
|
79 | "assert",
|
80 | "base",
|
81 | "begin",
|
82 | "class",
|
83 | "default",
|
84 | "delegate",
|
85 | "do",
|
86 | "done",
|
87 | "downcast",
|
88 | "downto",
|
89 | "elif",
|
90 | "else",
|
91 | "end",
|
92 | "exception",
|
93 | "extern",
|
94 |
|
95 | "finally",
|
96 | "fixed",
|
97 | "for",
|
98 | "fun",
|
99 | "function",
|
100 | "global",
|
101 | "if",
|
102 | "in",
|
103 | "inherit",
|
104 | "inline",
|
105 | "interface",
|
106 | "internal",
|
107 | "lazy",
|
108 | "let",
|
109 | "match",
|
110 | "member",
|
111 | "module",
|
112 | "mutable",
|
113 | "namespace",
|
114 | "new",
|
115 |
|
116 |
|
117 | "of",
|
118 | "open",
|
119 | "or",
|
120 | "override",
|
121 | "private",
|
122 | "public",
|
123 | "rec",
|
124 | "return",
|
125 | "static",
|
126 | "struct",
|
127 | "then",
|
128 | "to",
|
129 |
|
130 | "try",
|
131 | "type",
|
132 | "upcast",
|
133 | "use",
|
134 | "val",
|
135 | "void",
|
136 | "when",
|
137 | "while",
|
138 | "with",
|
139 | "yield"
|
140 | ];
|
141 |
|
142 | const BANG_KEYWORD_MODE = {
|
143 |
|
144 | scope: 'keyword',
|
145 | match: /\b(yield|return|let|do|match|use)!/
|
146 | };
|
147 |
|
148 | const PREPROCESSOR_KEYWORDS = [
|
149 | "if",
|
150 | "else",
|
151 | "endif",
|
152 | "line",
|
153 | "nowarn",
|
154 | "light",
|
155 | "r",
|
156 | "i",
|
157 | "I",
|
158 | "load",
|
159 | "time",
|
160 | "help",
|
161 | "quit"
|
162 | ];
|
163 |
|
164 | const LITERALS = [
|
165 | "true",
|
166 | "false",
|
167 | "null",
|
168 | "Some",
|
169 | "None",
|
170 | "Ok",
|
171 | "Error",
|
172 | "infinity",
|
173 | "infinityf",
|
174 | "nan",
|
175 | "nanf"
|
176 | ];
|
177 |
|
178 | const SPECIAL_IDENTIFIERS = [
|
179 | "__LINE__",
|
180 | "__SOURCE_DIRECTORY__",
|
181 | "__SOURCE_FILE__"
|
182 | ];
|
183 |
|
184 | const TYPES = [
|
185 |
|
186 | "bool",
|
187 | "byte",
|
188 | "sbyte",
|
189 | "int8",
|
190 | "int16",
|
191 | "int32",
|
192 | "uint8",
|
193 | "uint16",
|
194 | "uint32",
|
195 | "int",
|
196 | "uint",
|
197 | "int64",
|
198 | "uint64",
|
199 | "nativeint",
|
200 | "unativeint",
|
201 | "decimal",
|
202 | "float",
|
203 | "double",
|
204 | "float32",
|
205 | "single",
|
206 | "char",
|
207 | "string",
|
208 | "unit",
|
209 | "bigint",
|
210 |
|
211 | "option",
|
212 | "voption",
|
213 | "list",
|
214 | "array",
|
215 | "seq",
|
216 | "byref",
|
217 | "exn",
|
218 | "inref",
|
219 | "nativeptr",
|
220 | "obj",
|
221 | "outref",
|
222 | "voidptr"
|
223 | ];
|
224 |
|
225 | const BUILTINS = [
|
226 |
|
227 |
|
228 |
|
229 |
|
230 | "not",
|
231 | "ref",
|
232 | "raise",
|
233 | "reraise",
|
234 | "dict",
|
235 | "readOnlyDict",
|
236 | "set",
|
237 | "enum",
|
238 | "sizeof",
|
239 | "typeof",
|
240 | "typedefof",
|
241 | "nameof",
|
242 | "nullArg",
|
243 | "invalidArg",
|
244 | "invalidOp",
|
245 | "id",
|
246 | "fst",
|
247 | "snd",
|
248 | "ignore",
|
249 | "lock",
|
250 | "using",
|
251 | "box",
|
252 | "unbox",
|
253 | "tryUnbox",
|
254 | "printf",
|
255 | "printfn",
|
256 | "sprintf",
|
257 | "eprintf",
|
258 | "eprintfn",
|
259 | "fprintf",
|
260 | "fprintfn",
|
261 | "failwith",
|
262 | "failwithf"
|
263 | ];
|
264 |
|
265 | const ALL_KEYWORDS = {
|
266 | type: TYPES,
|
267 | keyword: KEYWORDS,
|
268 | literal: LITERALS,
|
269 | built_in: BUILTINS,
|
270 | 'variable.constant': SPECIAL_IDENTIFIERS
|
271 | };
|
272 |
|
273 |
|
274 | const ML_COMMENT =
|
275 | hljs.COMMENT(/\(\*(?!\))/, /\*\)/, {
|
276 | contains: ["self"]
|
277 | });
|
278 |
|
279 | const COMMENT = {
|
280 | variants: [
|
281 | ML_COMMENT,
|
282 | hljs.C_LINE_COMMENT_MODE,
|
283 | ]
|
284 | };
|
285 |
|
286 |
|
287 | const GENERIC_TYPE_SYMBOL = {
|
288 | match: concat(/('|\^)/, hljs.UNDERSCORE_IDENT_RE),
|
289 | scope: 'symbol',
|
290 | relevance: 0
|
291 | };
|
292 |
|
293 | const COMPUTATION_EXPRESSION = {
|
294 |
|
295 | scope: 'computation-expression',
|
296 | match: /\b[_a-z]\w*(?=\s*\{)/
|
297 | };
|
298 |
|
299 | const PREPROCESSOR = {
|
300 |
|
301 | begin: [
|
302 | /^\s*/,
|
303 | concat(/#/, either(...PREPROCESSOR_KEYWORDS)),
|
304 | /\b/
|
305 | ],
|
306 | beginScope: { 2: 'meta' },
|
307 | end: lookahead(/\s|$/)
|
308 | };
|
309 |
|
310 |
|
311 |
|
312 | const NUMBER = {
|
313 | variants: [
|
314 | hljs.BINARY_NUMBER_MODE,
|
315 | hljs.C_NUMBER_MODE
|
316 | ]
|
317 | };
|
318 |
|
319 |
|
320 |
|
321 |
|
322 |
|
323 | const QUOTED_STRING = {
|
324 | scope: 'string',
|
325 | begin: /"/,
|
326 | end: /"/,
|
327 | contains: [
|
328 | hljs.BACKSLASH_ESCAPE
|
329 | ]
|
330 | };
|
331 |
|
332 | const VERBATIM_STRING = {
|
333 | scope: 'string',
|
334 | begin: /@"/,
|
335 | end: /"/,
|
336 | contains: [
|
337 | {
|
338 | match: /""/
|
339 | },
|
340 | hljs.BACKSLASH_ESCAPE
|
341 | ]
|
342 | };
|
343 |
|
344 | const TRIPLE_QUOTED_STRING = {
|
345 | scope: 'string',
|
346 | begin: /"""/,
|
347 | end: /"""/,
|
348 | relevance: 2
|
349 | };
|
350 | const SUBST = {
|
351 | scope: 'subst',
|
352 | begin: /\{/,
|
353 | end: /\}/,
|
354 | keywords: ALL_KEYWORDS
|
355 | };
|
356 |
|
357 | const INTERPOLATED_STRING = {
|
358 | scope: 'string',
|
359 | begin: /\$"/,
|
360 | end: /"/,
|
361 | contains: [
|
362 | {
|
363 | match: /\{\{/
|
364 | },
|
365 | {
|
366 | match: /\}\}/
|
367 | },
|
368 | hljs.BACKSLASH_ESCAPE,
|
369 | SUBST
|
370 | ]
|
371 | };
|
372 |
|
373 | const INTERPOLATED_VERBATIM_STRING = {
|
374 | scope: 'string',
|
375 | begin: /(\$@|@\$)"/,
|
376 | end: /"/,
|
377 | contains: [
|
378 | {
|
379 | match: /\{\{/
|
380 | },
|
381 | {
|
382 | match: /\}\}/
|
383 | },
|
384 | {
|
385 | match: /""/
|
386 | },
|
387 | hljs.BACKSLASH_ESCAPE,
|
388 | SUBST
|
389 | ]
|
390 | };
|
391 |
|
392 | const INTERPOLATED_TRIPLE_QUOTED_STRING = {
|
393 | scope: 'string',
|
394 | begin: /\$"""/,
|
395 | end: /"""/,
|
396 | contains: [
|
397 | {
|
398 | match: /\{\{/
|
399 | },
|
400 | {
|
401 | match: /\}\}/
|
402 | },
|
403 | SUBST
|
404 | ],
|
405 | relevance: 2
|
406 | };
|
407 |
|
408 | const CHAR_LITERAL = {
|
409 | scope: 'string',
|
410 | match: concat(
|
411 | /'/,
|
412 | either(
|
413 | /[^\\']/, // either a single non escaped char...
|
414 | /\\(?:.|\d{3}|x[a-fA-F\d]{2}|u[a-fA-F\d]{4}|U[a-fA-F\d]{8})/
|
415 | ),
|
416 | /'/
|
417 | )
|
418 | };
|
419 |
|
420 |
|
421 |
|
422 | SUBST.contains = [
|
423 | INTERPOLATED_VERBATIM_STRING,
|
424 | INTERPOLATED_STRING,
|
425 | VERBATIM_STRING,
|
426 | QUOTED_STRING,
|
427 | CHAR_LITERAL,
|
428 | BANG_KEYWORD_MODE,
|
429 | COMMENT,
|
430 | COMPUTATION_EXPRESSION,
|
431 | PREPROCESSOR,
|
432 | NUMBER,
|
433 | GENERIC_TYPE_SYMBOL
|
434 | ];
|
435 | const STRING = {
|
436 | variants: [
|
437 | INTERPOLATED_TRIPLE_QUOTED_STRING,
|
438 | INTERPOLATED_VERBATIM_STRING,
|
439 | INTERPOLATED_STRING,
|
440 | TRIPLE_QUOTED_STRING,
|
441 | VERBATIM_STRING,
|
442 | QUOTED_STRING,
|
443 | CHAR_LITERAL
|
444 | ]
|
445 | };
|
446 |
|
447 | return {
|
448 | name: 'F#',
|
449 | aliases: [
|
450 | 'fs',
|
451 | 'f#'
|
452 | ],
|
453 | keywords: ALL_KEYWORDS,
|
454 | illegal: /\/\*/,
|
455 | classNameAliases: {
|
456 | 'computation-expression': 'keyword'
|
457 | },
|
458 | contains: [
|
459 | BANG_KEYWORD_MODE,
|
460 | STRING,
|
461 | COMMENT,
|
462 | {
|
463 |
|
464 | begin: [
|
465 | /type/,
|
466 | /\s+/,
|
467 | hljs.UNDERSCORE_IDENT_RE
|
468 | ],
|
469 | beginScope: {
|
470 | 1: 'keyword',
|
471 | 3: 'title.class'
|
472 | },
|
473 | end: lookahead(/\(|=|$/),
|
474 | contains: [
|
475 | GENERIC_TYPE_SYMBOL
|
476 | ]
|
477 | },
|
478 | {
|
479 |
|
480 | scope: 'meta',
|
481 | begin: /^\s*\[</,
|
482 | excludeBegin: true,
|
483 | end: lookahead(/>\]/),
|
484 | relevance: 2,
|
485 | contains: [
|
486 | {
|
487 | scope: 'string',
|
488 | begin: /"/,
|
489 | end: /"/
|
490 | },
|
491 | NUMBER
|
492 | ]
|
493 | },
|
494 | COMPUTATION_EXPRESSION,
|
495 | PREPROCESSOR,
|
496 | NUMBER,
|
497 | GENERIC_TYPE_SYMBOL
|
498 | ]
|
499 | };
|
500 | }
|
501 |
|
502 | export { fsharp as default };
|