aboutsummaryrefslogtreecommitdiff
path: root/imports/codemirror/mode/erlang
diff options
context:
space:
mode:
Diffstat (limited to 'imports/codemirror/mode/erlang')
-rw-r--r--imports/codemirror/mode/erlang/erlang.js251
-rw-r--r--imports/codemirror/mode/erlang/index.html61
2 files changed, 312 insertions, 0 deletions
diff --git a/imports/codemirror/mode/erlang/erlang.js b/imports/codemirror/mode/erlang/erlang.js
new file mode 100644
index 00000000..5c094f8e
--- /dev/null
+++ b/imports/codemirror/mode/erlang/erlang.js
@@ -0,0 +1,251 @@
1// erlang -> CodeMirror tag
2//
3// atom -> atom
4// attribute -> attribute
5// builtin -> builtin
6// comment -> comment
7// error -> error
8// fun -> meta
9// function -> tag
10// guard -> property
11// keyword -> keyword
12// macro -> variable-2
13// number -> number
14// operator -> operator
15// record -> bracket
16// string -> string
17// type -> def
18// variable -> variable
19
20CodeMirror.defineMIME("text/x-erlang", "erlang");
21
22CodeMirror.defineMode("erlang", function(cmCfg, modeCfg) {
23
24 var typeWords = [
25 "-type", "-spec", "-export_type", "-opaque"];
26
27 var keywordWords = [
28 "after","begin","catch","case","cond","end","fun","if",
29 "let","of","query","receive","try","when"];
30
31 var operatorWords = [
32 "and","andalso","band","bnot","bor","bsl","bsr","bxor",
33 "div","not","or","orelse","rem","xor"];
34
35 var operatorSymbols = [
36 "+","-","*","/",">",">=","<","=<","=:=","==","=/=","/=","||","<-"];
37
38 var guardWords = [
39 "is_atom","is_binary","is_bitstring","is_boolean","is_float",
40 "is_function","is_integer","is_list","is_number","is_pid",
41 "is_port","is_record","is_reference","is_tuple",
42 "atom","binary","bitstring","boolean","function","integer","list",
43 "number","pid","port","record","reference","tuple"];
44
45 var bifWords = [
46 "abs","adler32","adler32_combine","alive","apply","atom_to_binary",
47 "atom_to_list","binary_to_atom","binary_to_existing_atom",
48 "binary_to_list","binary_to_term","bit_size","bitstring_to_list",
49 "byte_size","check_process_code","contact_binary","crc32",
50 "crc32_combine","date","decode_packet","delete_module",
51 "disconnect_node","element","erase","exit","float","float_to_list",
52 "garbage_collect","get","get_keys","group_leader","halt","hd",
53 "integer_to_list","internal_bif","iolist_size","iolist_to_binary",
54 "is_alive","is_atom","is_binary","is_bitstring","is_boolean",
55 "is_float","is_function","is_integer","is_list","is_number","is_pid",
56 "is_port","is_process_alive","is_record","is_reference","is_tuple",
57 "length","link","list_to_atom","list_to_binary","list_to_bitstring",
58 "list_to_existing_atom","list_to_float","list_to_integer",
59 "list_to_pid","list_to_tuple","load_module","make_ref","module_loaded",
60 "monitor_node","node","node_link","node_unlink","nodes","notalive",
61 "now","open_port","pid_to_list","port_close","port_command",
62 "port_connect","port_control","pre_loaded","process_flag",
63 "process_info","processes","purge_module","put","register",
64 "registered","round","self","setelement","size","spawn","spawn_link",
65 "spawn_monitor","spawn_opt","split_binary","statistics",
66 "term_to_binary","time","throw","tl","trunc","tuple_size",
67 "tuple_to_list","unlink","unregister","whereis"];
68
69 function isMember(element,list) {
70 return (-1 < list.indexOf(element));
71 }
72
73 function isPrev(stream,string) {
74 var start = stream.start;
75 var len = string.length;
76 if (len <= start) {
77 var word = stream.string.slice(start-len,start);
78 return word == string;
79 }else{
80 return false;
81 }
82 }
83
84 var smallRE = /[a-z_]/;
85 var largeRE = /[A-Z_]/;
86 var digitRE = /[0-9]/;
87 var octitRE = /[0-7]/;
88 var idRE = /[a-z_A-Z0-9]/;
89
90 function tokenize(stream, state) {
91 if (stream.eatSpace()) {
92 return null;
93 }
94
95 // attributes and type specs
96 if (stream.sol() && stream.peek() == '-') {
97 stream.next();
98 if (stream.eat(smallRE) && stream.eatWhile(idRE)) {
99 if (stream.peek() == "(") {
100 return "attribute";
101 }else if (isMember(stream.current(),typeWords)) {
102 return "def";
103 }else{
104 return null;
105 }
106 }
107 stream.backUp(1);
108 }
109
110 var ch = stream.next();
111
112 // comment
113 if (ch == '%') {
114 stream.skipToEnd();
115 return "comment";
116 }
117
118 // macro
119 if (ch == '?') {
120 stream.eatWhile(idRE);
121 return "variable-2";
122 }
123
124 // record
125 if ( ch == "#") {
126 stream.eatWhile(idRE);
127 return "bracket";
128 }
129
130 // char
131 if ( ch == "$") {
132 if (stream.next() == "\\") {
133 if (!stream.eatWhile(octitRE)) {
134 stream.next();
135 }
136 }
137 return "string";
138 }
139
140 // quoted atom
141 if (ch == '\'') {
142 return singleQuote(stream);
143 }
144
145 // string
146 if (ch == '"') {
147 return doubleQuote(stream);
148 }
149
150 // variable
151 if (largeRE.test(ch)) {
152 stream.eatWhile(idRE);
153 return "variable";
154 }
155
156 // atom/keyword/BIF/function
157 if (smallRE.test(ch)) {
158 stream.eatWhile(idRE);
159
160 if (stream.peek() == "/") {
161 stream.next();
162 if (stream.eatWhile(digitRE)) {
163 return "meta"; // f/0 style fun
164 }else{
165 stream.backUp(1);
166 return "atom";
167 }
168 }
169
170 var w = stream.current();
171
172 if (isMember(w,keywordWords)) {
173 return "keyword"; // keyword
174 }
175 if (stream.peek() == "(") {
176 if (isMember(w,bifWords) &&
177 (!isPrev(stream,":") || isPrev(stream,"erlang:"))) {
178 return "builtin"; // BIF
179 }else{
180 return "tag"; // function
181 }
182 }
183 if (isMember(w,guardWords)) {
184 return "property"; // guard
185 }
186 if (isMember(w,operatorWords)) {
187 return "operator"; // operator
188 }
189
190
191 if (stream.peek() == ":") {
192 if (w == "erlang") { // f:now() is highlighted incorrectly
193 return "builtin";
194 } else {
195 return "tag"; // function application
196 }
197 }
198
199 return "atom";
200 }
201
202 // number
203 if (digitRE.test(ch)) {
204 stream.eatWhile(digitRE);
205 if (stream.eat('#')) {
206 stream.eatWhile(digitRE); // 16#10 style integer
207 } else {
208 if (stream.eat('.')) { // float
209 stream.eatWhile(digitRE);
210 }
211 if (stream.eat(/[eE]/)) {
212 stream.eat(/[-+]/); // float with exponent
213 stream.eatWhile(digitRE);
214 }
215 }
216 return "number"; // normal integer
217 }
218
219 return null;
220 }
221
222 function doubleQuote(stream) {
223 return Quote(stream, '"', '\\', "string");
224 }
225
226 function singleQuote(stream) {
227 return Quote(stream,'\'','\\',"atom");
228 }
229
230 function Quote(stream,quoteChar,escapeChar,tag) {
231 while (!stream.eol()) {
232 var ch = stream.next();
233 if (ch == quoteChar) {
234 return tag;
235 }else if (ch == escapeChar) {
236 stream.next();