reasonml.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  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. { begin: RE_NUMBER },
  58. { begin: '\\(-' + RE_NUMBER + '\\)' }
  59. ]
  60. };
  61. const OPERATOR_MODE = {
  62. className: 'operator',
  63. relevance: 0,
  64. begin: RE_OPERATOR
  65. };
  66. const LIST_CONTENTS_MODES = [
  67. {
  68. className: 'identifier',
  69. relevance: 0,
  70. begin: RE_IDENT
  71. },
  72. OPERATOR_MODE,
  73. NUMBER_MODE
  74. ];
  75. const MODULE_ACCESS_CONTENTS = [
  76. hljs.QUOTE_STRING_MODE,
  77. OPERATOR_MODE,
  78. {
  79. className: 'module',
  80. begin: "\\b" + RE_MODULE_IDENT,
  81. returnBegin: true,
  82. relevance: 0,
  83. end: "\.",
  84. contains: [
  85. {
  86. className: 'identifier',
  87. begin: RE_MODULE_IDENT,
  88. relevance: 0
  89. }
  90. ]
  91. }
  92. ];
  93. const PARAMS_CONTENTS = [
  94. {
  95. className: 'module',
  96. begin: "\\b" + RE_MODULE_IDENT,
  97. returnBegin: true,
  98. end: "\.",
  99. relevance: 0,
  100. contains: [
  101. {
  102. className: 'identifier',
  103. begin: RE_MODULE_IDENT,
  104. relevance: 0
  105. }
  106. ]
  107. }
  108. ];
  109. const PARAMS_MODE = {
  110. begin: RE_IDENT,
  111. end: '(,|\\n|\\))',
  112. relevance: 0,
  113. contains: [
  114. OPERATOR_MODE,
  115. {
  116. className: 'typing',
  117. begin: ':',
  118. end: '(,|\\n)',
  119. returnBegin: true,
  120. relevance: 0,
  121. contains: PARAMS_CONTENTS
  122. }
  123. ]
  124. };
  125. const FUNCTION_BLOCK_MODE = {
  126. className: 'function',
  127. relevance: 0,
  128. keywords: KEYWORDS,
  129. variants: [
  130. {
  131. begin: '\\s(\\(\\.?.*?\\)|' + RE_IDENT + ')\\s*=>',
  132. end: '\\s*=>',
  133. returnBegin: true,
  134. relevance: 0,
  135. contains: [
  136. {
  137. className: 'params',
  138. variants: [
  139. { begin: RE_IDENT },
  140. { begin: RE_PARAM },
  141. { begin: /\(\s*\)/ }
  142. ]
  143. }
  144. ]
  145. },
  146. {
  147. begin: '\\s\\(\\.?[^;\\|]*\\)\\s*=>',
  148. end: '\\s=>',
  149. returnBegin: true,
  150. relevance: 0,
  151. contains: [
  152. {
  153. className: 'params',
  154. relevance: 0,
  155. variants: [ PARAMS_MODE ]
  156. }
  157. ]
  158. },
  159. { begin: '\\(\\.\\s' + RE_IDENT + '\\)\\s*=>' }
  160. ]
  161. };
  162. MODULE_ACCESS_CONTENTS.push(FUNCTION_BLOCK_MODE);
  163. const CONSTRUCTOR_MODE = {
  164. className: 'constructor',
  165. begin: RE_MODULE_IDENT + '\\(',
  166. end: '\\)',
  167. illegal: '\\n',
  168. keywords: KEYWORDS,
  169. contains: [
  170. hljs.QUOTE_STRING_MODE,
  171. OPERATOR_MODE,
  172. {
  173. className: 'params',
  174. begin: '\\b' + RE_IDENT
  175. }
  176. ]
  177. };
  178. const PATTERN_MATCH_BLOCK_MODE = {
  179. className: 'pattern-match',
  180. begin: '\\|',
  181. returnBegin: true,
  182. keywords: KEYWORDS,
  183. end: '=>',
  184. relevance: 0,
  185. contains: [
  186. CONSTRUCTOR_MODE,
  187. OPERATOR_MODE,
  188. {
  189. relevance: 0,
  190. className: 'constructor',
  191. begin: RE_MODULE_IDENT
  192. }
  193. ]
  194. };
  195. const MODULE_ACCESS_MODE = {
  196. className: 'module-access',
  197. keywords: KEYWORDS,
  198. returnBegin: true,
  199. variants: [
  200. { begin: "\\b(" + RE_MODULE_IDENT + "\\.)+" + RE_IDENT },
  201. {
  202. begin: "\\b(" + RE_MODULE_IDENT + "\\.)+\\(",
  203. end: "\\)",
  204. returnBegin: true,
  205. contains: [
  206. FUNCTION_BLOCK_MODE,
  207. {
  208. begin: '\\(',
  209. end: '\\)',
  210. relevance: 0,
  211. skip: true
  212. }
  213. ].concat(MODULE_ACCESS_CONTENTS)
  214. },
  215. {
  216. begin: "\\b(" + RE_MODULE_IDENT + "\\.)+\\{",
  217. end: /\}/
  218. }
  219. ],
  220. contains: MODULE_ACCESS_CONTENTS
  221. };
  222. PARAMS_CONTENTS.push(MODULE_ACCESS_MODE);
  223. return {
  224. name: 'ReasonML',
  225. aliases: [ 're' ],
  226. keywords: KEYWORDS,
  227. illegal: '(:-|:=|\\$\\{|\\+=)',
  228. contains: [
  229. hljs.COMMENT('/\\*', '\\*/', { illegal: '^(#,\\/\\/)' }),
  230. {
  231. className: 'character',
  232. begin: '\'(\\\\[^\']+|[^\'])\'',
  233. illegal: '\\n',
  234. relevance: 0
  235. },
  236. hljs.QUOTE_STRING_MODE,
  237. {
  238. className: 'literal',
  239. begin: '\\(\\)',
  240. relevance: 0
  241. },
  242. {
  243. className: 'literal',
  244. begin: '\\[\\|',
  245. end: '\\|\\]',
  246. relevance: 0,
  247. contains: LIST_CONTENTS_MODES
  248. },
  249. {
  250. className: 'literal',
  251. begin: '\\[',
  252. end: '\\]',
  253. relevance: 0,
  254. contains: LIST_CONTENTS_MODES
  255. },
  256. CONSTRUCTOR_MODE,
  257. {
  258. className: 'operator',
  259. begin: RE_OPERATOR_SPACED,
  260. illegal: '-->',
  261. relevance: 0
  262. },
  263. NUMBER_MODE,
  264. hljs.C_LINE_COMMENT_MODE,
  265. PATTERN_MATCH_BLOCK_MODE,
  266. FUNCTION_BLOCK_MODE,
  267. {
  268. className: 'module-def',
  269. begin: "\\bmodule\\s+" + RE_IDENT + "\\s+" + RE_MODULE_IDENT + "\\s+=\\s+\\{",
  270. end: /\}/,
  271. returnBegin: true,
  272. keywords: KEYWORDS,
  273. relevance: 0,
  274. contains: [
  275. {
  276. className: 'module',
  277. relevance: 0,
  278. begin: RE_MODULE_IDENT
  279. },
  280. {
  281. begin: /\{/,
  282. end: /\}/,
  283. relevance: 0,
  284. skip: true
  285. }
  286. ].concat(MODULE_ACCESS_CONTENTS)
  287. },
  288. MODULE_ACCESS_MODE
  289. ]
  290. };
  291. }
  292. export { reasonml as default };