Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

321 lines
7.0 KiB

/*
Language: ReasonML
Description: Reason lets you write simple, fast and quality type safe code while leveraging both the JavaScript & OCaml ecosystems.
Website: https://reasonml.github.io
Author: Gidi Meir Morris <oss@gidi.io>
Category: functional
*/
function reasonml(hljs) {
function orReValues(ops) {
return ops
.map(function(op) {
return op
.split('')
.map(function(char) {
return '\\' + char;
})
.join('');
})
.join('|');
}
const RE_IDENT = '~?[a-z$_][0-9a-zA-Z$_]*';
const RE_MODULE_IDENT = '`?[A-Z$_][0-9a-zA-Z$_]*';
const RE_PARAM_TYPEPARAM = '\'?[a-z$_][0-9a-z$_]*';
const RE_PARAM_TYPE = '\s*:\s*[a-z$_][0-9a-z$_]*(\(\s*(' + RE_PARAM_TYPEPARAM + '\s*(,' + RE_PARAM_TYPEPARAM + ')*)?\s*\))?';
const RE_PARAM = RE_IDENT + '(' + RE_PARAM_TYPE + ')?(' + RE_PARAM_TYPE + ')?';
const RE_OPERATOR = "(" + orReValues([
'||',
'++',
'**',
'+.',
'*',
'/',
'*.',
'/.',
'...'
]) + "|\\|>|&&|==|===)";
const RE_OPERATOR_SPACED = "\\s+" + RE_OPERATOR + "\\s+";
const KEYWORDS = {
keyword:
'and as asr assert begin class constraint do done downto else end exception external ' +
'for fun function functor if in include inherit initializer ' +
'land lazy let lor lsl lsr lxor match method mod module mutable new nonrec ' +
'object of open or private rec sig struct then to try type val virtual when while with',
built_in:
'array bool bytes char exn|5 float int int32 int64 list lazy_t|5 nativeint|5 ref string unit ',
literal:
'true false'
};
const RE_NUMBER = '\\b(0[xX][a-fA-F0-9_]+[Lln]?|' +
'0[oO][0-7_]+[Lln]?|' +
'0[bB][01_]+[Lln]?|' +
'[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)';
const NUMBER_MODE = {
className: 'number',
relevance: 0,
variants: [
{
begin: RE_NUMBER
},
{
begin: '\\(-' + RE_NUMBER + '\\)'
}
]
};
const OPERATOR_MODE = {
className: 'operator',
relevance: 0,
begin: RE_OPERATOR
};
const LIST_CONTENTS_MODES = [
{
className: 'identifier',
relevance: 0,
begin: RE_IDENT
},
OPERATOR_MODE,
NUMBER_MODE
];
const MODULE_ACCESS_CONTENTS = [
hljs.QUOTE_STRING_MODE,
OPERATOR_MODE,
{
className: 'module',
begin: "\\b" + RE_MODULE_IDENT,
returnBegin: true,
end: "\.",
contains: [
{
className: 'identifier',
begin: RE_MODULE_IDENT,
relevance: 0
}
]
}
];
const PARAMS_CONTENTS = [
{
className: 'module',
begin: "\\b" + RE_MODULE_IDENT,
returnBegin: true,
end: "\.",
relevance: 0,
contains: [
{
className: 'identifier',
begin: RE_MODULE_IDENT,
relevance: 0
}
]
}
];
const PARAMS_MODE = {
begin: RE_IDENT,
end: '(,|\\n|\\))',
relevance: 0,
contains: [
OPERATOR_MODE,
{
className: 'typing',
begin: ':',
end: '(,|\\n)',
returnBegin: true,
relevance: 0,
contains: PARAMS_CONTENTS
}
]
};
const FUNCTION_BLOCK_MODE = {
className: 'function',
relevance: 0,
keywords: KEYWORDS,
variants: [
{
begin: '\\s(\\(\\.?.*?\\)|' + RE_IDENT + ')\\s*=>',
end: '\\s*=>',
returnBegin: true,
relevance: 0,
contains: [
{
className: 'params',
variants: [
{
begin: RE_IDENT
},
{
begin: RE_PARAM
},
{
begin: /\(\s*\)/
}
]
}
]
},
{
begin: '\\s\\(\\.?[^;\\|]*\\)\\s*=>',
end: '\\s=>',
returnBegin: true,
relevance: 0,
contains: [
{
className: 'params',
relevance: 0,
variants: [ PARAMS_MODE ]
}
]
},
{
begin: '\\(\\.\\s' + RE_IDENT + '\\)\\s*=>'
}
]
};
MODULE_ACCESS_CONTENTS.push(FUNCTION_BLOCK_MODE);
const CONSTRUCTOR_MODE = {
className: 'constructor',
begin: RE_MODULE_IDENT + '\\(',
end: '\\)',
illegal: '\\n',
keywords: KEYWORDS,
contains: [
hljs.QUOTE_STRING_MODE,
OPERATOR_MODE,
{
className: 'params',
begin: '\\b' + RE_IDENT
}
]
};
const PATTERN_MATCH_BLOCK_MODE = {
className: 'pattern-match',
begin: '\\|',
returnBegin: true,
keywords: KEYWORDS,
end: '=>',
relevance: 0,
contains: [
CONSTRUCTOR_MODE,
OPERATOR_MODE,
{
relevance: 0,
className: 'constructor',
begin: RE_MODULE_IDENT
}
]
};
const MODULE_ACCESS_MODE = {
className: 'module-access',
keywords: KEYWORDS,
returnBegin: true,
variants: [
{
begin: "\\b(" + RE_MODULE_IDENT + "\\.)+" + RE_IDENT
},
{
begin: "\\b(" + RE_MODULE_IDENT + "\\.)+\\(",
end: "\\)",
returnBegin: true,
contains: [
FUNCTION_BLOCK_MODE,
{
begin: '\\(',
end: '\\)',
skip: true
}
].concat(MODULE_ACCESS_CONTENTS)
},
{
begin: "\\b(" + RE_MODULE_IDENT + "\\.)+\\{",
end: /\}/
}
],
contains: MODULE_ACCESS_CONTENTS
};
PARAMS_CONTENTS.push(MODULE_ACCESS_MODE);
return {
name: 'ReasonML',
aliases: [ 're' ],
keywords: KEYWORDS,
illegal: '(:-|:=|\\$\\{|\\+=)',
contains: [
hljs.COMMENT('/\\*', '\\*/', {
illegal: '^(#,\\/\\/)'
}),
{
className: 'character',
begin: '\'(\\\\[^\']+|[^\'])\'',
illegal: '\\n',
relevance: 0
},
hljs.QUOTE_STRING_MODE,
{
className: 'literal',
begin: '\\(\\)',
relevance: 0
},
{
className: 'literal',
begin: '\\[\\|',
end: '\\|\\]',
relevance: 0,
contains: LIST_CONTENTS_MODES
},
{
className: 'literal',
begin: '\\[',
end: '\\]',
relevance: 0,
contains: LIST_CONTENTS_MODES
},
CONSTRUCTOR_MODE,
{
className: 'operator',
begin: RE_OPERATOR_SPACED,
illegal: '-->',
relevance: 0
},
NUMBER_MODE,
hljs.C_LINE_COMMENT_MODE,
PATTERN_MATCH_BLOCK_MODE,
FUNCTION_BLOCK_MODE,
{
className: 'module-def',
begin: "\\bmodule\\s+" + RE_IDENT + "\\s+" + RE_MODULE_IDENT + "\\s+=\\s+\\{",
end: /\}/,
returnBegin: true,
keywords: KEYWORDS,
relevance: 0,
contains: [
{
className: 'module',
relevance: 0,
begin: RE_MODULE_IDENT
},
{
begin: /\{/,
end: /\}/,
skip: true
}
].concat(MODULE_ACCESS_CONTENTS)
},
MODULE_ACCESS_MODE
]
};
}
module.exports = reasonml;