123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- /*
- 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 };
|