/*
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 };
//# sourceMappingURL=wren.js.map