mirror of https://github.com/jkjoy/sunpeiwen.git
303 lines
5.3 KiB
JavaScript
303 lines
5.3 KiB
JavaScript
/*
|
|
Language: Wren
|
|
Description: Think Smalltalk in a Lua-sized package with a dash of Erlang and wrapped up in a familiar, modern syntax.
|
|
Category: scripting
|
|
Author: @joshgoebel
|
|
Maintainer: @joshgoebel
|
|
Website: https://wren.io/
|
|
*/
|
|
|
|
/** @type LanguageFn */
|
|
function wren(hljs) {
|
|
const regex = hljs.regex;
|
|
const IDENT_RE = /[a-zA-Z]\w*/;
|
|
const KEYWORDS = [
|
|
"as",
|
|
"break",
|
|
"class",
|
|
"construct",
|
|
"continue",
|
|
"else",
|
|
"for",
|
|
"foreign",
|
|
"if",
|
|
"import",
|
|
"in",
|
|
"is",
|
|
"return",
|
|
"static",
|
|
"var",
|
|
"while"
|
|
];
|
|
const LITERALS = [
|
|
"true",
|
|
"false",
|
|
"null"
|
|
];
|
|
const LANGUAGE_VARS = [
|
|
"this",
|
|
"super"
|
|
];
|
|
const CORE_CLASSES = [
|
|
"Bool",
|
|
"Class",
|
|
"Fiber",
|
|
"Fn",
|
|
"List",
|
|
"Map",
|
|
"Null",
|
|
"Num",
|
|
"Object",
|
|
"Range",
|
|
"Sequence",
|
|
"String",
|
|
"System"
|
|
];
|
|
const OPERATORS = [
|
|
"-",
|
|
"~",
|
|
/\*/,
|
|
"%",
|
|
/\.\.\./,
|
|
/\.\./,
|
|
/\+/,
|
|
"<<",
|
|
">>",
|
|
">=",
|
|
"<=",
|
|
"<",
|
|
">",
|
|
/\^/,
|
|
/!=/,
|
|
/!/,
|
|
/\bis\b/,
|
|
"==",
|
|
"&&",
|
|
"&",
|
|
/\|\|/,
|
|
/\|/,
|
|
/\?:/,
|
|
"="
|
|
];
|
|
const FUNCTION = {
|
|
relevance: 0,
|
|
match: regex.concat(/\b(?!(if|while|for|else|super)\b)/, IDENT_RE, /(?=\s*[({])/),
|
|
className: "title.function"
|
|
};
|
|
const FUNCTION_DEFINITION = {
|
|
match: regex.concat(
|
|
regex.either(
|
|
regex.concat(/\b(?!(if|while|for|else|super)\b)/, IDENT_RE),
|
|
regex.either(...OPERATORS)
|
|
),
|
|
/(?=\s*\([^)]+\)\s*\{)/),
|
|
className: "title.function",
|
|
starts: { contains: [
|
|
{
|
|
begin: /\(/,
|
|
end: /\)/,
|
|
contains: [
|
|
{
|
|
relevance: 0,
|
|
scope: "params",
|
|
match: IDENT_RE
|
|
}
|
|
]
|
|
}
|
|
] }
|
|
};
|
|
const CLASS_DEFINITION = {
|
|
variants: [
|
|
{ match: [
|
|
/class\s+/,
|
|
IDENT_RE,
|
|
/\s+is\s+/,
|
|
IDENT_RE
|
|
] },
|
|
{ match: [
|
|
/class\s+/,
|
|
IDENT_RE
|
|
] }
|
|
],
|
|
scope: {
|
|
2: "title.class",
|
|
4: "title.class.inherited"
|
|
},
|
|
keywords: KEYWORDS
|
|
};
|
|
|
|
const OPERATOR = {
|
|
relevance: 0,
|
|
match: regex.either(...OPERATORS),
|
|
className: "operator"
|
|
};
|
|
|
|
const TRIPLE_STRING = {
|
|
className: "string",
|
|
begin: /"""/,
|
|
end: /"""/
|
|
};
|
|
|
|
const PROPERTY = {
|
|
className: "property",
|
|
begin: regex.concat(/\./, regex.lookahead(IDENT_RE)),
|
|
end: IDENT_RE,
|
|
excludeBegin: true,
|
|
relevance: 0
|
|
};
|
|
|
|
const FIELD = {
|
|
relevance: 0,
|
|
match: regex.concat(/\b_/, IDENT_RE),
|
|
scope: "variable"
|
|
};
|
|
|
|
// CamelCase
|
|
const CLASS_REFERENCE = {
|
|
relevance: 0,
|
|
match: /\b[A-Z]+[a-z]+([A-Z]+[a-z]+)*/,
|
|
scope: "title.class",
|
|
keywords: { _: CORE_CLASSES }
|
|
};
|
|
|
|
// TODO: add custom number modes
|
|
const NUMBER = hljs.C_NUMBER_MODE;
|
|
|
|
const SETTER = {
|
|
match: [
|
|
IDENT_RE,
|
|
/\s*/,
|
|
/=/,
|
|
/\s*/,
|
|
/\(/,
|
|
IDENT_RE,
|
|
/\)\s*\{/
|
|
],
|
|
scope: {
|
|
1: "title.function",
|
|
3: "operator",
|
|
6: "params"
|
|
}
|
|
};
|
|
|
|
const COMMENT_DOCS = hljs.COMMENT(
|
|
/\/\*\*/,
|
|
/\*\//,
|
|
{ contains: [
|
|
{
|
|
match: /@[a-z]+/,
|
|
scope: "doctag"
|
|
},
|
|
"self"
|
|
] }
|
|
);
|
|
const SUBST = {
|
|
scope: "subst",
|
|
begin: /%\(/,
|
|
end: /\)/,
|
|
contains: [
|
|
NUMBER,
|
|
CLASS_REFERENCE,
|
|
FUNCTION,
|
|
FIELD,
|
|
OPERATOR
|
|
]
|
|
};
|
|
const STRING = {
|
|
scope: "string",
|
|
begin: /"/,
|
|
end: /"/,
|
|
contains: [
|
|
SUBST,
|
|
{
|
|
scope: "char.escape",
|
|
variants: [
|
|
{ match: /\\\\|\\["0%abefnrtv]/ },
|
|
{ match: /\\x[0-9A-F]{2}/ },
|
|
{ match: /\\u[0-9A-F]{4}/ },
|
|
{ match: /\\U[0-9A-F]{8}/ }
|
|
]
|
|
}
|
|
]
|
|
};
|
|
SUBST.contains.push(STRING);
|
|
|
|
const ALL_KWS = [
|
|
...KEYWORDS,
|
|
...LANGUAGE_VARS,
|
|
...LITERALS
|
|
];
|
|
const VARIABLE = {
|
|
relevance: 0,
|
|
match: regex.concat(
|
|
"\\b(?!",
|
|
ALL_KWS.join("|"),
|
|
"\\b)",
|
|
/[a-zA-Z_]\w*(?:[?!]|\b)/
|
|
),
|
|
className: "variable"
|
|
};
|
|
|
|
// TODO: reconsider this in the future
|
|
const ATTRIBUTE = {
|
|
// scope: "meta",
|
|
scope: "comment",
|
|
variants: [
|
|
{
|
|
begin: [
|
|
/#!?/,
|
|
/[A-Za-z_]+(?=\()/
|
|
],
|
|
beginScope: {
|
|
// 2: "attr"
|
|
},
|
|
keywords: { literal: LITERALS },
|
|
contains: [
|
|
// NUMBER,
|
|
// VARIABLE
|
|
],
|
|
end: /\)/
|
|
},
|
|
{
|
|
begin: [
|
|
/#!?/,
|
|
/[A-Za-z_]+/
|
|
],
|
|
beginScope: {
|
|
// 2: "attr"
|
|
},
|
|
end: /$/
|
|
}
|
|
]
|
|
};
|
|
|
|
return {
|
|
name: "Wren",
|
|
keywords: {
|
|
keyword: KEYWORDS,
|
|
"variable.language": LANGUAGE_VARS,
|
|
literal: LITERALS
|
|
},
|
|
contains: [
|
|
ATTRIBUTE,
|
|
NUMBER,
|
|
STRING,
|
|
TRIPLE_STRING,
|
|
COMMENT_DOCS,
|
|
hljs.C_LINE_COMMENT_MODE,
|
|
hljs.C_BLOCK_COMMENT_MODE,
|
|
CLASS_REFERENCE,
|
|
CLASS_DEFINITION,
|
|
SETTER,
|
|
FUNCTION_DEFINITION,
|
|
FUNCTION,
|
|
OPERATOR,
|
|
FIELD,
|
|
PROPERTY,
|
|
VARIABLE
|
|
]
|
|
};
|
|
}
|
|
|
|
export { wren as default };
|