1 | /*
|
2 | Language: Ada
|
3 | Author: Lars Schulna <kartoffelbrei.mit.muskatnuss@gmail.org>
|
4 | Description: Ada is a general-purpose programming language that has great support for saftey critical and real-time applications.
|
5 | It has been developed by the DoD and thus has been used in military and safety-critical applications (like civil aviation).
|
6 | The first version appeared in the 80s, but it's still actively developed today with
|
7 | the newest standard being Ada2012.
|
8 | */
|
9 |
|
10 | // We try to support full Ada2012
|
11 | //
|
12 | // We highlight all appearances of types, keywords, literals (string, char, number, bool)
|
13 | // and titles (user defined function/procedure/package)
|
14 | // CSS classes are set accordingly
|
15 | //
|
16 | // Languages causing problems for language detection:
|
17 | // xml (broken by Foo : Bar type), elm (broken by Foo : Bar type), vbscript-html (broken by body keyword)
|
18 | // sql (ada default.txt has a lot of sql keywords)
|
19 |
|
20 | /** @type LanguageFn */
|
21 | function ada(hljs) {
|
22 | // Regular expression for Ada numeric literals.
|
23 | // stolen form the VHDL highlighter
|
24 |
|
25 | // Decimal literal:
|
26 | const INTEGER_RE = '\\d(_|\\d)*';
|
27 | const EXPONENT_RE = '[eE][-+]?' + INTEGER_RE;
|
28 | const DECIMAL_LITERAL_RE = INTEGER_RE + '(\\.' + INTEGER_RE + ')?' + '(' + EXPONENT_RE + ')?';
|
29 |
|
30 | // Based literal:
|
31 | const BASED_INTEGER_RE = '\\w+';
|
32 | const BASED_LITERAL_RE = INTEGER_RE + '#' + BASED_INTEGER_RE + '(\\.' + BASED_INTEGER_RE + ')?' + '#' + '(' + EXPONENT_RE + ')?';
|
33 |
|
34 | const NUMBER_RE = '\\b(' + BASED_LITERAL_RE + '|' + DECIMAL_LITERAL_RE + ')';
|
35 |
|
36 | // Identifier regex
|
37 | const ID_REGEX = '[A-Za-z](_?[A-Za-z0-9.])*';
|
38 |
|
39 | // bad chars, only allowed in literals
|
40 | const BAD_CHARS = `[]\\{\\}%#'"`;
|
41 |
|
42 | // Ada doesn't have block comments, only line comments
|
43 | const COMMENTS = hljs.COMMENT('--', '$');
|
44 |
|
45 | // variable declarations of the form
|
46 | // Foo : Bar := Baz;
|
47 | // where only Bar will be highlighted
|
48 | const VAR_DECLS = {
|
49 | // TODO: These spaces are not required by the Ada syntax
|
50 | // however, I have yet to see handwritten Ada code where
|
51 | // someone does not put spaces around :
|
52 | begin: '\\s+:\\s+',
|
53 | end: '\\s*(:=|;|\\)|=>|$)',
|
54 | // endsWithParent: true,
|
55 | // returnBegin: true,
|
56 | illegal: BAD_CHARS,
|
57 | contains: [
|
58 | {
|
59 | // workaround to avoid highlighting
|
60 | // named loops and declare blocks
|
61 | beginKeywords: 'loop for declare others',
|
62 | endsParent: true
|
63 | },
|
64 | {
|
65 | // properly highlight all modifiers
|
66 | className: 'keyword',
|
67 | beginKeywords: 'not null constant access function procedure in out aliased exception'
|
68 | },
|
69 | {
|
70 | className: 'type',
|
71 | begin: ID_REGEX,
|
72 | endsParent: true,
|
73 | relevance: 0
|
74 | }
|
75 | ]
|
76 | };
|
77 |
|
78 | const KEYWORDS = [
|
79 | "abort",
|
80 | "else",
|
81 | "new",
|
82 | "return",
|
83 | "abs",
|
84 | "elsif",
|
85 | "not",
|
86 | "reverse",
|
87 | "abstract",
|
88 | "end",
|
89 | "accept",
|
90 | "entry",
|
91 | "select",
|
92 | "access",
|
93 | "exception",
|
94 | "of",
|
95 | "separate",
|
96 | "aliased",
|
97 | "exit",
|
98 | "or",
|
99 | "some",
|
100 | "all",
|
101 | "others",
|
102 | "subtype",
|
103 | "and",
|
104 | "for",
|
105 | "out",
|
106 | "synchronized",
|
107 | "array",
|
108 | "function",
|
109 | "overriding",
|
110 | "at",
|
111 | "tagged",
|
112 | "generic",
|
113 | "package",
|
114 | "task",
|
115 | "begin",
|
116 | "goto",
|
117 | "pragma",
|
118 | "terminate",
|
119 | "body",
|
120 | "private",
|
121 | "then",
|
122 | "if",
|
123 | "procedure",
|
124 | "type",
|
125 | "case",
|
126 | "in",
|
127 | "protected",
|
128 | "constant",
|
129 | "interface",
|
130 | "is",
|
131 | "raise",
|
132 | "use",
|
133 | "declare",
|
134 | "range",
|
135 | "delay",
|
136 | "limited",
|
137 | "record",
|
138 | "when",
|
139 | "delta",
|
140 | "loop",
|
141 | "rem",
|
142 | "while",
|
143 | "digits",
|
144 | "renames",
|
145 | "with",
|
146 | "do",
|
147 | "mod",
|
148 | "requeue",
|
149 | "xor"
|
150 | ];
|
151 |
|
152 | return {
|
153 | name: 'Ada',
|
154 | case_insensitive: true,
|
155 | keywords: {
|
156 | keyword: KEYWORDS,
|
157 | literal: [
|
158 | "True",
|
159 | "False"
|
160 | ]
|
161 | },
|
162 | contains: [
|
163 | COMMENTS,
|
164 | // strings "foobar"
|
165 | {
|
166 | className: 'string',
|
167 | begin: /"/,
|
168 | end: /"/,
|
169 | contains: [{
|
170 | begin: /""/,
|
171 | relevance: 0
|
172 | }]
|
173 | },
|
174 | // characters ''
|
175 | {
|
176 | // character literals always contain one char
|
177 | className: 'string',
|
178 | begin: /'.'/
|
179 | },
|
180 | {
|
181 | // number literals
|
182 | className: 'number',
|
183 | begin: NUMBER_RE,
|
184 | relevance: 0
|
185 | },
|
186 | {
|
187 | // Attributes
|
188 | className: 'symbol',
|
189 | begin: "'" + ID_REGEX
|
190 | },
|
191 | {
|
192 | // package definition, maybe inside generic
|
193 | className: 'title',
|
194 | begin: '(\\bwith\\s+)?(\\bprivate\\s+)?\\bpackage\\s+(\\bbody\\s+)?',
|
195 | end: '(is|$)',
|
196 | keywords: 'package body',
|
197 | excludeBegin: true,
|
198 | excludeEnd: true,
|
199 | illegal: BAD_CHARS
|
200 | },
|
201 | {
|
202 | // function/procedure declaration/definition
|
203 | // maybe inside generic
|
204 | begin: '(\\b(with|overriding)\\s+)?\\b(function|procedure)\\s+',
|
205 | end: '(\\bis|\\bwith|\\brenames|\\)\\s*;)',
|
206 | keywords: 'overriding function procedure with is renames return',
|
207 | // we need to re-match the 'function' keyword, so that
|
208 | // the title mode below matches only exactly once
|
209 | returnBegin: true,
|
210 | contains:
|
211 | [
|
212 | COMMENTS,
|
213 | {
|
214 | // name of the function/procedure
|
215 | className: 'title',
|
216 | begin: '(\\bwith\\s+)?\\b(function|procedure)\\s+',
|
217 | end: '(\\(|\\s+|$)',
|
218 | excludeBegin: true,
|
219 | excludeEnd: true,
|
220 | illegal: BAD_CHARS
|
221 | },
|
222 | // 'self'
|
223 | // // parameter types
|
224 | VAR_DECLS,
|
225 | {
|
226 | // return type
|
227 | className: 'type',
|
228 | begin: '\\breturn\\s+',
|
229 | end: '(\\s+|;|$)',
|
230 | keywords: 'return',
|
231 | excludeBegin: true,
|
232 | excludeEnd: true,
|
233 | // we are done with functions
|
234 | endsParent: true,
|
235 | illegal: BAD_CHARS
|
236 |
|
237 | }
|
238 | ]
|
239 | },
|
240 | {
|
241 | // new type declarations
|
242 | // maybe inside generic
|
243 | className: 'type',
|
244 | begin: '\\b(sub)?type\\s+',
|
245 | end: '\\s+',
|
246 | keywords: 'type',
|
247 | excludeBegin: true,
|
248 | illegal: BAD_CHARS
|
249 | },
|
250 |
|
251 | // see comment above the definition
|
252 | VAR_DECLS
|
253 |
|
254 | // no markup
|
255 | // relevance boosters for small snippets
|
256 | // {begin: '\\s*=>\\s*'},
|
257 | // {begin: '\\s*:=\\s*'},
|
258 | // {begin: '\\s+:=\\s+'},
|
259 | ]
|
260 | };
|
261 | }
|
262 |
|
263 | export { ada as default };
|