basant307/AI_Governance_Project
048
1/**2 * @param {string} value3 * @returns {RegExp}4 * */5function escape(value) {6 return new RegExp(value.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&'), 'm');7}8 9/**10 * @param {RegExp | string } re11 * @returns {string}12 */13function source(re) {14 if (!re) return null;15 if (typeof re === "string") return re;16 17 return re.source;18}19 20/**21 * @param {RegExp | string } re22 * @returns {string}23 */24function lookahead(re) {25 return concat('(?=', re, ')');26}27 28/**29 * @param {...(RegExp | string) } args30 * @returns {string}31 */32function concat(...args) {33 const joined = args.map((x) => source(x)).join("");34 return joined;35}36 37/**38 * @param { Array<string | RegExp | Object> } args39 * @returns {object}40 */41function stripOptionsFromArgs(args) {42 const opts = args[args.length - 1];43 44 if (typeof opts === 'object' && opts.constructor === Object) {45 args.splice(args.length - 1, 1);46 return opts;47 } else {48 return {};49 }50}51 52/** @typedef { {capture?: boolean} } RegexEitherOptions */53 54/**55 * Any of the passed expresssions may match56 *57 * Creates a huge this | this | that | that match58 * @param {(RegExp | string)[] | [...(RegExp | string)[], RegexEitherOptions]} args59 * @returns {string}60 */61function either(...args) {62 /** @type { object & {capture?: boolean} } */63 const opts = stripOptionsFromArgs(args);64 const joined = '('65 + (opts.capture ? "" : "?:")66 + args.map((x) => source(x)).join("|") + ")";67 return joined;68}69 70/*71Language: F#72Author: Jonas Follesø <jonas@follesoe.no>73Contributors: Troy Kershaw <hello@troykershaw.com>, Henrik Feldt <henrik@haf.se>, Melvyn Laïly <melvyn.laily@gmail.com>74Website: https://docs.microsoft.com/en-us/dotnet/fsharp/75Category: functional76*/77 78 79/** @type LanguageFn */80function fsharp(hljs) {81 const KEYWORDS = [82 "abstract",83 "and",84 "as",85 "assert",86 "base",87 "begin",88 "class",89 "default",90 "delegate",91 "do",92 "done",93 "downcast",94 "downto",95 "elif",96 "else",97 "end",98 "exception",99 "extern",100 // "false", // literal101 "finally",102 "fixed",103 "for",104 "fun",105 "function",106 "global",107 "if",108 "in",109 "inherit",110 "inline",111 "interface",112 "internal",113 "lazy",114 "let",115 "match",116 "member",117 "module",118 "mutable",119 "namespace",120 "new",121 // "not", // built_in122 // "null", // literal123 "of",124 "open",125 "or",126 "override",127 "private",128 "public",129 "rec",130 "return",131 "static",132 "struct",133 "then",134 "to",135 // "true", // literal136 "try",137 "type",138 "upcast",139 "use",140 "val",141 "void",142 "when",143 "while",144 "with",145 "yield"146 ];147 148 const BANG_KEYWORD_MODE = {149 // monad builder keywords (matches before non-bang keywords)150 scope: 'keyword',151 match: /\b(yield|return|let|do|match|use)!/152 };153 154 const PREPROCESSOR_KEYWORDS = [155 "if",156 "else",157 "endif",158 "line",159 "nowarn",160 "light",161 "r",162 "i",163 "I",164 "load",165 "time",166 "help",167 "quit"168 ];169 170 const LITERALS = [171 "true",172 "false",173 "null",174 "Some",175 "None",176 "Ok",177 "Error",178 "infinity",179 "infinityf",180 "nan",181 "nanf"182 ];183 184 const SPECIAL_IDENTIFIERS = [185 "__LINE__",186 "__SOURCE_DIRECTORY__",187 "__SOURCE_FILE__"188 ];189 190 // Since it's possible to re-bind/shadow names (e.g. let char = 'c'),191 // these builtin types should only be matched when a type name is expected.192 const KNOWN_TYPES = [193 // basic types194 "bool",195 "byte",196 "sbyte",197 "int8",198 "int16",199 "int32",200 "uint8",201 "uint16",202 "uint32",203 "int",204 "uint",205 "int64",206 "uint64",207 "nativeint",208 "unativeint",209 "decimal",210 "float",211 "double",212 "float32",213 "single",214 "char",215 "string",216 "unit",217 "bigint",218 // other native types or lowercase aliases219 "option",220 "voption",221 "list",222 "array",223 "seq",224 "byref",225 "exn",226 "inref",227 "nativeptr",228 "obj",229 "outref",230 "voidptr",231 // other important FSharp types232 "Result"233 ];234 235 const BUILTINS = [236 // Somewhat arbitrary list of builtin functions and values.237 // Most of them are declared in Microsoft.FSharp.Core238 // I tried to stay relevant by adding only the most idiomatic239 // and most used symbols that are not already declared as types.240 "not",241 "ref",242 "raise",243 "reraise",244 "dict",245 "readOnlyDict",246 "set",247 "get",248 "enum",249 "sizeof",250 "typeof",251 "typedefof",252 "nameof",253 "nullArg",254 "invalidArg",255 "invalidOp",256 "id",257 "fst",258 "snd",259 "ignore",260 "lock",261 "using",262 "box",263 "unbox",264 "tryUnbox",265 "printf",266 "printfn",267 "sprintf",268 "eprintf",269 "eprintfn",270 "fprintf",271 "fprintfn",272 "failwith",273 "failwithf"274 ];275 276 const ALL_KEYWORDS = {277 keyword: KEYWORDS,278 literal: LITERALS,279 built_in: BUILTINS,280 'variable.constant': SPECIAL_IDENTIFIERS281 };282 283 // (* potentially multi-line Meta Language style comment *)284 const ML_COMMENT =285 hljs.COMMENT(/\(\*(?!\))/, /\*\)/, {286 contains: ["self"]287 });288 // Either a multi-line (* Meta Language style comment *) or a single line // C style comment.289 const COMMENT = {290 variants: [291 ML_COMMENT,292 hljs.C_LINE_COMMENT_MODE,293 ]294 };295 296 // Most identifiers can contain apostrophes297 const IDENTIFIER_RE = /[a-zA-Z_](\w|')*/;298 299 const QUOTED_IDENTIFIER = {300 scope: 'variable',301 begin: /``/,302 end: /``/303 };304 305 // 'a or ^a where a can be a ``quoted identifier``306 const BEGIN_GENERIC_TYPE_SYMBOL_RE = /\B('|\^)/;307 const GENERIC_TYPE_SYMBOL = {308 scope: 'symbol',309 variants: [310 // the type name is a quoted identifier:311 { match: concat(BEGIN_GENERIC_TYPE_SYMBOL_RE, /``.*?``/) },312 // the type name is a normal identifier (we don't use IDENTIFIER_RE because there cannot be another apostrophe here):313 { match: concat(BEGIN_GENERIC_TYPE_SYMBOL_RE, hljs.UNDERSCORE_IDENT_RE) }314 ],315 relevance: 0316 };317 318 const makeOperatorMode = function({ includeEqual }) {319 // List or symbolic operator characters from the FSharp Spec 4.1, minus the dot, and with `?` added, used for nullable operators.320 let allOperatorChars;321 if (includeEqual)322 allOperatorChars = "!%&*+-/<=>@^|~?";323 else324 allOperatorChars = "!%&*+-/<>@^|~?";325 const OPERATOR_CHARS = Array.from(allOperatorChars);326 const OPERATOR_CHAR_RE = concat('[', ...OPERATOR_CHARS.map(escape), ']');327 // The lone dot operator is special. It cannot be redefined, and we don't want to highlight it. It can be used as part of a multi-chars operator though.328 const OPERATOR_CHAR_OR_DOT_RE = either(OPERATOR_CHAR_RE, /\./);329 // When a dot is present, it must be followed by another operator char:330 const OPERATOR_FIRST_CHAR_OF_MULTIPLE_RE = concat(OPERATOR_CHAR_OR_DOT_RE, lookahead(OPERATOR_CHAR_OR_DOT_RE));331 const SYMBOLIC_OPERATOR_RE = either(332 concat(OPERATOR_FIRST_CHAR_OF_MULTIPLE_RE, OPERATOR_CHAR_OR_DOT_RE, '*'), // Matches at least 2 chars operators333 concat(OPERATOR_CHAR_RE, '+'), // Matches at least one char operators334 );335 return {336 scope: 'operator',337 match: either(338 // symbolic operators:339 SYMBOLIC_OPERATOR_RE,340 // other symbolic keywords:341 // Type casting and conversion operators:342 /:\?>/,343 /:\?/,344 /:>/,345 /:=/, // Reference cell assignment346 /::?/, // : or ::347 /\$/), // A single $ can be used as an operator348 relevance: 0349 };350 };351 352 const OPERATOR = makeOperatorMode({ includeEqual: true });353 // This variant is used when matching '=' should end a parent mode:354 const OPERATOR_WITHOUT_EQUAL = makeOperatorMode({ includeEqual: false });355 356 const makeTypeAnnotationMode = function(prefix, prefixScope) {357 return {358 begin: concat( // a type annotation is a359 prefix, // should be a colon or the 'of' keyword360 lookahead( // that has to be followed by361 concat(362 /\s*/, // optional space363 either( // then either of:364 /\w/, // word365 /'/, // generic type name366 /\^/, // generic type name367 /#/, // flexible type name368 /``/, // quoted type name369 /\(/, // parens type expression370 /{\|/, // anonymous type annotation371 )))),372 beginScope: prefixScope,373 // BUG: because ending with \n is necessary for some cases, multi-line type annotations are not properly supported.374 // Examples where \n is required at the end:375 // - abstract member definitions in classes: abstract Property : int * string376 // - return type annotations: let f f' = f' () : returnTypeAnnotation377 // - record fields definitions: { A : int \n B : string }378 end: lookahead(379 either(380 /\n/,381 /=/)),382 relevance: 0,383 // we need the known types, and we need the type constraint keywords and literals. e.g.: when 'a : null384 keywords: hljs.inherit(ALL_KEYWORDS, { type: KNOWN_TYPES }),385 contains: [386 COMMENT,387 GENERIC_TYPE_SYMBOL,388 hljs.inherit(QUOTED_IDENTIFIER, { scope: null }), // match to avoid strange patterns inside that may break the parsing389 OPERATOR_WITHOUT_EQUAL390 ]391 };392 };393 394 const TYPE_ANNOTATION = makeTypeAnnotationMode(/:/, 'operator');395 const DISCRIMINATED_UNION_TYPE_ANNOTATION = makeTypeAnnotationMode(/\bof\b/, 'keyword');396 397 // type MyType<'a> = ...398 const TYPE_DECLARATION = {399 begin: [400 /(^|\s+)/, // prevents matching the following: `match s.stype with`401 /type/,402 /\s+/,403 IDENTIFIER_RE404 ],405 beginScope: {406 2: 'keyword',407 4: 'title.class'408 },409 end: lookahead(/\(|=|$/),410 keywords: ALL_KEYWORDS, // match keywords in type constraints. e.g.: when 'a : null411 contains: [412 COMMENT,413 hljs.inherit(QUOTED_IDENTIFIER, { scope: null }), // match to avoid strange patterns inside that may break the parsing414 GENERIC_TYPE_SYMBOL,415 {416 // For visual consistency, highlight type brackets as operators.417 scope: 'operator',418 match: /<|>/419 },420 TYPE_ANNOTATION // generic types can have constraints, which are type annotations. e.g. type MyType<'T when 'T : delegate<obj * string>> =421 ]422 };423 424 const COMPUTATION_EXPRESSION = {425 // computation expressions:426 scope: 'computation-expression',427 // BUG: might conflict with record deconstruction. e.g. let f { Name = name } = name // will highlight f428 match: /\b[_a-z]\w*(?=\s*\{)/429 };430 431 const PREPROCESSOR = {432 // preprocessor directives and fsi commands:433 begin: [434 /^\s*/,435 concat(/#/, either(...PREPROCESSOR_KEYWORDS)),436 /\b/437 ],438 beginScope: { 2: 'meta' },439 end: lookahead(/\s|$/)440 };441 442 // TODO: this definition is missing support for type suffixes and octal notation.443 // BUG: range operator without any space is wrongly interpreted as a single number (e.g. 1..10 )444 const NUMBER = {445 variants: [446 hljs.BINARY_NUMBER_MODE,447 hljs.C_NUMBER_MODE448 ]449 };450 451 // All the following string definitions are potentially multi-line.452 // BUG: these definitions are missing support for byte strings (suffixed with B)453 454 // "..."455 const QUOTED_STRING = {456 scope: 'string',457 begin: /"/,458 end: /"/,459 contains: [460 hljs.BACKSLASH_ESCAPE461 ]462 };463 // @"..."464 const VERBATIM_STRING = {465 scope: 'string',466 begin: /@"/,467 end: /"/,468 contains: [469 {470 match: /""/ // escaped "471 },472 hljs.BACKSLASH_ESCAPE473 ]474 };475 // """..."""476 const TRIPLE_QUOTED_STRING = {477 scope: 'string',478 begin: /"""/,479 end: /"""/,480 relevance: 2481 };482 const SUBST = {483 scope: 'subst',484 begin: /\{/,485 end: /\}/,486 keywords: ALL_KEYWORDS487 };488 // $"...{1+1}..."489 const INTERPOLATED_STRING = {490 scope: 'string',491 begin: /\$"/,492 end: /"/,493 contains: [494 {495 match: /\{\{/ // escaped {496 },497 {498 match: /\}\}/ // escaped }499 },500 hljs.BACKSLASH_ESCAPE,501 SUBST502 ]503 };504 // $@"...{1+1}..."505 const INTERPOLATED_VERBATIM_STRING = {506 scope: 'string',507 begin: /(\$@|@\$)"/,508 end: /"/,509 contains: [510 {511 match: /\{\{/ // escaped {512 },513 {514 match: /\}\}/ // escaped }515 },516 {517 match: /""/518 },519 hljs.BACKSLASH_ESCAPE,520 SUBST521 ]522 };523 // $"""...{1+1}..."""524 const INTERPOLATED_TRIPLE_QUOTED_STRING = {525 scope: 'string',526 begin: /\$"""/,527 end: /"""/,528 contains: [529 {530 match: /\{\{/ // escaped {531 },532 {533 match: /\}\}/ // escaped }534 },535 SUBST536 ],537 relevance: 2538 };539 // '.'540 const CHAR_LITERAL = {541 scope: 'string',542 match: concat(543 /'/,544 either(545 /[^\\']/, // either a single non escaped char...546 /\\(?:.|\d{3}|x[a-fA-F\d]{2}|u[a-fA-F\d]{4}|U[a-fA-F\d]{8})/ // ...or an escape sequence547 ),548 /'/549 )550 };551 // F# allows a lot of things inside string placeholders.552 // Things that don't currently seem allowed by the compiler: types definition, attributes usage.553 // (Strictly speaking, some of the followings are only allowed inside triple quoted interpolated strings...)554 SUBST.contains = [555 INTERPOLATED_VERBATIM_STRING,556 INTERPOLATED_STRING,557 VERBATIM_STRING,558 QUOTED_STRING,559 CHAR_LITERAL,560 BANG_KEYWORD_MODE,561 COMMENT,562 QUOTED_IDENTIFIER,563 TYPE_ANNOTATION,564 COMPUTATION_EXPRESSION,565 PREPROCESSOR,566 NUMBER,567 GENERIC_TYPE_SYMBOL,568 OPERATOR569 ];570 const STRING = {571 variants: [572 INTERPOLATED_TRIPLE_QUOTED_STRING,573 INTERPOLATED_VERBATIM_STRING,574 INTERPOLATED_STRING,575 TRIPLE_QUOTED_STRING,576 VERBATIM_STRING,577 QUOTED_STRING,578 CHAR_LITERAL579 ]580 };581 582 return {583 name: 'F#',584 aliases: [585 'fs',586 'f#'587 ],588 keywords: ALL_KEYWORDS,589 illegal: /\/\*/,590 classNameAliases: {591 'computation-expression': 'keyword'592 },593 contains: [594 BANG_KEYWORD_MODE,595 STRING,596 COMMENT,597 QUOTED_IDENTIFIER,598 TYPE_DECLARATION,599 {600 // e.g. [<Attributes("")>] or [<``module``: MyCustomAttributeThatWorksOnModules>]601 // or [<Sealed; NoEquality; NoComparison; CompiledName("FSharpAsync`1")>]602 scope: 'meta',603 begin: /\[</,604 end: />\]/,605 relevance: 2,606 contains: [607 QUOTED_IDENTIFIER,608 // can contain any constant value609 TRIPLE_QUOTED_STRING,610 VERBATIM_STRING,611 QUOTED_STRING,612 CHAR_LITERAL,613 NUMBER614 ]615 },616 DISCRIMINATED_UNION_TYPE_ANNOTATION,617 TYPE_ANNOTATION,618 COMPUTATION_EXPRESSION,619 PREPROCESSOR,620 NUMBER,621 GENERIC_TYPE_SYMBOL,622 OPERATOR623 ]624 };625}626 627export { fsharp as default };628 