reasonml.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /*
  2. Language: ReasonML
  3. Description: Reason lets you write simple, fast and quality type safe code while leveraging both the JavaScript & OCaml ecosystems.
  4. Website: https://reasonml.github.io
  5. Author: Gidi Meir Morris <oss@gidi.io>
  6. Category: functional
  7. */
  8. function reasonml(hljs) {
  9. function orReValues(ops) {
  10. return ops
  11. .map(function(op) {
  12. return op
  13. .split('')
  14. .map(function(char) {
  15. return '\\' + char;
  16. })
  17. .join('');
  18. })
  19. .join('|');
  20. }
  21. const RE_IDENT = '~?[a-z$_][0-9a-zA-Z$_]*';
  22. const RE_MODULE_IDENT = '`?[A-Z$_][0-9a-zA-Z$_]*';
  23. const RE_PARAM_TYPEPARAM = '\'?[a-z$_][0-9a-z$_]*';
  24. const RE_PARAM_TYPE = '\\s*:\\s*[a-z$_][0-9a-z$_]*(\\(\\s*(' + RE_PARAM_TYPEPARAM + '\\s*(,' + RE_PARAM_TYPEPARAM + '\\s*)*)?\\))?';
  25. const RE_PARAM = RE_IDENT + '(' + RE_PARAM_TYPE + '){0,2}';
  26. const RE_OPERATOR = "(" + orReValues([
  27. '||',
  28. '++',
  29. '**',
  30. '+.',
  31. '*',
  32. '/',
  33. '*.',
  34. '/.',
  35. '...'
  36. ]) + "|\\|>|&&|==|===)";
  37. const RE_OPERATOR_SPACED = "\\s+" + RE_OPERATOR + "\\s+";
  38. const KEYWORDS = {
  39. keyword:
  40. 'and as asr assert begin class constraint do done downto else end exception external ' +
  41. 'for fun function functor if in include inherit initializer ' +
  42. 'land lazy let lor lsl lsr lxor match method mod module mutable new nonrec ' +
  43. 'object of open or private rec sig struct then to try type val virtual when while with',
  44. built_in:
  45. 'array bool bytes char exn|5 float int int32 int64 list lazy_t|5 nativeint|5 ref string unit ',
  46. literal:
  47. 'true false'
  48. };
  49. const RE_NUMBER = '\\b(0[xX][a-fA-F0-9_]+[Lln]?|' +
  50. '0[oO][0-7_]+[Lln]?|' +
  51. '0[bB][01_]+[Lln]?|' +
  52. '[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)';
  53. const NUMBER_MODE = {
  54. className: 'number',
  55. relevance: 0,
  56. variants: [
  57. {
  58. begin: RE_NUMBER
  59. },
  60. {
  61. begin: '\\(-' + RE_NUMBER + '\\)'
  62. }
  63. ]
  64. };
  65. const OPERATOR_MODE = {
  66. className: 'operator',
  67. relevance: 0,
  68. begin: RE_OPERATOR
  69. };
  70. const LIST_CONTENTS_MODES = [
  71. {
  72. className: 'identifier',
  73. relevance: 0,
  74. begin: RE_IDENT
  75. },
  76. OPERATOR_MODE,
  77. NUMBER_MODE
  78. ];
  79. const MODULE_ACCESS_CONTENTS = [
  80. hljs.QUOTE_STRING_MODE,
  81. OPERATOR_MODE,
  82. {
  83. className: 'module',
  84. begin: "\\b" + RE_MODULE_IDENT,
  85. returnBegin: true,
  86. end: "\.",
  87. contains: [
  88. {
  89. className: 'identifier',
  90. begin: RE_MODULE_IDENT,
  91. relevance: 0
  92. }
  93. ]
  94. }
  95. ];
  96. const PARAMS_CONTENTS = [
  97. {
  98. className: 'module',
  99. begin: "\\b" + RE_MODULE_IDENT,
  100. returnBegin: true,
  101. end: "\.",
  102. relevance: 0,
  103. contains: [
  104. {
  105. className: 'identifier',
  106. begin: RE_MODULE_IDENT,
  107. relevance: 0
  108. }
  109. ]
  110. }
  111. ];
  112. const PARAMS_MODE = {
  113. begin: RE_IDENT,
  114. end: '(,|\\n|\\))',
  115. relevance: 0,
  116. contains: [
  117. OPERATOR_MODE,
  118. {
  119. className: 'typing',
  120. begin: ':',
  121. end: '(,|\\n)',
  122. returnBegin: true,
  123. relevance: 0,
  124. contains: PARAMS_CONTENTS
  125. }
  126. ]
  127. };
  128. const FUNCTION_BLOCK_MODE = {
  129. className: 'function',
  130. relevance: 0,
  131. keywords: KEYWORDS,
  132. variants: [
  133. {
  134. begin: '\\s(\\(\\.?.*?\\)|' + RE_IDENT + ')\\s*=>',
  135. end: '\\s*=>',
  136. returnBegin: true,
  137. relevance: 0,
  138. contains: [
  139. {
  140. className: 'params',
  141. variants: [
  142. {
  143. begin: RE_IDENT
  144. },
  145. {
  146. begin: RE_PARAM
  147. },
  148. {
  149. begin: /\(\s*\)/
  150. }
  151. ]
  152. }
  153. ]
  154. },
  155. {
  156. begin: '\\s\\(\\.?[^;\\|]*\\)\\s*=>',
  157. end: '\\s=>',
  158. returnBegin: true,
  159. relevance: 0,
  160. contains: [
  161. {
  162. className: 'params',
  163. relevance: 0,
  164. variants: [ PARAMS_MODE ]
  165. }
  166. ]
  167. },
  168. {
  169. begin: '\\(\\.\\s' + RE_IDENT + '\\)\\s*=>'
  170. }
  171. ]
  172. };
  173. MODULE_ACCESS_CONTENTS.push(FUNCTION_BLOCK_MODE);
  174. const CONSTRUCTOR_MODE = {
  175. className: 'constructor',
  176. begin: RE_MODULE_IDENT + '\\(',
  177. end: '\\)',
  178. illegal: '\\n',
  179. keywords: KEYWORDS,
  180. contains: [
  181. hljs.QUOTE_STRING_MODE,
  182. OPERATOR_MODE,
  183. {
  184. className: 'params',
  185. begin: '\\b' + RE_IDENT
  186. }
  187. ]
  188. };
  189. const PATTERN_MATCH_BLOCK_MODE = {
  190. className: 'pattern-match',
  191. begin: '\\|',
  192. returnBegin: true,
  193. keywords: KEYWORDS,
  194. end: '=>',
  195. relevance: 0,
  196. contains: [
  197. CONSTRUCTOR_MODE,
  198. OPERATOR_MODE,
  199. {
  200. relevance: 0,
  201. className: 'constructor',
  202. begin: RE_MODULE_IDENT
  203. }
  204. ]
  205. };
  206. const MODULE_ACCESS_MODE = {
  207. className: 'module-access',
  208. keywords: KEYWORDS,
  209. returnBegin: true,
  210. variants: [
  211. {
  212. begin: "\\b(" + RE_MODULE_IDENT + "\\.)+" + RE_IDENT
  213. },
  214. {
  215. begin: "\\b(" + RE_MODULE_IDENT + "\\.)+\\(",
  216. end: "\\)",
  217. returnBegin: true,
  218. contains: [
  219. FUNCTION_BLOCK_MODE,
  220. {
  221. begin: '\\(',
  222. end: '\\)',
  223. skip: true
  224. }
  225. ].concat(MODULE_ACCESS_CONTENTS)
  226. },
  227. {
  228. begin: "\\b(" + RE_MODULE_IDENT + "\\.)+\\{",
  229. end: /\}/
  230. }
  231. ],
  232. contains: MODULE_ACCESS_CONTENTS
  233. };
  234. PARAMS_CONTENTS.push(MODULE_ACCESS_MODE);
  235. return {
  236. name: 'ReasonML',
  237. aliases: [ 're' ],
  238. keywords: KEYWORDS,
  239. illegal: '(:-|:=|\\$\\{|\\+=)',
  240. contains: [
  241. hljs.COMMENT('/\\*', '\\*/', {
  242. illegal: '^(#,\\/\\/)'
  243. }),
  244. {
  245. className: 'character',
  246. begin: '\'(\\\\[^\']+|[^\'])\'',
  247. illegal: '\\n',
  248. relevance: 0
  249. },
  250. hljs.QUOTE_STRING_MODE,
  251. {
  252. className: 'literal',
  253. begin: '\\(\\)',
  254. relevance: 0
  255. },
  256. {
  257. className: 'literal',
  258. begin: '\\[\\|',
  259. end: '\\|\\]',
  260. relevance: 0,
  261. contains: LIST_CONTENTS_MODES
  262. },
  263. {
  264. className: 'literal',
  265. begin: '\\[',
  266. end: '\\]',
  267. relevance: 0,
  268. contains: LIST_CONTENTS_MODES
  269. },
  270. CONSTRUCTOR_MODE,
  271. {
  272. className: 'operator',
  273. begin: RE_OPERATOR_SPACED,
  274. illegal: '-->',
  275. relevance: 0
  276. },
  277. NUMBER_MODE,
  278. hljs.C_LINE_COMMENT_MODE,
  279. PATTERN_MATCH_BLOCK_MODE,
  280. FUNCTION_BLOCK_MODE,
  281. {
  282. className: 'module-def',
  283. begin: "\\bmodule\\s+" + RE_IDENT + "\\s+" + RE_MODULE_IDENT + "\\s+=\\s+\\{",
  284. end: /\}/,
  285. returnBegin: true,
  286. keywords: KEYWORDS,
  287. relevance: 0,
  288. contains: [
  289. {
  290. className: 'module',
  291. relevance: 0,
  292. begin: RE_MODULE_IDENT
  293. },
  294. {
  295. begin: /\{/,
  296. end: /\}/,
  297. skip: true
  298. }
  299. ].concat(MODULE_ACCESS_CONTENTS)
  300. },
  301. MODULE_ACCESS_MODE
  302. ]
  303. };
  304. }
  305. module.exports = reasonml;