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.

200 lines
5.6 KiB

4 years ago
/**
* @param {string} value
* @returns {RegExp}
* */
/**
* @param {RegExp | string } re
* @returns {string}
*/
function source(re) {
if (!re) return null;
if (typeof re === "string") return re;
return re.source;
}
/**
* @param {...(RegExp | string) } args
* @returns {string}
*/
function concat(...args) {
const joined = args.map((x) => source(x)).join("");
return joined;
}
/*
Language: Perl
Author: Peter Leonov <gojpeg@yandex.ru>
Website: https://www.perl.org
Category: common
*/
/** @type LanguageFn */
function perl(hljs) {
var PERL_KEYWORDS = {
$pattern: /[\w.]+/,
keyword: 'getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ' +
'ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime ' +
'readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qq ' +
'fileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent ' +
'shutdown dump chomp connect getsockname die socketpair close flock exists index shmget ' +
'sub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr ' +
'unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 ' +
'getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline ' +
'endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand ' +
'mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink ' +
'getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr ' +
'untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link ' +
'getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller ' +
'lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and ' +
'sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 ' +
'chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach ' +
'tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedir ' +
'ioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe ' +
'atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when'
};
var SUBST = {
className: 'subst',
begin: '[$@]\\{', end: '\\}',
keywords: PERL_KEYWORDS
};
var METHOD = {
begin: /->\{/, end: /\}/
// contains defined later
};
var VAR = {
variants: [
{begin: /\$\d/},
{begin: concat(
/[$%@](\^\w\b|#\w+(::\w+)*|\{\w+\}|\w+(::\w*)*)/,
// negative look-ahead tries to avoid matching patterns that are not
// Perl at all like $ident$, @ident@, etc.
`(?![A-Za-z])(?![@$%])`
)},
{begin: /[$%@][^\s\w{]/, relevance: 0}
]
};
var STRING_CONTAINS = [hljs.BACKSLASH_ESCAPE, SUBST, VAR];
var PERL_DEFAULT_CONTAINS = [
VAR,
hljs.HASH_COMMENT_MODE,
hljs.COMMENT(
/^=\w/,
/=cut/,
{
endsWithParent: true
}
),
METHOD,
{
className: 'string',
contains: STRING_CONTAINS,
variants: [
{
begin: 'q[qwxr]?\\s*\\(', end: '\\)',
relevance: 5
},
{
begin: 'q[qwxr]?\\s*\\[', end: '\\]',
relevance: 5
},
{
begin: 'q[qwxr]?\\s*\\{', end: '\\}',
relevance: 5
},
{
begin: 'q[qwxr]?\\s*\\|', end: '\\|',
relevance: 5
},
{
begin: 'q[qwxr]?\\s*<', end: '>',
relevance: 5
},
{
begin: 'qw\\s+q', end: 'q',
relevance: 5
},
{
begin: '\'', end: '\'',
contains: [hljs.BACKSLASH_ESCAPE]
},
{
begin: '"', end: '"'
},
{
begin: '`', end: '`',
contains: [hljs.BACKSLASH_ESCAPE]
},
{
begin: /\{\w+\}/,
contains: [],
relevance: 0
},
{
begin: '-?\\w+\\s*=>',
contains: [],
relevance: 0
}
]
},
{
className: 'number',
begin: '(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b',
relevance: 0
},
{ // regexp container
begin: '(\\/\\/|' + hljs.RE_STARTERS_RE + '|\\b(split|return|print|reverse|grep)\\b)\\s*',
keywords: 'split return print reverse grep',
relevance: 0,
contains: [
hljs.HASH_COMMENT_MODE,
{
className: 'regexp',
begin: '(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*',
relevance: 10
},
{
className: 'regexp',
begin: '(m|qr)?/', end: '/[a-z]*',
contains: [hljs.BACKSLASH_ESCAPE],
relevance: 0 // allows empty "//" which is a common comment delimiter in other languages
}
]
},
{
className: 'function',
beginKeywords: 'sub', end: '(\\s*\\(.*?\\))?[;{]', excludeEnd: true,
relevance: 5,
contains: [hljs.TITLE_MODE]
},
{
begin: '-\\w\\b',
relevance: 0
},
{
begin: "^__DATA__$",
end: "^__END__$",
subLanguage: 'mojolicious',
contains: [
{
begin: "^@@.*",
end: "$",
className: "comment"
}
]
}
];
SUBST.contains = PERL_DEFAULT_CONTAINS;
METHOD.contains = PERL_DEFAULT_CONTAINS;
return {
name: 'Perl',
aliases: ['pl', 'pm'],
keywords: PERL_KEYWORDS,
contains: PERL_DEFAULT_CONTAINS
};
}
module.exports = perl;