Skip to content

Commit 3f752d0

Browse files
waywardmonkeysmarijnh
authored andcommitted
[dylan mode] Improve and add tests
* Support nested block comments. * Improve number and operator parsing. * Improve string parsing. * Style brackets correctly. * Improve #-words.
1 parent 8b9066a commit 3f752d0

File tree

3 files changed

+159
-16
lines changed

3 files changed

+159
-16
lines changed

mode/dylan/dylan.js

Lines changed: 69 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -169,15 +169,16 @@ CodeMirror.defineMode("dylan", function(_config) {
169169
} else if (stream.eat("/")) {
170170
stream.skipToEnd();
171171
return "comment";
172-
} else {
173-
stream.skipTo(" ");
174-
return "operator";
175172
}
173+
stream.backUp(1);
176174
}
177175
// Decimal
178-
else if (/\d/.test(ch)) {
179-
stream.match(/^\d*(?:\.\d*)?(?:e[+\-]?\d+)?/);
180-
return "number";
176+
else if (/[+\-\d\.]/.test(ch)) {
177+
if (stream.match(/^[+-]?[0-9]*\.[0-9]*([esdx][+-]?[0-9]+)?/i) ||
178+
stream.match(/^[+-]?[0-9]+([esdx][+-]?[0-9]+)/i) ||
179+
stream.match(/^[+-]?\d+/)) {
180+
return "number";
181+
}
181182
}
182183
// Hash
183184
else if (ch == "#") {
@@ -186,7 +187,7 @@ CodeMirror.defineMode("dylan", function(_config) {
186187
ch = stream.peek();
187188
if (ch == '"') {
188189
stream.next();
189-
return chain(stream, state, tokenString('"', "string-2"));
190+
return chain(stream, state, tokenString('"', "string"));
190191
}
191192
// Binary number
192193
else if (ch == "b") {
@@ -206,11 +207,51 @@ CodeMirror.defineMode("dylan", function(_config) {
206207
stream.eatWhile(/[0-7]/);
207208
return "number";
208209
}
210+
// Token concatenation in macros
211+
else if (ch == '#') {
212+
stream.next();
213+
return "punctuation";
214+
}
215+
// Sequence literals
216+
else if ((ch == '[') || (ch == '(')) {
217+
stream.next();
218+
return "bracket";
209219
// Hash symbol
210-
else {
220+
} else if (stream.match(/f|t|all-keys|include|key|next|rest/i)) {
221+
return "atom";
222+
} else {
211223
stream.eatWhile(/[-a-zA-Z]/);
212-
return "keyword";
224+
return "error";
225+
}
226+
} else if (ch == "~") {
227+
stream.next();
228+
ch = stream.peek();
229+
if (ch == "=") {
230+
stream.next();
231+
ch = stream.peek();
232+
if (ch == "=") {
233+
stream.next();
234+
return "operator";
235+
}
236+
return "operator";
213237
}
238+
return "operator";
239+
} else if (ch == ":") {
240+
stream.next();
241+
ch = stream.peek();
242+
if (ch == "=") {
243+
stream.next();
244+
return "operator";
245+
} else if (ch == ":") {
246+
stream.next();
247+
return "punctuation";
248+
}
249+
} else if ("[](){}".indexOf(ch) != -1) {
250+
stream.next();
251+
return "bracket";
252+
} else if (".,".indexOf(ch) != -1) {
253+
stream.next();
254+
return "punctuation";
214255
} else if (stream.match("end")) {
215256
return "keyword";
216257
}
@@ -223,6 +264,10 @@ CodeMirror.defineMode("dylan", function(_config) {
223264
return patternStyles[name];
224265
}
225266
}
267+
if (/[+\-*\/^=<>&|]/.test(ch)) {
268+
stream.next();
269+
return "operator";
270+
}
226271
if (stream.match("define")) {
227272
return "def";
228273
} else {
@@ -240,29 +285,37 @@ CodeMirror.defineMode("dylan", function(_config) {
240285
}
241286

242287
function tokenComment(stream, state) {
243-
var maybeEnd = false,
244-
ch;
288+
var maybeEnd = false, maybeNested = false, nestedCount = 0, ch;
245289
while ((ch = stream.next())) {
246290
if (ch == "/" && maybeEnd) {
247-
state.tokenize = tokenBase;
248-
break;
291+
if (nestedCount > 0) {
292+
nestedCount--;
293+
} else {
294+
state.tokenize = tokenBase;
295+
break;
296+
}
297+
} else if (ch == "*" && maybeNested) {
298+
nestedCount++;
249299
}
250300
maybeEnd = (ch == "*");
301+
maybeNested = (ch == "/");
251302
}
252303
return "comment";
253304
}
254305

255306
function tokenString(quote, style) {
256307
return function(stream, state) {
257-
var next, end = false;
308+
var escaped = false, next, end = false;
258309
while ((next = stream.next()) != null) {
259-
if (next == quote) {
310+
if (next == quote && !escaped) {
260311
end = true;
261312
break;
262313
}
314+
escaped = !escaped && next == "\\";
263315
}
264-
if (end)
316+
if (end || !escaped) {
265317
state.tokenize = tokenBase;
318+
}
266319
return style;
267320
};
268321
}

mode/dylan/test.js

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// CodeMirror, copyright (c) by Marijn Haverbeke and others
2+
// Distributed under an MIT license: http://codemirror.net/LICENSE
3+
4+
(function() {
5+
var mode = CodeMirror.getMode({indentUnit: 2}, "dylan");
6+
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
7+
8+
MT('comments',
9+
'[comment // This is a line comment]',
10+
'[comment /* This is a block comment */]',
11+
'[comment /* This is a multi]',
12+
'[comment line comment]',
13+
'[comment */]',
14+
'[comment /* And this is a /*]',
15+
'[comment /* nested */ comment */]');
16+
17+
MT('unary_operators',
18+
'[operator -][variable a]',
19+
'[operator -] [variable a]',
20+
'[operator ~][variable a]',
21+
'[operator ~] [variable a]');
22+
23+
MT('binary_operators',
24+
'[variable a] [operator +] [variable b]',
25+
'[variable a] [operator -] [variable b]',
26+
'[variable a] [operator *] [variable b]',
27+
'[variable a] [operator /] [variable b]',
28+
'[variable a] [operator ^] [variable b]',
29+
'[variable a] [operator =] [variable b]',
30+
'[variable a] [operator ==] [variable b]',
31+
'[variable a] [operator ~=] [variable b]',
32+
'[variable a] [operator ~==] [variable b]',
33+
'[variable a] [operator <] [variable b]',
34+
'[variable a] [operator <=] [variable b]',
35+
'[variable a] [operator >] [variable b]',
36+
'[variable a] [operator >=] [variable b]',
37+
'[variable a] [operator &] [variable b]',
38+
'[variable a] [operator |] [variable b]',
39+
'[variable a] [operator :=] [variable b]');
40+
41+
MT('integers',
42+
'[number 1]',
43+
'[number 123]',
44+
'[number -123]',
45+
'[number +456]',
46+
'[number #b010]',
47+
'[number #o073]',
48+
'[number #xabcDEF123]');
49+
50+
MT('floats',
51+
'[number .3]',
52+
'[number -1.]',
53+
'[number -2.335]',
54+
'[number +3.78d1]',
55+
'[number 3.78s-1]',
56+
'[number -3.32e+5]');
57+
58+
MT('characters_and_strings',
59+
"[string 'a']",
60+
"[string '\\\\'']",
61+
'[string ""]',
62+
'[string "a"]',
63+
'[string "abc def"]',
64+
'[string "More escaped characters: \\\\\\\\ \\\\a \\\\b \\\\e \\\\f \\\\n \\\\r \\\\t \\\\0 ..."]');
65+
66+
MT('brackets',
67+
'[bracket #[[]]]',
68+
'[bracket #()]',
69+
'[bracket #(][number 1][bracket )]',
70+
'[bracket [[][number 1][punctuation ,] [number 3][bracket ]]]',
71+
'[bracket ()]',
72+
'[bracket {}]',
73+
'[keyword if] [bracket (][variable foo][bracket )]',
74+
'[bracket (][number 1][bracket )]',
75+
'[bracket [[][number 1][bracket ]]]');
76+
77+
MT('hash_words',
78+
'[punctuation ##]',
79+
'[atom #f]', '[atom #F]',
80+
'[atom #t]', '[atom #T]',
81+
'[atom #all-keys]',
82+
'[atom #include]',
83+
'[atom #key]',
84+
'[atom #next]',
85+
'[atom #rest]',
86+
'[string #"foo"]',
87+
'[error #invalid]');
88+
})();

test/index.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
<script src="../keymap/vim.js"></script>
4141
<script src="../mode/rust/rust.js"></script>
4242
<script src="../mode/mscgen/mscgen.js"></script>
43+
<script src="../mode/dylan/dylan.js"></script>
4344

4445
<style type="text/css">
4546
.ok {color: #090;}
@@ -123,6 +124,7 @@ <h2>Test Suite</h2>
123124
<script src="../mode/mscgen/mscgen_test.js"></script>
124125
<script src="../mode/mscgen/xu_test.js"></script>
125126
<script src="../mode/mscgen/msgenny_test.js"></script>
127+
<script src="../mode/dylan/test.js"></script>
126128
<script src="../addon/mode/multiplex_test.js"></script>
127129
<script src="emacs_test.js"></script>
128130
<script src="sql-hint-test.js"></script>

0 commit comments

Comments
 (0)