erlang.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. Language: Erlang
  3. Description: Erlang is a general-purpose functional language, with strict evaluation, single assignment, and dynamic typing.
  4. Author: Nikolay Zakharov <nikolay.desh@gmail.com>, Dmitry Kovega <arhibot@gmail.com>
  5. Website: https://www.erlang.org
  6. Category: functional
  7. */
  8. /** @type LanguageFn */
  9. function erlang(hljs) {
  10. const BASIC_ATOM_RE = '[a-z\'][a-zA-Z0-9_\']*';
  11. const FUNCTION_NAME_RE = '(' + BASIC_ATOM_RE + ':' + BASIC_ATOM_RE + '|' + BASIC_ATOM_RE + ')';
  12. const ERLANG_RESERVED = {
  13. keyword:
  14. 'after and andalso|10 band begin bnot bor bsl bzr bxor case catch cond div end fun if '
  15. + 'let not of orelse|10 query receive rem try when xor maybe else',
  16. literal:
  17. 'false true'
  18. };
  19. const COMMENT = hljs.COMMENT('%', '$');
  20. const NUMBER = {
  21. className: 'number',
  22. begin: '\\b(\\d+(_\\d+)*#[a-fA-F0-9]+(_[a-fA-F0-9]+)*|\\d+(_\\d+)*(\\.\\d+(_\\d+)*)?([eE][-+]?\\d+)?)',
  23. relevance: 0
  24. };
  25. const NAMED_FUN = { begin: 'fun\\s+' + BASIC_ATOM_RE + '/\\d+' };
  26. const FUNCTION_CALL = {
  27. begin: FUNCTION_NAME_RE + '\\(',
  28. end: '\\)',
  29. returnBegin: true,
  30. relevance: 0,
  31. contains: [
  32. {
  33. begin: FUNCTION_NAME_RE,
  34. relevance: 0
  35. },
  36. {
  37. begin: '\\(',
  38. end: '\\)',
  39. endsWithParent: true,
  40. returnEnd: true,
  41. relevance: 0
  42. // "contains" defined later
  43. }
  44. ]
  45. };
  46. const TUPLE = {
  47. begin: /\{/,
  48. end: /\}/,
  49. relevance: 0
  50. // "contains" defined later
  51. };
  52. const VAR1 = {
  53. begin: '\\b_([A-Z][A-Za-z0-9_]*)?',
  54. relevance: 0
  55. };
  56. const VAR2 = {
  57. begin: '[A-Z][a-zA-Z0-9_]*',
  58. relevance: 0
  59. };
  60. const RECORD_ACCESS = {
  61. begin: '#' + hljs.UNDERSCORE_IDENT_RE,
  62. relevance: 0,
  63. returnBegin: true,
  64. contains: [
  65. {
  66. begin: '#' + hljs.UNDERSCORE_IDENT_RE,
  67. relevance: 0
  68. },
  69. {
  70. begin: /\{/,
  71. end: /\}/,
  72. relevance: 0
  73. // "contains" defined later
  74. }
  75. ]
  76. };
  77. const CHAR_LITERAL = {
  78. scope: 'string',
  79. match: /\$(\\([^0-9]|[0-9]{1,3}|)|.)/,
  80. };
  81. const TRIPLE_QUOTE = {
  82. scope: 'string',
  83. match: /"""("*)(?!")[\s\S]*?"""\1/,
  84. };
  85. const SIGIL = {
  86. scope: 'string',
  87. contains: [ hljs.BACKSLASH_ESCAPE ],
  88. variants: [
  89. {match: /~\w?"""("*)(?!")[\s\S]*?"""\1/},
  90. {begin: /~\w?\(/, end: /\)/},
  91. {begin: /~\w?\[/, end: /\]/},
  92. {begin: /~\w?{/, end: /}/},
  93. {begin: /~\w?</, end: />/},
  94. {begin: /~\w?\//, end: /\//},
  95. {begin: /~\w?\|/, end: /\|/},
  96. {begin: /~\w?'/, end: /'/},
  97. {begin: /~\w?"/, end: /"/},
  98. {begin: /~\w?`/, end: /`/},
  99. {begin: /~\w?#/, end: /#/},
  100. ],
  101. };
  102. const BLOCK_STATEMENTS = {
  103. beginKeywords: 'fun receive if try case maybe',
  104. end: 'end',
  105. keywords: ERLANG_RESERVED
  106. };
  107. BLOCK_STATEMENTS.contains = [
  108. COMMENT,
  109. NAMED_FUN,
  110. hljs.inherit(hljs.APOS_STRING_MODE, { className: '' }),
  111. BLOCK_STATEMENTS,
  112. FUNCTION_CALL,
  113. SIGIL,
  114. TRIPLE_QUOTE,
  115. hljs.QUOTE_STRING_MODE,
  116. NUMBER,
  117. TUPLE,
  118. VAR1,
  119. VAR2,
  120. RECORD_ACCESS,
  121. CHAR_LITERAL
  122. ];
  123. const BASIC_MODES = [
  124. COMMENT,
  125. NAMED_FUN,
  126. BLOCK_STATEMENTS,
  127. FUNCTION_CALL,
  128. SIGIL,
  129. TRIPLE_QUOTE,
  130. hljs.QUOTE_STRING_MODE,
  131. NUMBER,
  132. TUPLE,
  133. VAR1,
  134. VAR2,
  135. RECORD_ACCESS,
  136. CHAR_LITERAL
  137. ];
  138. FUNCTION_CALL.contains[1].contains = BASIC_MODES;
  139. TUPLE.contains = BASIC_MODES;
  140. RECORD_ACCESS.contains[1].contains = BASIC_MODES;
  141. const DIRECTIVES = [
  142. "-module",
  143. "-record",
  144. "-undef",
  145. "-export",
  146. "-ifdef",
  147. "-ifndef",
  148. "-author",
  149. "-copyright",
  150. "-doc",
  151. "-moduledoc",
  152. "-vsn",
  153. "-import",
  154. "-include",
  155. "-include_lib",
  156. "-compile",
  157. "-define",
  158. "-else",
  159. "-endif",
  160. "-file",
  161. "-behaviour",
  162. "-behavior",
  163. "-spec",
  164. "-on_load",
  165. "-nifs",
  166. ];
  167. const PARAMS = {
  168. className: 'params',
  169. begin: '\\(',
  170. end: '\\)',
  171. contains: BASIC_MODES
  172. };
  173. return {
  174. name: 'Erlang',
  175. aliases: [ 'erl' ],
  176. keywords: ERLANG_RESERVED,
  177. illegal: '(</|\\*=|\\+=|-=|/\\*|\\*/|\\(\\*|\\*\\))',
  178. contains: [
  179. {
  180. className: 'function',
  181. begin: '^' + BASIC_ATOM_RE + '\\s*\\(',
  182. end: '->',
  183. returnBegin: true,
  184. illegal: '\\(|#|//|/\\*|\\\\|:|;',
  185. contains: [
  186. PARAMS,
  187. hljs.inherit(hljs.TITLE_MODE, { begin: BASIC_ATOM_RE })
  188. ],
  189. starts: {
  190. end: ';|\\.',
  191. keywords: ERLANG_RESERVED,
  192. contains: BASIC_MODES
  193. }
  194. },
  195. COMMENT,
  196. {
  197. begin: '^-',
  198. end: '\\.',
  199. relevance: 0,
  200. excludeEnd: true,
  201. returnBegin: true,
  202. keywords: {
  203. $pattern: '-' + hljs.IDENT_RE,
  204. keyword: DIRECTIVES.map(x => `${x}|1.5`).join(" ")
  205. },
  206. contains: [
  207. PARAMS,
  208. SIGIL,
  209. TRIPLE_QUOTE,
  210. hljs.QUOTE_STRING_MODE
  211. ]
  212. },
  213. NUMBER,
  214. SIGIL,
  215. TRIPLE_QUOTE,
  216. hljs.QUOTE_STRING_MODE,
  217. RECORD_ACCESS,
  218. VAR1,
  219. VAR2,
  220. TUPLE,
  221. CHAR_LITERAL,
  222. { begin: /\.$/ } // relevance booster
  223. ]
  224. };
  225. }
  226. export { erlang as default };