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