basant307/AI_Governance_Project
048
1/*2Language: Elixir3Author: Josh Adams <josh@isotope11.com>4Description: language definition for Elixir source code files (.ex and .exs). Based on ruby language support.5Category: functional6Website: https://elixir-lang.org7*/8 9/** @type LanguageFn */10function elixir(hljs) {11 const regex = hljs.regex;12 const ELIXIR_IDENT_RE = '[a-zA-Z_][a-zA-Z0-9_.]*(!|\\?)?';13 const ELIXIR_METHOD_RE = '[a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?';14 const KEYWORDS = [15 "after",16 "alias",17 "and",18 "case",19 "catch",20 "cond",21 "defstruct",22 "defguard",23 "do",24 "else",25 "end",26 "fn",27 "for",28 "if",29 "import",30 "in",31 "not",32 "or",33 "quote",34 "raise",35 "receive",36 "require",37 "reraise",38 "rescue",39 "try",40 "unless",41 "unquote",42 "unquote_splicing",43 "use",44 "when",45 "with|0"46 ];47 const LITERALS = [48 "false",49 "nil",50 "true"51 ];52 const KWS = {53 $pattern: ELIXIR_IDENT_RE,54 keyword: KEYWORDS,55 literal: LITERALS56 };57 const SUBST = {58 className: 'subst',59 begin: /#\{/,60 end: /\}/,61 keywords: KWS62 };63 const NUMBER = {64 className: 'number',65 begin: '(\\b0o[0-7_]+)|(\\b0b[01_]+)|(\\b0x[0-9a-fA-F_]+)|(-?\\b[0-9][0-9_]*(\\.[0-9_]+([eE][-+]?[0-9]+)?)?)',66 relevance: 067 };68 // TODO: could be tightened69 // https://elixir-lang.readthedocs.io/en/latest/intro/18.html70 // but you also need to include closing delemeters in the escape list per71 // individual sigil mode from what I can tell,72 // ie: \} might or might not be an escape depending on the sigil used73 const ESCAPES_RE = /\\[\s\S]/;74 // const ESCAPES_RE = /\\["'\\abdefnrstv0]/;75 const BACKSLASH_ESCAPE = {76 match: ESCAPES_RE,77 scope: "char.escape",78 relevance: 079 };80 const SIGIL_DELIMITERS = '[/|([{<"\']';81 const SIGIL_DELIMITER_MODES = [82 {83 begin: /"/,84 end: /"/85 },86 {87 begin: /'/,88 end: /'/89 },90 {91 begin: /\//,92 end: /\//93 },94 {95 begin: /\|/,96 end: /\|/97 },98 {99 begin: /\(/,100 end: /\)/101 },102 {103 begin: /\[/,104 end: /\]/105 },106 {107 begin: /\{/,108 end: /\}/109 },110 {111 begin: /</,112 end: />/113 }114 ];115 const escapeSigilEnd = (end) => {116 return {117 scope: "char.escape",118 begin: regex.concat(/\\/, end),119 relevance: 0120 };121 };122 const LOWERCASE_SIGIL = {123 className: 'string',124 begin: '~[a-z]' + '(?=' + SIGIL_DELIMITERS + ')',125 contains: SIGIL_DELIMITER_MODES.map(x => hljs.inherit(x,126 { contains: [127 escapeSigilEnd(x.end),128 BACKSLASH_ESCAPE,129 SUBST130 ] }131 ))132 };133 134 const UPCASE_SIGIL = {135 className: 'string',136 begin: '~[A-Z]' + '(?=' + SIGIL_DELIMITERS + ')',137 contains: SIGIL_DELIMITER_MODES.map(x => hljs.inherit(x,138 { contains: [ escapeSigilEnd(x.end) ] }139 ))140 };141 142 const REGEX_SIGIL = {143 className: 'regex',144 variants: [145 {146 begin: '~r' + '(?=' + SIGIL_DELIMITERS + ')',147 contains: SIGIL_DELIMITER_MODES.map(x => hljs.inherit(x,148 {149 end: regex.concat(x.end, /[uismxfU]{0,7}/),150 contains: [151 escapeSigilEnd(x.end),152 BACKSLASH_ESCAPE,153 SUBST154 ]155 }156 ))157 },158 {159 begin: '~R' + '(?=' + SIGIL_DELIMITERS + ')',160 contains: SIGIL_DELIMITER_MODES.map(x => hljs.inherit(x,161 {162 end: regex.concat(x.end, /[uismxfU]{0,7}/),163 contains: [ escapeSigilEnd(x.end) ]164 })165 )166 }167 ]168 };169 170 const STRING = {171 className: 'string',172 contains: [173 hljs.BACKSLASH_ESCAPE,174 SUBST175 ],176 variants: [177 {178 begin: /"""/,179 end: /"""/180 },181 {182 begin: /'''/,183 end: /'''/184 },185 {186 begin: /~S"""/,187 end: /"""/,188 contains: [] // override default189 },190 {191 begin: /~S"/,192 end: /"/,193 contains: [] // override default194 },195 {196 begin: /~S'''/,197 end: /'''/,198 contains: [] // override default199 },200 {201 begin: /~S'/,202 end: /'/,203 contains: [] // override default204 },205 {206 begin: /'/,207 end: /'/208 },209 {210 begin: /"/,211 end: /"/212 }213 ]214 };215 const FUNCTION = {216 className: 'function',217 beginKeywords: 'def defp defmacro defmacrop',218 end: /\B\b/, // the mode is ended by the title219 contains: [220 hljs.inherit(hljs.TITLE_MODE, {221 begin: ELIXIR_IDENT_RE,222 endsParent: true223 })224 ]225 };226 const CLASS = hljs.inherit(FUNCTION, {227 className: 'class',228 beginKeywords: 'defimpl defmodule defprotocol defrecord',229 end: /\bdo\b|$|;/230 });231 const ELIXIR_DEFAULT_CONTAINS = [232 STRING,233 REGEX_SIGIL,234 UPCASE_SIGIL,235 LOWERCASE_SIGIL,236 hljs.HASH_COMMENT_MODE,237 CLASS,238 FUNCTION,239 { begin: '::' },240 {241 className: 'symbol',242 begin: ':(?![\\s:])',243 contains: [244 STRING,245 { begin: ELIXIR_METHOD_RE }246 ],247 relevance: 0248 },249 {250 className: 'symbol',251 begin: ELIXIR_IDENT_RE + ':(?!:)',252 relevance: 0253 },254 { // Usage of a module, struct, etc.255 className: 'title.class',256 begin: /(\b[A-Z][a-zA-Z0-9_]+)/,257 relevance: 0258 },259 NUMBER,260 {261 className: 'variable',262 begin: '(\\$\\W)|((\\$|@@?)(\\w+))'263 }264 // -> has been removed, capnproto always uses this grammar construct265 ];266 SUBST.contains = ELIXIR_DEFAULT_CONTAINS;267 268 return {269 name: 'Elixir',270 aliases: [271 'ex',272 'exs'273 ],274 keywords: KWS,275 contains: ELIXIR_DEFAULT_CONTAINS276 };277}278 279export { elixir as default };280 