erlang.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  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',
  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 = {
  26. begin: 'fun\\s+' + BASIC_ATOM_RE + '/\\d+'
  27. };
  28. const FUNCTION_CALL = {
  29. begin: FUNCTION_NAME_RE + '\\(',
  30. end: '\\)',
  31. returnBegin: true,
  32. relevance: 0,
  33. contains: [
  34. {
  35. begin: FUNCTION_NAME_RE,
  36. relevance: 0
  37. },
  38. {
  39. begin: '\\(',
  40. end: '\\)',
  41. endsWithParent: true,
  42. returnEnd: true,
  43. relevance: 0
  44. // "contains" defined later
  45. }
  46. ]
  47. };
  48. const TUPLE = {
  49. begin: /\{/,
  50. end: /\}/,
  51. relevance: 0
  52. // "contains" defined later
  53. };
  54. const VAR1 = {
  55. begin: '\\b_([A-Z][A-Za-z0-9_]*)?',
  56. relevance: 0
  57. };
  58. const VAR2 = {
  59. begin: '[A-Z][a-zA-Z0-9_]*',
  60. relevance: 0
  61. };
  62. const RECORD_ACCESS = {
  63. begin: '#' + hljs.UNDERSCORE_IDENT_RE,
  64. relevance: 0,
  65. returnBegin: true,
  66. contains: [
  67. {
  68. begin: '#' + hljs.UNDERSCORE_IDENT_RE,
  69. relevance: 0
  70. },
  71. {
  72. begin: /\{/,
  73. end: /\}/,
  74. relevance: 0
  75. // "contains" defined later
  76. }
  77. ]
  78. };
  79. const BLOCK_STATEMENTS = {
  80. beginKeywords: 'fun receive if try case',
  81. end: 'end',
  82. keywords: ERLANG_RESERVED
  83. };
  84. BLOCK_STATEMENTS.contains = [
  85. COMMENT,
  86. NAMED_FUN,
  87. hljs.inherit(hljs.APOS_STRING_MODE, {
  88. className: ''
  89. }),
  90. BLOCK_STATEMENTS,
  91. FUNCTION_CALL,
  92. hljs.QUOTE_STRING_MODE,
  93. NUMBER,
  94. TUPLE,
  95. VAR1,
  96. VAR2,
  97. RECORD_ACCESS
  98. ];
  99. const BASIC_MODES = [
  100. COMMENT,
  101. NAMED_FUN,
  102. BLOCK_STATEMENTS,
  103. FUNCTION_CALL,
  104. hljs.QUOTE_STRING_MODE,
  105. NUMBER,
  106. TUPLE,
  107. VAR1,
  108. VAR2,
  109. RECORD_ACCESS
  110. ];
  111. FUNCTION_CALL.contains[1].contains = BASIC_MODES;
  112. TUPLE.contains = BASIC_MODES;
  113. RECORD_ACCESS.contains[1].contains = BASIC_MODES;
  114. const DIRECTIVES = [
  115. "-module",
  116. "-record",
  117. "-undef",
  118. "-export",
  119. "-ifdef",
  120. "-ifndef",
  121. "-author",
  122. "-copyright",
  123. "-doc",
  124. "-vsn",
  125. "-import",
  126. "-include",
  127. "-include_lib",
  128. "-compile",
  129. "-define",
  130. "-else",
  131. "-endif",
  132. "-file",
  133. "-behaviour",
  134. "-behavior",
  135. "-spec"
  136. ];
  137. const PARAMS = {
  138. className: 'params',
  139. begin: '\\(',
  140. end: '\\)',
  141. contains: BASIC_MODES
  142. };
  143. return {
  144. name: 'Erlang',
  145. aliases: ['erl'],
  146. keywords: ERLANG_RESERVED,
  147. illegal: '(</|\\*=|\\+=|-=|/\\*|\\*/|\\(\\*|\\*\\))',
  148. contains: [
  149. {
  150. className: 'function',
  151. begin: '^' + BASIC_ATOM_RE + '\\s*\\(',
  152. end: '->',
  153. returnBegin: true,
  154. illegal: '\\(|#|//|/\\*|\\\\|:|;',
  155. contains: [
  156. PARAMS,
  157. hljs.inherit(hljs.TITLE_MODE, {
  158. begin: BASIC_ATOM_RE
  159. })
  160. ],
  161. starts: {
  162. end: ';|\\.',
  163. keywords: ERLANG_RESERVED,
  164. contains: BASIC_MODES
  165. }
  166. },
  167. COMMENT,
  168. {
  169. begin: '^-',
  170. end: '\\.',
  171. relevance: 0,
  172. excludeEnd: true,
  173. returnBegin: true,
  174. keywords: {
  175. $pattern: '-' + hljs.IDENT_RE,
  176. keyword: DIRECTIVES.map(x => `${x}|1.5`).join(" ")
  177. },
  178. contains: [PARAMS]
  179. },
  180. NUMBER,
  181. hljs.QUOTE_STRING_MODE,
  182. RECORD_ACCESS,
  183. VAR1,
  184. VAR2,
  185. TUPLE,
  186. {
  187. begin: /\.$/
  188. } // relevance booster
  189. ]
  190. };
  191. }
  192. module.exports = erlang;