|
|
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/5/LICENSE
(function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror")); else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod); else // Plain browser env
mod(CodeMirror); })(function(CodeMirror) { "use strict";
function forEach(arr, f) { for (var i = 0; i < arr.length; i++) f(arr[i], i) } function some(arr, f) { for (var i = 0; i < arr.length; i++) if (f(arr[i], i)) return true return false }
CodeMirror.defineMode("dylan", function(_config) { // Words
var words = { // Words that introduce unnamed definitions like "define interface"
unnamedDefinition: ["interface"],
// Words that introduce simple named definitions like "define library"
namedDefinition: ["module", "library", "macro", "C-struct", "C-union", "C-function", "C-callable-wrapper" ],
// Words that introduce type definitions like "define class".
// These are also parameterized like "define method" and are
// appended to otherParameterizedDefinitionWords
typeParameterizedDefinition: ["class", "C-subtype", "C-mapped-subtype"],
// Words that introduce trickier definitions like "define method".
// These require special definitions to be added to startExpressions
otherParameterizedDefinition: ["method", "function", "C-variable", "C-address" ],
// Words that introduce module constant definitions.
// These must also be simple definitions and are
// appended to otherSimpleDefinitionWords
constantSimpleDefinition: ["constant"],
// Words that introduce module variable definitions.
// These must also be simple definitions and are
// appended to otherSimpleDefinitionWords
variableSimpleDefinition: ["variable"],
// Other words that introduce simple definitions
// (without implicit bodies).
otherSimpleDefinition: ["generic", "domain", "C-pointer-type", "table" ],
// Words that begin statements with implicit bodies.
statement: ["if", "block", "begin", "method", "case", "for", "select", "when", "unless", "until", "while", "iterate", "profiling", "dynamic-bind" ],
// Patterns that act as separators in compound statements.
// This may include any general pattern that must be indented
// specially.
separator: ["finally", "exception", "cleanup", "else", "elseif", "afterwards" ],
// Keywords that do not require special indentation handling,
// but which should be highlighted
other: ["above", "below", "by", "from", "handler", "in", "instance", "let", "local", "otherwise", "slot", "subclass", "then", "to", "keyed-by", "virtual" ],
// Condition signaling function calls
signalingCalls: ["signal", "error", "cerror", "break", "check-type", "abort" ] };
words["otherDefinition"] = words["unnamedDefinition"] .concat(words["namedDefinition"]) .concat(words["otherParameterizedDefinition"]);
words["definition"] = words["typeParameterizedDefinition"] .concat(words["otherDefinition"]);
words["parameterizedDefinition"] = words["typeParameterizedDefinition"] .concat(words["otherParameterizedDefinition"]);
words["simpleDefinition"] = words["constantSimpleDefinition"] .concat(words["variableSimpleDefinition"]) .concat(words["otherSimpleDefinition"]);
words["keyword"] = words["statement"] .concat(words["separator"]) .concat(words["other"]);
// Patterns
var symbolPattern = "[-_a-zA-Z?!*@<>$%]+"; var symbol = new RegExp("^" + symbolPattern); var patterns = { // Symbols with special syntax
symbolKeyword: symbolPattern + ":", symbolClass: "<" + symbolPattern + ">", symbolGlobal: "\\*" + symbolPattern + "\\*", symbolConstant: "\\$" + symbolPattern }; var patternStyles = { symbolKeyword: "atom", symbolClass: "tag", symbolGlobal: "variable-2", symbolConstant: "variable-3" };
// Compile all patterns to regular expressions
for (var patternName in patterns) if (patterns.hasOwnProperty(patternName)) patterns[patternName] = new RegExp("^" + patterns[patternName]);
// Names beginning "with-" and "without-" are commonly
// used as statement macro
patterns["keyword"] = [/^with(?:out)?-[-_a-zA-Z?!*@<>$%]+/];
var styles = {}; styles["keyword"] = "keyword"; styles["definition"] = "def"; styles["simpleDefinition"] = "def"; styles["signalingCalls"] = "builtin";
// protected words lookup table
var wordLookup = {}; var styleLookup = {};
forEach([ "keyword", "definition", "simpleDefinition", "signalingCalls" ], function(type) { forEach(words[type], function(word) { wordLookup[word] = type; styleLookup[word] = styles[type]; }); });
function chain(stream, state, f) { state.tokenize = f; return f(stream, state); }
function tokenBase(stream, state) { // String
var ch = stream.peek(); if (ch == "'" || ch == '"') { stream.next(); return chain(stream, state, tokenString(ch, "string")); } // Comment
else if (ch == "/") { stream.next(); if (stream.eat("*")) { return chain(stream, state, tokenComment); } else if (stream.eat("/")) { stream.skipToEnd(); return "comment"; } stream.backUp(1); } // Decimal
else if (/[+\-\d\.]/.test(ch)) { if (stream.match(/^[+-]?[0-9]*\.[0-9]*([esdx][+-]?[0-9]+)?/i) || stream.match(/^[+-]?[0-9]+([esdx][+-]?[0-9]+)/i) || stream.match(/^[+-]?\d+/)) { return "number"; } } // Hash
else if (ch == "#") { stream.next(); // Symbol with string syntax
ch = stream.peek(); if (ch == '"') { stream.next(); return chain(stream, state, tokenString('"', "string")); } // Binary number
else if (ch == "b") { stream.next(); stream.eatWhile(/[01]/); return "number"; } // Hex number
else if (ch == "x") { stream.next(); stream.eatWhile(/[\da-f]/i); return "number"; } // Octal number
else if (ch == "o") { stream.next(); stream.eatWhile(/[0-7]/); return "number"; } // Token concatenation in macros
else if (ch == '#') { stream.next(); return "punctuation"; } // Sequence literals
else if ((ch == '[') || (ch == '(')) { stream.next(); return "bracket"; // Hash symbol
} else if (stream.match(/f|t|all-keys|include|key|next|rest/i)) { return "atom"; } else { stream.eatWhile(/[-a-zA-Z]/); return "error"; } } else if (ch == "~") { stream.next(); ch = stream.peek(); if (ch == "=") { stream.next(); ch = stream.peek(); if (ch == "=") { stream.next(); return "operator"; } return "operator"; } return "operator"; } else if (ch == ":") { stream.next(); ch = stream.peek(); if (ch == "=") { stream.next(); return "operator"; } else if (ch == ":") { stream.next(); return "punctuation"; } } else if ("[](){}".indexOf(ch) != -1) { stream.next(); return "bracket"; } else if (".,".indexOf(ch) != -1) { stream.next(); return "punctuation"; } else if (stream.match("end")) { return "keyword"; } for (var name in patterns) { if (patterns.hasOwnProperty(name)) { var pattern = patterns[name]; if ((pattern instanceof Array && some(pattern, function(p) { return stream.match(p); })) || stream.match(pattern)) return patternStyles[name]; } } if (/[+\-*\/^=<>&|]/.test(ch)) { stream.next(); return "operator"; } if (stream.match("define")) { return "def"; } else { stream.eatWhile(/[\w\-]/); // Keyword
if (wordLookup.hasOwnProperty(stream.current())) { return styleLookup[stream.current()]; } else if (stream.current().match(symbol)) { return "variable"; } else { stream.next(); return "variable-2"; } } }
function tokenComment(stream, state) { var maybeEnd = false, maybeNested = false, nestedCount = 0, ch; while ((ch = stream.next())) { if (ch == "/" && maybeEnd) { if (nestedCount > 0) { nestedCount--; } else { state.tokenize = tokenBase; break; } } else if (ch == "*" && maybeNested) { nestedCount++; } maybeEnd = (ch == "*"); maybeNested = (ch == "/"); } return "comment"; }
function tokenString(quote, style) { return function(stream, state) { var escaped = false, next, end = false; while ((next = stream.next()) != null) { if (next == quote && !escaped) { end = true; break; } escaped = !escaped && next == "\\"; } if (end || !escaped) { state.tokenize = tokenBase; } return style; }; }
// Interface
return { startState: function() { return { tokenize: tokenBase, currentIndent: 0 }; }, token: function(stream, state) { if (stream.eatSpace()) return null; var style = state.tokenize(stream, state); return style; }, blockCommentStart: "/*", blockCommentEnd: "*/" }; });
CodeMirror.defineMIME("text/x-dylan", "dylan");
});
|