// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
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
})(function(CodeMirror) {
CodeMirror.defineMode("dylan", function(_config) {
// Words that introduce unnamed definitions like "define interface"
unnamedDefinition: ["interface"],
// Words that introduce simple named definitions like "define library"
namedDefinition: ["module", "library", "macro",
"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",
// 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
separator: ["finally", "exception", "cleanup", "else",
// 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["typeParameterizedDefinition"]
.concat(words["otherDefinition"]);
words["parameterizedDefinition"] =
words["typeParameterizedDefinition"]
.concat(words["otherParameterizedDefinition"]);
words["simpleDefinition"] =
words["constantSimpleDefinition"]
.concat(words["variableSimpleDefinition"])
.concat(words["otherSimpleDefinition"]);
.concat(words["separator"])
var symbolPattern = "[-_a-zA-Z?!*@<>$%]+";
var symbol = new RegExp("^" + symbolPattern);
// Symbols with special syntax
symbolKeyword: symbolPattern + ":",
symbolClass: "<" + symbolPattern + ">",
symbolGlobal: "\\*" + symbolPattern + "\\*",
symbolConstant: "\\$" + symbolPattern
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?!*@<>$%]+/];
styles["keyword"] = "keyword";
styles["definition"] = "def";
styles["simpleDefinition"] = "def";
styles["signalingCalls"] = "builtin";
// protected words lookup table
].forEach(function(type) {
words[type].forEach(function(word) {
styleLookup[word] = styles[type];
function chain(stream, state, f) {
function tokenBase(stream, state) {
if (ch == "'" || ch == '"') {
return chain(stream, state, tokenString(ch, "string"));
return chain(stream, state, tokenComment);
} else if (stream.eat("/")) {
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+/)) {
// Symbol with string syntax
return chain(stream, state, tokenString('"', "string"));
stream.eatWhile(/[\da-f]/i);
stream.eatWhile(/[0-7]/);
// Token concatenation in macros
else if ((ch == '[') || (ch == '(')) {
} else if (stream.match(/f|t|all-keys|include|key|next|rest/i)) {
stream.eatWhile(/[-a-zA-Z]/);
} else if ("[](){}".indexOf(ch) != -1) {
} else if (".,".indexOf(ch) != -1) {
} else if (stream.match("end")) {
for (var name in patterns) {
if (patterns.hasOwnProperty(name)) {
var pattern = patterns[name];
if ((pattern instanceof Array && pattern.some(function(p) {
})) || stream.match(pattern))
return patternStyles[name];
if (/[+\-*\/^=<>&|]/.test(ch)) {
if (stream.match("define")) {
stream.eatWhile(/[\w\-]/);
if (wordLookup[stream.current()]) {
return styleLookup[stream.current()];
} else if (stream.current().match(symbol)) {
function tokenComment(stream, state) {
var maybeEnd = false, maybeNested = false, nestedCount = 0, ch;
while ((ch = stream.next())) {
if (ch == "/" && maybeEnd) {
state.tokenize = tokenBase;
} else if (ch == "*" && maybeNested) {
maybeNested = (ch == "/");
function tokenString(quote, style) {
return function(stream, state) {
var escaped = false, next, end = false;
while ((next = stream.next()) != null) {
if (next == quote && !escaped) {
escaped = !escaped && next == "\\";
state.tokenize = tokenBase;
token: function(stream, state) {
var style = state.tokenize(stream, state);
CodeMirror.defineMIME("text/x-dylan", "dylan");