File modules/editor/codemirror/mode/dylan/dylan.js

Last commit: Sun Dec 17 01:14:09 2017 +0100	Jan Dankert	Integration eines weiteren Code-Editors: Codemirror. Demnächst müssen wir hier mal aufräumen und andere Editoren rauswerfen.
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 // Distributed under an MIT license: http://codemirror.net/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 });
Download modules/editor/codemirror/mode/dylan/dylan.js
History Sun, 17 Dec 2017 01:14:09 +0100 Jan Dankert Integration eines weiteren Code-Editors: Codemirror. Demnächst müssen wir hier mal aufräumen und andere Editoren rauswerfen.