Mercurial
comparison .cms/lib/codemirror/mode/dylan/dylan.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 function forEach(arr, f) { | |
15 for (var i = 0; i < arr.length; i++) f(arr[i], i) | |
16 } | |
17 function some(arr, f) { | |
18 for (var i = 0; i < arr.length; i++) if (f(arr[i], i)) return true | |
19 return false | |
20 } | |
21 | |
22 CodeMirror.defineMode("dylan", function(_config) { | |
23 // Words | |
24 var words = { | |
25 // Words that introduce unnamed definitions like "define interface" | |
26 unnamedDefinition: ["interface"], | |
27 | |
28 // Words that introduce simple named definitions like "define library" | |
29 namedDefinition: ["module", "library", "macro", | |
30 "C-struct", "C-union", | |
31 "C-function", "C-callable-wrapper" | |
32 ], | |
33 | |
34 // Words that introduce type definitions like "define class". | |
35 // These are also parameterized like "define method" and are | |
36 // appended to otherParameterizedDefinitionWords | |
37 typeParameterizedDefinition: ["class", "C-subtype", "C-mapped-subtype"], | |
38 | |
39 // Words that introduce trickier definitions like "define method". | |
40 // These require special definitions to be added to startExpressions | |
41 otherParameterizedDefinition: ["method", "function", | |
42 "C-variable", "C-address" | |
43 ], | |
44 | |
45 // Words that introduce module constant definitions. | |
46 // These must also be simple definitions and are | |
47 // appended to otherSimpleDefinitionWords | |
48 constantSimpleDefinition: ["constant"], | |
49 | |
50 // Words that introduce module variable definitions. | |
51 // These must also be simple definitions and are | |
52 // appended to otherSimpleDefinitionWords | |
53 variableSimpleDefinition: ["variable"], | |
54 | |
55 // Other words that introduce simple definitions | |
56 // (without implicit bodies). | |
57 otherSimpleDefinition: ["generic", "domain", | |
58 "C-pointer-type", | |
59 "table" | |
60 ], | |
61 | |
62 // Words that begin statements with implicit bodies. | |
63 statement: ["if", "block", "begin", "method", "case", | |
64 "for", "select", "when", "unless", "until", | |
65 "while", "iterate", "profiling", "dynamic-bind" | |
66 ], | |
67 | |
68 // Patterns that act as separators in compound statements. | |
69 // This may include any general pattern that must be indented | |
70 // specially. | |
71 separator: ["finally", "exception", "cleanup", "else", | |
72 "elseif", "afterwards" | |
73 ], | |
74 | |
75 // Keywords that do not require special indentation handling, | |
76 // but which should be highlighted | |
77 other: ["above", "below", "by", "from", "handler", "in", | |
78 "instance", "let", "local", "otherwise", "slot", | |
79 "subclass", "then", "to", "keyed-by", "virtual" | |
80 ], | |
81 | |
82 // Condition signaling function calls | |
83 signalingCalls: ["signal", "error", "cerror", | |
84 "break", "check-type", "abort" | |
85 ] | |
86 }; | |
87 | |
88 words["otherDefinition"] = | |
89 words["unnamedDefinition"] | |
90 .concat(words["namedDefinition"]) | |
91 .concat(words["otherParameterizedDefinition"]); | |
92 | |
93 words["definition"] = | |
94 words["typeParameterizedDefinition"] | |
95 .concat(words["otherDefinition"]); | |
96 | |
97 words["parameterizedDefinition"] = | |
98 words["typeParameterizedDefinition"] | |
99 .concat(words["otherParameterizedDefinition"]); | |
100 | |
101 words["simpleDefinition"] = | |
102 words["constantSimpleDefinition"] | |
103 .concat(words["variableSimpleDefinition"]) | |
104 .concat(words["otherSimpleDefinition"]); | |
105 | |
106 words["keyword"] = | |
107 words["statement"] | |
108 .concat(words["separator"]) | |
109 .concat(words["other"]); | |
110 | |
111 // Patterns | |
112 var symbolPattern = "[-_a-zA-Z?!*@<>$%]+"; | |
113 var symbol = new RegExp("^" + symbolPattern); | |
114 var patterns = { | |
115 // Symbols with special syntax | |
116 symbolKeyword: symbolPattern + ":", | |
117 symbolClass: "<" + symbolPattern + ">", | |
118 symbolGlobal: "\\*" + symbolPattern + "\\*", | |
119 symbolConstant: "\\$" + symbolPattern | |
120 }; | |
121 var patternStyles = { | |
122 symbolKeyword: "atom", | |
123 symbolClass: "tag", | |
124 symbolGlobal: "variable-2", | |
125 symbolConstant: "variable-3" | |
126 }; | |
127 | |
128 // Compile all patterns to regular expressions | |
129 for (var patternName in patterns) | |
130 if (patterns.hasOwnProperty(patternName)) | |
131 patterns[patternName] = new RegExp("^" + patterns[patternName]); | |
132 | |
133 // Names beginning "with-" and "without-" are commonly | |
134 // used as statement macro | |
135 patterns["keyword"] = [/^with(?:out)?-[-_a-zA-Z?!*@<>$%]+/]; | |
136 | |
137 var styles = {}; | |
138 styles["keyword"] = "keyword"; | |
139 styles["definition"] = "def"; | |
140 styles["simpleDefinition"] = "def"; | |
141 styles["signalingCalls"] = "builtin"; | |
142 | |
143 // protected words lookup table | |
144 var wordLookup = {}; | |
145 var styleLookup = {}; | |
146 | |
147 forEach([ | |
148 "keyword", | |
149 "definition", | |
150 "simpleDefinition", | |
151 "signalingCalls" | |
152 ], function(type) { | |
153 forEach(words[type], function(word) { | |
154 wordLookup[word] = type; | |
155 styleLookup[word] = styles[type]; | |
156 }); | |
157 }); | |
158 | |
159 | |
160 function chain(stream, state, f) { | |
161 state.tokenize = f; | |
162 return f(stream, state); | |
163 } | |
164 | |
165 function tokenBase(stream, state) { | |
166 // String | |
167 var ch = stream.peek(); | |
168 if (ch == "'" || ch == '"') { | |
169 stream.next(); | |
170 return chain(stream, state, tokenString(ch, "string")); | |
171 } | |
172 // Comment | |
173 else if (ch == "/") { | |
174 stream.next(); | |
175 if (stream.eat("*")) { | |
176 return chain(stream, state, tokenComment); | |
177 } else if (stream.eat("/")) { | |
178 stream.skipToEnd(); | |
179 return "comment"; | |
180 } | |
181 stream.backUp(1); | |
182 } | |
183 // Decimal | |
184 else if (/[+\-\d\.]/.test(ch)) { | |
185 if (stream.match(/^[+-]?[0-9]*\.[0-9]*([esdx][+-]?[0-9]+)?/i) || | |
186 stream.match(/^[+-]?[0-9]+([esdx][+-]?[0-9]+)/i) || | |
187 stream.match(/^[+-]?\d+/)) { | |
188 return "number"; | |
189 } | |
190 } | |
191 // Hash | |
192 else if (ch == "#") { | |
193 stream.next(); | |
194 // Symbol with string syntax | |
195 ch = stream.peek(); | |
196 if (ch == '"') { | |
197 stream.next(); | |
198 return chain(stream, state, tokenString('"', "string")); | |
199 } | |
200 // Binary number | |
201 else if (ch == "b") { | |
202 stream.next(); | |
203 stream.eatWhile(/[01]/); | |
204 return "number"; | |
205 } | |
206 // Hex number | |
207 else if (ch == "x") { | |
208 stream.next(); | |
209 stream.eatWhile(/[\da-f]/i); | |
210 return "number"; | |
211 } | |
212 // Octal number | |
213 else if (ch == "o") { | |
214 stream.next(); | |
215 stream.eatWhile(/[0-7]/); | |
216 return "number"; | |
217 } | |
218 // Token concatenation in macros | |
219 else if (ch == '#') { | |
220 stream.next(); | |
221 return "punctuation"; | |
222 } | |
223 // Sequence literals | |
224 else if ((ch == '[') || (ch == '(')) { | |
225 stream.next(); | |
226 return "bracket"; | |
227 // Hash symbol | |
228 } else if (stream.match(/f|t|all-keys|include|key|next|rest/i)) { | |
229 return "atom"; | |
230 } else { | |
231 stream.eatWhile(/[-a-zA-Z]/); | |
232 return "error"; | |
233 } | |
234 } else if (ch == "~") { | |
235 stream.next(); | |
236 ch = stream.peek(); | |
237 if (ch == "=") { | |
238 stream.next(); | |
239 ch = stream.peek(); | |
240 if (ch == "=") { | |
241 stream.next(); | |
242 return "operator"; | |
243 } | |
244 return "operator"; | |
245 } | |
246 return "operator"; | |
247 } else if (ch == ":") { | |
248 stream.next(); | |
249 ch = stream.peek(); | |
250 if (ch == "=") { | |
251 stream.next(); | |
252 return "operator"; | |
253 } else if (ch == ":") { | |
254 stream.next(); | |
255 return "punctuation"; | |
256 } | |
257 } else if ("[](){}".indexOf(ch) != -1) { | |
258 stream.next(); | |
259 return "bracket"; | |
260 } else if (".,".indexOf(ch) != -1) { | |
261 stream.next(); | |
262 return "punctuation"; | |
263 } else if (stream.match("end")) { | |
264 return "keyword"; | |
265 } | |
266 for (var name in patterns) { | |
267 if (patterns.hasOwnProperty(name)) { | |
268 var pattern = patterns[name]; | |
269 if ((pattern instanceof Array && some(pattern, function(p) { | |
270 return stream.match(p); | |
271 })) || stream.match(pattern)) | |
272 return patternStyles[name]; | |
273 } | |
274 } | |
275 if (/[+\-*\/^=<>&|]/.test(ch)) { | |
276 stream.next(); | |
277 return "operator"; | |
278 } | |
279 if (stream.match("define")) { | |
280 return "def"; | |
281 } else { | |
282 stream.eatWhile(/[\w\-]/); | |
283 // Keyword | |
284 if (wordLookup.hasOwnProperty(stream.current())) { | |
285 return styleLookup[stream.current()]; | |
286 } else if (stream.current().match(symbol)) { | |
287 return "variable"; | |
288 } else { | |
289 stream.next(); | |
290 return "variable-2"; | |
291 } | |
292 } | |
293 } | |
294 | |
295 function tokenComment(stream, state) { | |
296 var maybeEnd = false, maybeNested = false, nestedCount = 0, ch; | |
297 while ((ch = stream.next())) { | |
298 if (ch == "/" && maybeEnd) { | |
299 if (nestedCount > 0) { | |
300 nestedCount--; | |
301 } else { | |
302 state.tokenize = tokenBase; | |
303 break; | |
304 } | |
305 } else if (ch == "*" && maybeNested) { | |
306 nestedCount++; | |
307 } | |
308 maybeEnd = (ch == "*"); | |
309 maybeNested = (ch == "/"); | |
310 } | |
311 return "comment"; | |
312 } | |
313 | |
314 function tokenString(quote, style) { | |
315 return function(stream, state) { | |
316 var escaped = false, next, end = false; | |
317 while ((next = stream.next()) != null) { | |
318 if (next == quote && !escaped) { | |
319 end = true; | |
320 break; | |
321 } | |
322 escaped = !escaped && next == "\\"; | |
323 } | |
324 if (end || !escaped) { | |
325 state.tokenize = tokenBase; | |
326 } | |
327 return style; | |
328 }; | |
329 } | |
330 | |
331 // Interface | |
332 return { | |
333 startState: function() { | |
334 return { | |
335 tokenize: tokenBase, | |
336 currentIndent: 0 | |
337 }; | |
338 }, | |
339 token: function(stream, state) { | |
340 if (stream.eatSpace()) | |
341 return null; | |
342 var style = state.tokenize(stream, state); | |
343 return style; | |
344 }, | |
345 blockCommentStart: "/*", | |
346 blockCommentEnd: "*/" | |
347 }; | |
348 }); | |
349 | |
350 CodeMirror.defineMIME("text/x-dylan", "dylan"); | |
351 | |
352 }); |