forked from codewars/codemirror-agda
-
Notifications
You must be signed in to change notification settings - Fork 0
/
agda-mode.js
88 lines (76 loc) · 2.92 KB
/
agda-mode.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import CodeMirror from "codemirror";
// Requires addon/mode/simple.js
const floatRegex = /-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?(?=[.;{}()@"\s]|$)/u;
const integerRegex = /-?(?:0|[1-9]\d*|0x[0-9A-Fa-f]+)(?=[.;{}()@"\s]|$)/u;
const keywordsRegex = new RegExp(
"(?:[_=|→:?\\\\λ∀]|->|\\.{2,3}|abstract|codata|coinductive|constructor|" +
"data|do|eta-equality|field|forall|hiding|import|in|inductive|" +
"infix|infixl|infixr|instance|let|macro|module|mutual|no-eta-equality|" +
"open|overlap|pattern|postulate|primitive|private|public|quote|" +
"quoteContext|quoteGoal|quoteTerm|record|renaming|rewrite|" +
"syntax|tactic|unquote|unquoteDecl|unquoteDef|using|where|with|" +
'Set(?:\\d+|[₀₁₂₃₄₅₆₇₈₉]+)?)(?=[.;{}()@"\\s]|$)',
"u"
);
const escapeDec = "0|[1-9]\\d*";
const escapeHex = "x(?:0|[1-9A-Fa-f][0-9A-Fa-f]*)";
const escapeCode =
"[abtnvf&\\\\'\"]|NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|" +
"SO|SI|DLE|DC[1-4]|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS|US|SP|DEL";
const escapeChar = new RegExp(
"\\\\(?:" + escapeDec + "|" + escapeHex + "|" + escapeCode + ")",
"u"
);
const startState = [
// comments, pragmas, holes
{ regex: /\{-#.*?#-\}/u, token: "meta" },
{ regex: /\{-/u, token: "comment", push: "comment" },
{ regex: /\{!/u, token: "keyword", push: "hole" },
{ regex: /--.*/u, token: "comment" },
// literals
{ regex: floatRegex, token: "number" },
{ regex: integerRegex, token: "integer" },
{ regex: /'/u, token: "string", push: "charLit" },
{ regex: /"/u, token: "string", push: "strLit" },
// keywords & qualified names
{ regex: keywordsRegex, token: "keyword" },
{ regex: /[^\s.;{}()@"]+\./u, token: "qualifier" },
{ regex: /[^\s.;{}()@"]+/u, token: null },
{ regex: /./u, token: null },
];
const commentState = [
{ regex: /\{-/u, token: "comment", push: "comment" },
{ regex: /-\}/u, token: "comment", pop: true },
{ regex: /./u, token: "comment" },
];
const holeState = [
{ regex: /\{!/u, token: "keyword", push: "hole" },
{ regex: /!\}/u, token: "keyword", pop: true },
{ regex: /./u, token: "comment" },
];
const charLitState = [
{ regex: /'/u, token: "string error", pop: true },
{ regex: /[^'\\]/u, token: "string", next: "charLitEnd" },
{ regex: escapeChar, token: "string", next: "charLitEnd" },
{ regex: /./u, token: "string error" },
];
const charLitEndState = [
{ regex: /'/u, token: "string", pop: true },
{ regex: /./u, token: "string error" },
{ regex: /[^]/u, token: "string error", pop: true },
];
const stringState = [
{ regex: /"/u, token: "string", pop: true },
{ regex: /[^"\\]/u, token: "string" },
{ regex: escapeChar, token: "string" },
{ regex: /./u, token: "string error" },
];
CodeMirror.defineSimpleMode("agda", {
start: startState,
comment: commentState,
hole: holeState,
charLit: charLitState,
charLitEnd: charLitEndState,
strLit: stringState,
});
CodeMirror.defineMIME("text/x-agda", "agda");