comparison .cms/lib/codemirror/mode/julia/julia.js @ 0:78edf6b517a0 draft

24.10
author Coffee CMS <info@coffee-cms.ru>
date Fri, 11 Oct 2024 22:40:23 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:78edf6b517a0
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: https://codemirror.net/5/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 CodeMirror.defineMode("julia", function(config, parserConf) {
15 function wordRegexp(words, end, pre) {
16 if (typeof pre === "undefined") { pre = ""; }
17 if (typeof end === "undefined") { end = "\\b"; }
18 return new RegExp("^" + pre + "((" + words.join(")|(") + "))" + end);
19 }
20
21 var octChar = "\\\\[0-7]{1,3}";
22 var hexChar = "\\\\x[A-Fa-f0-9]{1,2}";
23 var sChar = "\\\\[abefnrtv0%?'\"\\\\]";
24 var uChar = "([^\\u0027\\u005C\\uD800-\\uDFFF]|[\\uD800-\\uDFFF][\\uDC00-\\uDFFF])";
25
26 var asciiOperatorsList = [
27 "[<>]:", "[<>=]=", "<<=?", ">>>?=?", "=>", "--?>", "<--[->]?", "\\/\\/",
28 "\\.{2,3}", "[\\.\\\\%*+\\-<>!\\/^|&]=?", "\\?", "\\$", "~", ":"
29 ];
30 var operators = parserConf.operators || wordRegexp([
31 "[<>]:", "[<>=]=", "[!=]==", "<<=?", ">>>?=?", "=>?", "--?>", "<--[->]?", "\\/\\/",
32 "[\\\\%*+\\-<>!\\/^|&\\u00F7\\u22BB]=?", "\\?", "\\$", "~", ":",
33 "\\u00D7", "\\u2208", "\\u2209", "\\u220B", "\\u220C", "\\u2218",
34 "\\u221A", "\\u221B", "\\u2229", "\\u222A", "\\u2260", "\\u2264",
35 "\\u2265", "\\u2286", "\\u2288", "\\u228A", "\\u22C5",
36 "\\b(in|isa)\\b(?!\.?\\()"
37 ], "");
38 var delimiters = parserConf.delimiters || /^[;,()[\]{}]/;
39 var identifiers = parserConf.identifiers ||
40 /^[_A-Za-z\u00A1-\u2217\u2219-\uFFFF][\w\u00A1-\u2217\u2219-\uFFFF]*!*/;
41
42 var chars = wordRegexp([octChar, hexChar, sChar, uChar], "'");
43
44 var openersList = ["begin", "function", "type", "struct", "immutable", "let",
45 "macro", "for", "while", "quote", "if", "else", "elseif", "try",
46 "finally", "catch", "do"];
47
48 var closersList = ["end", "else", "elseif", "catch", "finally"];
49
50 var keywordsList = ["if", "else", "elseif", "while", "for", "begin", "let",
51 "end", "do", "try", "catch", "finally", "return", "break", "continue",
52 "global", "local", "const", "export", "import", "importall", "using",
53 "function", "where", "macro", "module", "baremodule", "struct", "type",
54 "mutable", "immutable", "quote", "typealias", "abstract", "primitive",
55 "bitstype"];
56
57 var builtinsList = ["true", "false", "nothing", "NaN", "Inf"];
58
59 CodeMirror.registerHelper("hintWords", "julia", keywordsList.concat(builtinsList));
60
61 var openers = wordRegexp(openersList);
62 var closers = wordRegexp(closersList);
63 var keywords = wordRegexp(keywordsList);
64 var builtins = wordRegexp(builtinsList);
65
66 var macro = /^@[_A-Za-z\u00A1-\uFFFF][\w\u00A1-\uFFFF]*!*/;
67 var symbol = /^:[_A-Za-z\u00A1-\uFFFF][\w\u00A1-\uFFFF]*!*/;
68 var stringPrefixes = /^(`|([_A-Za-z\u00A1-\uFFFF]*"("")?))/;
69
70 var macroOperators = wordRegexp(asciiOperatorsList, "", "@");
71 var symbolOperators = wordRegexp(asciiOperatorsList, "", ":");
72
73 function inArray(state) {
74 return (state.nestedArrays > 0);
75 }
76
77 function inGenerator(state) {
78 return (state.nestedGenerators > 0);
79 }
80
81 function currentScope(state, n) {
82 if (typeof(n) === "undefined") { n = 0; }
83 if (state.scopes.length <= n) {
84 return null;
85 }
86 return state.scopes[state.scopes.length - (n + 1)];
87 }
88
89 // tokenizers
90 function tokenBase(stream, state) {
91 // Handle multiline comments
92 if (stream.match('#=', false)) {
93 state.tokenize = tokenComment;
94 return state.tokenize(stream, state);
95 }
96
97 // Handle scope changes
98 var leavingExpr = state.leavingExpr;
99 if (stream.sol()) {
100 leavingExpr = false;
101 }
102 state.leavingExpr = false;
103
104 if (leavingExpr) {
105 if (stream.match(/^'+/)) {
106 return "operator";
107 }
108 }
109
110 if (stream.match(/\.{4,}/)) {
111 return "error";
112 } else if (stream.match(/\.{1,3}/)) {
113 return "operator";
114 }
115
116 if (stream.eatSpace()) {
117 return null;
118 }
119
120 var ch = stream.peek();
121
122 // Handle single line comments
123 if (ch === '#') {
124 stream.skipToEnd();
125 return "comment";
126 }
127
128 if (ch === '[') {
129 state.scopes.push('[');
130 state.nestedArrays++;
131 }
132
133 if (ch === '(') {
134 state.scopes.push('(');
135 state.nestedGenerators++;
136 }
137
138 if (inArray(state) && ch === ']') {
139 while (state.scopes.length && currentScope(state) !== "[") { state.scopes.pop(); }
140 state.scopes.pop();
141 state.nestedArrays--;
142 state.leavingExpr = true;
143 }
144
145 if (inGenerator(state) && ch === ')') {
146 while (state.scopes.length && currentScope(state) !== "(") { state.scopes.pop(); }
147 state.scopes.pop();
148 state.nestedGenerators--;
149 state.leavingExpr = true;
150 }
151
152 if (inArray(state)) {
153 if (state.lastToken == "end" && stream.match(':')) {
154 return "operator";
155 }
156 if (stream.match('end')) {
157 return "number";
158 }
159 }
160
161 var match;
162 if (match = stream.match(openers, false)) {
163 state.scopes.push(match[0]);
164 }
165
166 if (stream.match(closers, false)) {
167 state.scopes.pop();
168 }
169
170 // Handle type annotations
171 if (stream.match(/^::(?![:\$])/)) {
172 state.tokenize = tokenAnnotation;
173 return state.tokenize(stream, state);
174 }
175
176 // Handle symbols
177 if (!leavingExpr && (stream.match(symbol) || stream.match(symbolOperators))) {
178 return "builtin";
179 }
180
181 // Handle parametric types
182 //if (stream.match(/^{[^}]*}(?=\()/)) {
183 // return "builtin";
184 //}
185
186 // Handle operators and Delimiters
187 if (stream.match(operators)) {
188 return "operator";
189 }
190
191 // Handle Number Literals
192 if (stream.match(/^\.?\d/, false)) {
193 var imMatcher = RegExp(/^im\b/);
194 var numberLiteral = false;
195 if (stream.match(/^0x\.[0-9a-f_]+p[\+\-]?[_\d]+/i)) { numberLiteral = true; }
196 // Integers
197 if (stream.match(/^0x[0-9a-f_]+/i)) { numberLiteral = true; } // Hex
198 if (stream.match(/^0b[01_]+/i)) { numberLiteral = true; } // Binary
199 if (stream.match(/^0o[0-7_]+/i)) { numberLiteral = true; } // Octal
200 // Floats
201 if (stream.match(/^(?:(?:\d[_\d]*)?\.(?!\.)(?:\d[_\d]*)?|\d[_\d]*\.(?!\.)(?:\d[_\d]*))?([Eef][\+\-]?[_\d]+)?/i)) { numberLiteral = true; }
202 if (stream.match(/^\d[_\d]*(e[\+\-]?\d+)?/i)) { numberLiteral = true; } // Decimal
203 if (numberLiteral) {
204 // Integer literals may be "long"
205 stream.match(imMatcher);
206 state.leavingExpr = true;
207 return "number";
208 }
209 }
210
211 // Handle Chars
212 if (stream.match('\'')) {
213 state.tokenize = tokenChar;
214 return state.tokenize(stream, state);
215 }
216
217 // Handle Strings
218 if (stream.match(stringPrefixes)) {
219 state.tokenize = tokenStringFactory(stream.current());
220 return state.tokenize(stream, state);
221 }
222
223 if (stream.match(macro) || stream.match(macroOperators)) {
224 return "meta";
225 }
226
227 if (stream.match(delimiters)) {
228 return null;
229 }
230
231 if (stream.match(keywords)) {
232 return "keyword";
233 }
234
235 if (stream.match(builtins)) {
236 return "builtin";
237 }
238
239 var isDefinition = state.isDefinition || state.lastToken == "function" ||
240 state.lastToken == "macro" || state.lastToken == "type" ||
241 state.lastToken == "struct" || state.lastToken == "immutable";
242
243 if (stream.match(identifiers)) {
244 if (isDefinition) {
245 if (stream.peek() === '.') {
246 state.isDefinition = true;
247 return "variable";
248 }
249 state.isDefinition = false;
250 return "def";
251 }
252 state.leavingExpr = true;
253 return "variable";
254 }
255
256 // Handle non-detected items
257 stream.next();
258 return "error";
259 }
260
261 function tokenAnnotation(stream, state) {
262 stream.match(/.*?(?=[,;{}()=\s]|$)/);
263 if (stream.match('{')) {
264 state.nestedParameters++;
265 } else if (stream.match('}') && state.nestedParameters > 0) {
266 state.nestedParameters--;
267 }
268 if (state.nestedParameters > 0) {
269 stream.match(/.*?(?={|})/) || stream.next();
270 } else if (state.nestedParameters == 0) {
271 state.tokenize = tokenBase;
272 }
273 return "builtin";
274 }
275
276 function tokenComment(stream, state) {
277 if (stream.match('#=')) {
278 state.nestedComments++;
279 }
280 if (!stream.match(/.*?(?=(#=|=#))/)) {
281 stream.skipToEnd();
282 }
283 if (stream.match('=#')) {
284 state.nestedComments--;
285 if (state.nestedComments == 0)
286 state.tokenize = tokenBase;
287 }
288 return "comment";
289 }
290
291 function tokenChar(stream, state) {
292 var isChar = false, match;
293 if (stream.match(chars)) {
294 isChar = true;
295 } else if (match = stream.match(/\\u([a-f0-9]{1,4})(?=')/i)) {
296 var value = parseInt(match[1], 16);
297 if (value <= 55295 || value >= 57344) { // (U+0,U+D7FF), (U+E000,U+FFFF)
298 isChar = true;
299 stream.next();
300 }
301 } else if (match = stream.match(/\\U([A-Fa-f0-9]{5,8})(?=')/)) {
302 var value = parseInt(match[1], 16);
303 if (value <= 1114111) { // U+10FFFF
304 isChar = true;
305 stream.next();
306 }
307 }
308 if (isChar) {
309 state.leavingExpr = true;
310 state.tokenize = tokenBase;
311 return "string";
312 }
313 if (!stream.match(/^[^']+(?=')/)) { stream.skipToEnd(); }
314 if (stream.match('\'')) { state.tokenize = tokenBase; }
315 return "error";
316 }
317
318 function tokenStringFactory(delimiter) {
319 if (delimiter.substr(-3) === '"""') {
320 delimiter = '"""';
321 } else if (delimiter.substr(-1) === '"') {
322 delimiter = '"';
323 }
324 function tokenString(stream, state) {
325 if (stream.eat('\\')) {
326 stream.next();
327 } else if (stream.match(delimiter)) {
328 state.tokenize = tokenBase;
329 state.leavingExpr = true;
330 return "string";
331 } else {
332 stream.eat(/[`"]/);
333 }
334 stream.eatWhile(/[^\\`"]/);
335 return "string";
336 }
337 return tokenString;
338 }
339
340 var external = {
341 startState: function() {
342 return {
343 tokenize: tokenBase,
344 scopes: [],
345 lastToken: null,
346 leavingExpr: false,
347 isDefinition: false,
348 nestedArrays: 0,
349 nestedComments: 0,
350 nestedGenerators: 0,
351 nestedParameters: 0,
352 firstParenPos: -1
353 };
354 },
355
356 token: function(stream, state) {
357 var style = state.tokenize(stream, state);
358 var current = stream.current();
359
360 if (current && style) {
361 state.lastToken = current;
362 }
363
364 return style;
365 },
366
367 indent: function(state, textAfter) {
368 var delta = 0;
369 if ( textAfter === ']' || textAfter === ')' || /^end\b/.test(textAfter) ||
370 /^else/.test(textAfter) || /^catch\b/.test(textAfter) || /^elseif\b/.test(textAfter) ||
371 /^finally/.test(textAfter) ) {
372 delta = -1;
373 }
374 return (state.scopes.length + delta) * config.indentUnit;
375 },
376
377 electricInput: /\b(end|else|catch|finally)\b/,
378 blockCommentStart: "#=",
379 blockCommentEnd: "=#",
380 lineComment: "#",
381 closeBrackets: "()[]{}\"\"",
382 fold: "indent"
383 };
384 return external;
385 });
386
387
388 CodeMirror.defineMIME("text/x-julia", "julia");
389
390 });