UNPKG

4.22 kBJavaScriptView Raw
1/*
2Language: Erlang
3Description: Erlang is a general-purpose functional language, with strict evaluation, single assignment, and dynamic typing.
4Author: Nikolay Zakharov <nikolay.desh@gmail.com>, Dmitry Kovega <arhibot@gmail.com>
5Website: https://www.erlang.org
6Category: functional
7*/
8
9/** @type LanguageFn */
10function erlang(hljs) {
11 const BASIC_ATOM_RE = '[a-z\'][a-zA-Z0-9_\']*';
12 const FUNCTION_NAME_RE = '(' + BASIC_ATOM_RE + ':' + BASIC_ATOM_RE + '|' + BASIC_ATOM_RE + ')';
13 const ERLANG_RESERVED = {
14 keyword:
15 'after and andalso|10 band begin bnot bor bsl bzr bxor case catch cond div end fun if '
16 + 'let not of orelse|10 query receive rem try when xor',
17 literal:
18 'false true'
19 };
20
21 const COMMENT = hljs.COMMENT('%', '$');
22 const NUMBER = {
23 className: 'number',
24 begin: '\\b(\\d+(_\\d+)*#[a-fA-F0-9]+(_[a-fA-F0-9]+)*|\\d+(_\\d+)*(\\.\\d+(_\\d+)*)?([eE][-+]?\\d+)?)',
25 relevance: 0
26 };
27 const NAMED_FUN = { begin: 'fun\\s+' + BASIC_ATOM_RE + '/\\d+' };
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
80 const BLOCK_STATEMENTS = {
81 beginKeywords: 'fun receive if try case',
82 end: 'end',
83 keywords: ERLANG_RESERVED
84 };
85 BLOCK_STATEMENTS.contains = [
86 COMMENT,
87 NAMED_FUN,
88 hljs.inherit(hljs.APOS_STRING_MODE, { className: '' }),
89 BLOCK_STATEMENTS,
90 FUNCTION_CALL,
91 hljs.QUOTE_STRING_MODE,
92 NUMBER,
93 TUPLE,
94 VAR1,
95 VAR2,
96 RECORD_ACCESS
97 ];
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
115 const DIRECTIVES = [
116 "-module",
117 "-record",
118 "-undef",
119 "-export",
120 "-ifdef",
121 "-ifndef",
122 "-author",
123 "-copyright",
124 "-doc",
125 "-vsn",
126 "-import",
127 "-include",
128 "-include_lib",
129 "-compile",
130 "-define",
131 "-else",
132 "-endif",
133 "-file",
134 "-behaviour",
135 "-behavior",
136 "-spec"
137 ];
138
139 const PARAMS = {
140 className: 'params',
141 begin: '\\(',
142 end: '\\)',
143 contains: BASIC_MODES
144 };
145 return {
146 name: 'Erlang',
147 aliases: [ 'erl' ],
148 keywords: ERLANG_RESERVED,
149 illegal: '(</|\\*=|\\+=|-=|/\\*|\\*/|\\(\\*|\\*\\))',
150 contains: [
151 {
152 className: 'function',
153 begin: '^' + BASIC_ATOM_RE + '\\s*\\(',
154 end: '->',
155 returnBegin: true,
156 illegal: '\\(|#|//|/\\*|\\\\|:|;',
157 contains: [
158 PARAMS,
159 hljs.inherit(hljs.TITLE_MODE, { begin: BASIC_ATOM_RE })
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 { begin: /\.$/ } // relevance booster
187 ]
188 };
189}
190
191module.exports = erlang;