all repos — NoPaste @ 3e3c433f026c49e04d0efa0f0f39fc688ed32bb1

Resurrected - The PussTheCat.org fork of NoPaste

scripts/CodeMirror/mode/dylan/dylan.js (view raw)

  1// CodeMirror, copyright (c) by Marijn Haverbeke and others
  2// Distributed under an MIT license: https://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
 14function forEach(arr, f) {
 15  for (var i = 0; i < arr.length; i++) f(arr[i], i)
 16}
 17function some(arr, f) {
 18  for (var i = 0; i < arr.length; i++) if (f(arr[i], i)) return true
 19  return false
 20}
 21
 22CodeMirror.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
350CodeMirror.defineMIME("text/x-dylan", "dylan");
351
352});