ada.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. module.exports = // We try to support full Ada2012
  2. //
  3. // We highlight all appearances of types, keywords, literals (string, char, number, bool)
  4. // and titles (user defined function/procedure/package)
  5. // CSS classes are set accordingly
  6. //
  7. // Languages causing problems for language detection:
  8. // xml (broken by Foo : Bar type), elm (broken by Foo : Bar type), vbscript-html (broken by body keyword)
  9. // sql (ada default.txt has a lot of sql keywords)
  10. function(hljs) {
  11. // Regular expression for Ada numeric literals.
  12. // stolen form the VHDL highlighter
  13. // Decimal literal:
  14. var INTEGER_RE = '\\d(_|\\d)*';
  15. var EXPONENT_RE = '[eE][-+]?' + INTEGER_RE;
  16. var DECIMAL_LITERAL_RE = INTEGER_RE + '(\\.' + INTEGER_RE + ')?' + '(' + EXPONENT_RE + ')?';
  17. // Based literal:
  18. var BASED_INTEGER_RE = '\\w+';
  19. var BASED_LITERAL_RE = INTEGER_RE + '#' + BASED_INTEGER_RE + '(\\.' + BASED_INTEGER_RE + ')?' + '#' + '(' + EXPONENT_RE + ')?';
  20. var NUMBER_RE = '\\b(' + BASED_LITERAL_RE + '|' + DECIMAL_LITERAL_RE + ')';
  21. // Identifier regex
  22. var ID_REGEX = '[A-Za-z](_?[A-Za-z0-9.])*';
  23. // bad chars, only allowed in literals
  24. var BAD_CHARS = '[]{}%#\'\"'
  25. // Ada doesn't have block comments, only line comments
  26. var COMMENTS = hljs.COMMENT('--', '$');
  27. // variable declarations of the form
  28. // Foo : Bar := Baz;
  29. // where only Bar will be highlighted
  30. var VAR_DECLS = {
  31. // TODO: These spaces are not required by the Ada syntax
  32. // however, I have yet to see handwritten Ada code where
  33. // someone does not put spaces around :
  34. begin: '\\s+:\\s+', end: '\\s*(:=|;|\\)|=>|$)',
  35. // endsWithParent: true,
  36. // returnBegin: true,
  37. illegal: BAD_CHARS,
  38. contains: [
  39. {
  40. // workaround to avoid highlighting
  41. // named loops and declare blocks
  42. beginKeywords: 'loop for declare others',
  43. endsParent: true,
  44. },
  45. {
  46. // properly highlight all modifiers
  47. className: 'keyword',
  48. beginKeywords: 'not null constant access function procedure in out aliased exception'
  49. },
  50. {
  51. className: 'type',
  52. begin: ID_REGEX,
  53. endsParent: true,
  54. relevance: 0,
  55. }
  56. ]
  57. };
  58. return {
  59. case_insensitive: true,
  60. keywords: {
  61. keyword:
  62. 'abort else new return abs elsif not reverse abstract end ' +
  63. 'accept entry select access exception of separate aliased exit or some ' +
  64. 'all others subtype and for out synchronized array function overriding ' +
  65. 'at tagged generic package task begin goto pragma terminate ' +
  66. 'body private then if procedure type case in protected constant interface ' +
  67. 'is raise use declare range delay limited record when delta loop rem while ' +
  68. 'digits renames with do mod requeue xor',
  69. literal:
  70. 'True False',
  71. },
  72. contains: [
  73. COMMENTS,
  74. // strings "foobar"
  75. {
  76. className: 'string',
  77. begin: /"/, end: /"/,
  78. contains: [{begin: /""/, relevance: 0}]
  79. },
  80. // characters ''
  81. {
  82. // character literals always contain one char
  83. className: 'string',
  84. begin: /'.'/
  85. },
  86. {
  87. // number literals
  88. className: 'number',
  89. begin: NUMBER_RE,
  90. relevance: 0
  91. },
  92. {
  93. // Attributes
  94. className: 'symbol',
  95. begin: "'" + ID_REGEX,
  96. },
  97. {
  98. // package definition, maybe inside generic
  99. className: 'title',
  100. begin: '(\\bwith\\s+)?(\\bprivate\\s+)?\\bpackage\\s+(\\bbody\\s+)?', end: '(is|$)',
  101. keywords: 'package body',
  102. excludeBegin: true,
  103. excludeEnd: true,
  104. illegal: BAD_CHARS
  105. },
  106. {
  107. // function/procedure declaration/definition
  108. // maybe inside generic
  109. begin: '(\\b(with|overriding)\\s+)?\\b(function|procedure)\\s+', end: '(\\bis|\\bwith|\\brenames|\\)\\s*;)',
  110. keywords: 'overriding function procedure with is renames return',
  111. // we need to re-match the 'function' keyword, so that
  112. // the title mode below matches only exactly once
  113. returnBegin: true,
  114. contains:
  115. [
  116. COMMENTS,
  117. {
  118. // name of the function/procedure
  119. className: 'title',
  120. begin: '(\\bwith\\s+)?\\b(function|procedure)\\s+',
  121. end: '(\\(|\\s+|$)',
  122. excludeBegin: true,
  123. excludeEnd: true,
  124. illegal: BAD_CHARS
  125. },
  126. // 'self'
  127. // // parameter types
  128. VAR_DECLS,
  129. {
  130. // return type
  131. className: 'type',
  132. begin: '\\breturn\\s+', end: '(\\s+|;|$)',
  133. keywords: 'return',
  134. excludeBegin: true,
  135. excludeEnd: true,
  136. // we are done with functions
  137. endsParent: true,
  138. illegal: BAD_CHARS
  139. },
  140. ]
  141. },
  142. {
  143. // new type declarations
  144. // maybe inside generic
  145. className: 'type',
  146. begin: '\\b(sub)?type\\s+', end: '\\s+',
  147. keywords: 'type',
  148. excludeBegin: true,
  149. illegal: BAD_CHARS
  150. },
  151. // see comment above the definition
  152. VAR_DECLS,
  153. // no markup
  154. // relevance boosters for small snippets
  155. // {begin: '\\s*=>\\s*'},
  156. // {begin: '\\s*:=\\s*'},
  157. // {begin: '\\s+:=\\s+'},
  158. ]
  159. };
  160. };