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 | return {
|
---|
79 | name: 'Ada',
|
---|
80 | case_insensitive: true,
|
---|
81 | keywords: {
|
---|
82 | keyword:
|
---|
83 | 'abort else new return abs elsif not reverse abstract end ' +
|
---|
84 | 'accept entry select access exception of separate aliased exit or some ' +
|
---|
85 | 'all others subtype and for out synchronized array function overriding ' +
|
---|
86 | 'at tagged generic package task begin goto pragma terminate ' +
|
---|
87 | 'body private then if procedure type case in protected constant interface ' +
|
---|
88 | 'is raise use declare range delay limited record when delta loop rem while ' +
|
---|
89 | 'digits renames with do mod requeue xor',
|
---|
90 | literal:
|
---|
91 | 'True False'
|
---|
92 | },
|
---|
93 | contains: [
|
---|
94 | COMMENTS,
|
---|
95 | // strings "foobar"
|
---|
96 | {
|
---|
97 | className: 'string',
|
---|
98 | begin: /"/,
|
---|
99 | end: /"/,
|
---|
100 | contains: [{
|
---|
101 | begin: /""/,
|
---|
102 | relevance: 0
|
---|
103 | }]
|
---|
104 | },
|
---|
105 | // characters ''
|
---|
106 | {
|
---|
107 | // character literals always contain one char
|
---|
108 | className: 'string',
|
---|
109 | begin: /'.'/
|
---|
110 | },
|
---|
111 | {
|
---|
112 | // number literals
|
---|
113 | className: 'number',
|
---|
114 | begin: NUMBER_RE,
|
---|
115 | relevance: 0
|
---|
116 | },
|
---|
117 | {
|
---|
118 | // Attributes
|
---|
119 | className: 'symbol',
|
---|
120 | begin: "'" + ID_REGEX
|
---|
121 | },
|
---|
122 | {
|
---|
123 | // package definition, maybe inside generic
|
---|
124 | className: 'title',
|
---|
125 | begin: '(\\bwith\\s+)?(\\bprivate\\s+)?\\bpackage\\s+(\\bbody\\s+)?',
|
---|
126 | end: '(is|$)',
|
---|
127 | keywords: 'package body',
|
---|
128 | excludeBegin: true,
|
---|
129 | excludeEnd: true,
|
---|
130 | illegal: BAD_CHARS
|
---|
131 | },
|
---|
132 | {
|
---|
133 | // function/procedure declaration/definition
|
---|
134 | // maybe inside generic
|
---|
135 | begin: '(\\b(with|overriding)\\s+)?\\b(function|procedure)\\s+',
|
---|
136 | end: '(\\bis|\\bwith|\\brenames|\\)\\s*;)',
|
---|
137 | keywords: 'overriding function procedure with is renames return',
|
---|
138 | // we need to re-match the 'function' keyword, so that
|
---|
139 | // the title mode below matches only exactly once
|
---|
140 | returnBegin: true,
|
---|
141 | contains:
|
---|
142 | [
|
---|
143 | COMMENTS,
|
---|
144 | {
|
---|
145 | // name of the function/procedure
|
---|
146 | className: 'title',
|
---|
147 | begin: '(\\bwith\\s+)?\\b(function|procedure)\\s+',
|
---|
148 | end: '(\\(|\\s+|$)',
|
---|
149 | excludeBegin: true,
|
---|
150 | excludeEnd: true,
|
---|
151 | illegal: BAD_CHARS
|
---|
152 | },
|
---|
153 | // 'self'
|
---|
154 | // // parameter types
|
---|
155 | VAR_DECLS,
|
---|
156 | {
|
---|
157 | // return type
|
---|
158 | className: 'type',
|
---|
159 | begin: '\\breturn\\s+',
|
---|
160 | end: '(\\s+|;|$)',
|
---|
161 | keywords: 'return',
|
---|
162 | excludeBegin: true,
|
---|
163 | excludeEnd: true,
|
---|
164 | // we are done with functions
|
---|
165 | endsParent: true,
|
---|
166 | illegal: BAD_CHARS
|
---|
167 |
|
---|
168 | }
|
---|
169 | ]
|
---|
170 | },
|
---|
171 | {
|
---|
172 | // new type declarations
|
---|
173 | // maybe inside generic
|
---|
174 | className: 'type',
|
---|
175 | begin: '\\b(sub)?type\\s+',
|
---|
176 | end: '\\s+',
|
---|
177 | keywords: 'type',
|
---|
178 | excludeBegin: true,
|
---|
179 | illegal: BAD_CHARS
|
---|
180 | },
|
---|
181 |
|
---|
182 | // see comment above the definition
|
---|
183 | VAR_DECLS
|
---|
184 |
|
---|
185 | // no markup
|
---|
186 | // relevance boosters for small snippets
|
---|
187 | // {begin: '\\s*=>\\s*'},
|
---|
188 | // {begin: '\\s*:=\\s*'},
|
---|
189 | // {begin: '\\s+:=\\s+'},
|
---|
190 | ]
|
---|
191 | };
|
---|
192 | }
|
---|
193 |
|
---|
194 | module.exports = ada;
|
---|