/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
export var conf = {
    brackets: [
        ['{', '}'],
        ['[', ']'],
        ['(', ')']
    ],
    autoClosingPairs: [
        { open: '{', close: '}' },
        { open: '[', close: ']' },
        { open: '(', close: ')' },
        { open: '"', close: '"' },
        { open: "'", close: "'" }
    ],
    surroundingPairs: [
        { open: '{', close: '}' },
        { open: '[', close: ']' },
        { open: '(', close: ')' },
        { open: '"', close: '"' },
        { open: "'", close: "'" }
    ]
};
export var language = {
    tokenPostfix: '.julia',
    keywords: [
        'begin',
        'while',
        'if',
        'for',
        'try',
        'return',
        'break',
        'continue',
        'function',
        'macro',
        'quote',
        'let',
        'local',
        'global',
        'const',
        'do',
        'struct',
        'module',
        'baremodule',
        'using',
        'import',
        'export',
        'end',
        'else',
        'elseif',
        'catch',
        'finally',
        'mutable',
        'primitive',
        'abstract',
        'type',
        'in',
        'isa',
        'where',
        'new'
    ],
    types: [
        'LinRange',
        'LineNumberNode',
        'LinearIndices',
        'LoadError',
        'MIME',
        'Matrix',
        'Method',
        'MethodError',
        'Missing',
        'MissingException',
        'Module',
        'NTuple',
        'NamedTuple',
        'Nothing',
        'Number',
        'OrdinalRange',
        'OutOfMemoryError',
        'OverflowError',
        'Pair',
        'PartialQuickSort',
        'PermutedDimsArray',
        'Pipe',
        'Ptr',
        'QuoteNode',
        'Rational',
        'RawFD',
        'ReadOnlyMemoryError',
        'Real',
        'ReentrantLock',
        'Ref',
        'Regex',
        'RegexMatch',
        'RoundingMode',
        'SegmentationFault',
        'Set',
        'Signed',
        'Some',
        'StackOverflowError',
        'StepRange',
        'StepRangeLen',
        'StridedArray',
        'StridedMatrix',
        'StridedVecOrMat',
        'StridedVector',
        'String',
        'StringIndexError',
        'SubArray',
        'SubString',
        'SubstitutionString',
        'Symbol',
        'SystemError',
        'Task',
        'Text',
        'TextDisplay',
        'Timer',
        'Tuple',
        'Type',
        'TypeError',
        'TypeVar',
        'UInt',
        'UInt128',
        'UInt16',
        'UInt32',
        'UInt64',
        'UInt8',
        'UndefInitializer',
        'AbstractArray',
        'UndefKeywordError',
        'AbstractChannel',
        'UndefRefError',
        'AbstractChar',
        'UndefVarError',
        'AbstractDict',
        'Union',
        'AbstractDisplay',
        'UnionAll',
        'AbstractFloat',
        'UnitRange',
        'AbstractIrrational',
        'Unsigned',
        'AbstractMatrix',
        'AbstractRange',
        'Val',
        'AbstractSet',
        'Vararg',
        'AbstractString',
        'VecElement',
        'AbstractUnitRange',
        'VecOrMat',
        'AbstractVecOrMat',
        'Vector',
        'AbstractVector',
        'VersionNumber',
        'Any',
        'WeakKeyDict',
        'ArgumentError',
        'WeakRef',
        'Array',
        'AssertionError',
        'BigFloat',
        'BigInt',
        'BitArray',
        'BitMatrix',
        'BitSet',
        'BitVector',
        'Bool',
        'BoundsError',
        'CapturedException',
        'CartesianIndex',
        'CartesianIndices',
        'Cchar',
        'Cdouble',
        'Cfloat',
        'Channel',
        'Char',
        'Cint',
        'Cintmax_t',
        'Clong',
        'Clonglong',
        'Cmd',
        'Colon',
        'Complex',
        'ComplexF16',
        'ComplexF32',
        'ComplexF64',
        'CompositeException',
        'Condition',
        'Cptrdiff_t',
        'Cshort',
        'Csize_t',
        'Cssize_t',
        'Cstring',
        'Cuchar',
        'Cuint',
        'Cuintmax_t',
        'Culong',
        'Culonglong',
        'Cushort',
        'Cvoid',
        'Cwchar_t',
        'Cwstring',
        'DataType',
        'DenseArray',
        'DenseMatrix',
        'DenseVecOrMat',
        'DenseVector',
        'Dict',
        'DimensionMismatch',
        'Dims',
        'DivideError',
        'DomainError',
        'EOFError',
        'Enum',
        'ErrorException',
        'Exception',
        'ExponentialBackOff',
        'Expr',
        'Float16',
        'Float32',
        'Float64',
        'Function',
        'GlobalRef',
        'HTML',
        'IO',
        'IOBuffer',
        'IOContext',
        'IOStream',
        'IdDict',
        'IndexCartesian',
        'IndexLinear',
        'IndexStyle',
        'InexactError',
        'InitError',
        'Int',
        'Int128',
        'Int16',
        'Int32',
        'Int64',
        'Int8',
        'Integer',
        'InterruptException',
        'InvalidStateException',
        'Irrational',
        'KeyError'
    ],
    keywordops: ['<:', '>:', ':', '=>', '...', '.', '->', '?'],
    allops: /[^\w\d\s()\[\]{}"'#]+/,
    constants: [
        'true',
        'false',
        'nothing',
        'missing',
        'undef',
        'Inf',
        'pi',
        'NaN',
        'π',
        'ℯ',
        'ans',
        'PROGRAM_FILE',
        'ARGS',
        'C_NULL',
        'VERSION',
        'DEPOT_PATH',
        'LOAD_PATH'
    ],
    operators: [
        '!',
        '!=',
        '!==',
        '%',
        '&',
        '*',
        '+',
        '-',
        '/',
        '//',
        '<',
        '<<',
        '<=',
        '==',
        '===',
        '=>',
        '>',
        '>=',
        '>>',
        '>>>',
        '\\',
        '^',
        '|',
        '|>',
        '~',
        '÷',
        '∈',
        '∉',
        '∋',
        '∌',
        '∘',
        '√',
        '∛',
        '∩',
        '∪',
        '≈',
        '≉',
        '≠',
        '≡',
        '≢',
        '≤',
        '≥',
        '⊆',
        '⊇',
        '⊈',
        '⊉',
        '⊊',
        '⊋',
        '⊻'
    ],
    brackets: [
        { open: '(', close: ')', token: 'delimiter.parenthesis' },
        { open: '{', close: '}', token: 'delimiter.curly' },
        { open: '[', close: ']', token: 'delimiter.square' }
    ],
    ident: /π|ℯ|\b(?!\d)\w+\b/,
    // escape sequences
    escape: /(?:[abefnrstv\\"'\n\r]|[0-7]{1,3}|x[0-9A-Fa-f]{1,2}|u[0-9A-Fa-f]{4})/,
    escapes: /\\(?:C\-(@escape|.)|c(@escape|.)|@escape)/,
    // The main tokenizer for our languages
    tokenizer: {
        root: [
            [/(::)\s*|\b(isa)\s+/, 'keyword', '@typeanno'],
            [/\b(isa)(\s*\(@ident\s*,\s*)/, ['keyword', { token: '', next: '@typeanno' }]],
            [/\b(type|struct)[ \t]+/, 'keyword', '@typeanno'],
            // symbols
            [/^\s*:@ident[!?]?/, 'metatag'],
            [/(return)(\s*:@ident[!?]?)/, ['keyword', 'metatag']],
            [/(\(|\[|\{|@allops)(\s*:@ident[!?]?)/, ['', 'metatag']],
            [/:\(/, 'metatag', '@quote'],
            // regular expressions
            [/r"""/, 'regexp.delim', '@tregexp'],
            [/r"/, 'regexp.delim', '@sregexp'],
            // strings
            [/raw"""/, 'string.delim', '@rtstring'],
            [/[bv]?"""/, 'string.delim', '@dtstring'],
            [/raw"/, 'string.delim', '@rsstring'],
            [/[bv]?"/, 'string.delim', '@dsstring'],
            [
                /(@ident)\{/,
                {
                    cases: {
                        '$1@types': { token: 'type', next: '@gen' },
                        '@default': { token: 'type', next: '@gen' }
                    }
                }
            ],
            [
                /@ident[!?'']?(?=\.?\()/,
                {
                    cases: {
                        '@types': 'type',
                        '@keywords': 'keyword',
                        '@constants': 'variable',
                        '@default': 'keyword.flow'
                    }
                }
            ],
            [
                /@ident[!?']?/,
                {
                    cases: {
                        '@types': 'type',
                        '@keywords': 'keyword',
                        '@constants': 'variable',
                        '@default': 'identifier'
                    }
                }
            ],
            [/\$\w+/, 'key'],
            [/\$\(/, 'key', '@paste'],
            [/@@ident/, 'annotation'],
            // whitespace
            { include: '@whitespace' },
            // characters
            [/'(?:@escapes|.)'/, 'string.character'],
            // delimiters and operators
            [/[()\[\]{}]/, '@brackets'],
            [
                /@allops/,
                {
                    cases: {
                        '@keywordops': 'keyword',
                        '@operators': 'operator'
                    }
                }
            ],
            [/[;,]/, 'delimiter'],
            // numbers
            [/0[xX][0-9a-fA-F](_?[0-9a-fA-F])*/, 'number.hex'],
            [/0[_oO][0-7](_?[0-7])*/, 'number.octal'],
            [/0[bB][01](_?[01])*/, 'number.binary'],
            [/[+\-]?\d+(\.\d+)?(im?|[eE][+\-]?\d+(\.\d+)?)?/, 'number']
        ],
        // type
        typeanno: [
            [/[a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*)*\{/, 'type', '@gen'],
            [/([a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*)*)(\s*<:\s*)/, ['type', 'keyword']],
            [/[a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*)*/, 'type', '@pop'],
            ['', '', '@pop']
        ],
        // generic type
        gen: [
            [/[a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*)*\{/, 'type', '@push'],
            [/[a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*)*/, 'type'],
            [/<:/, 'keyword'],
            [/(\})(\s*<:\s*)/, ['type', { token: 'keyword', next: '@pop' }]],
            [/\}/, 'type', '@pop'],
            { include: '@root' }
        ],
        // $(...)
        quote: [
            [/\$\(/, 'key', '@paste'],
            [/\(/, '@brackets', '@paren'],
            [/\)/, 'metatag', '@pop'],
            { include: '@root' }
        ],
        // :(...)
        paste: [
            [/:\(/, 'metatag', '@quote'],
            [/\(/, '@brackets', '@paren'],
            [/\)/, 'key', '@pop'],
            { include: '@root' }
        ],
        // (...)
        paren: [
            [/\$\(/, 'key', '@paste'],
            [/:\(/, 'metatag', '@quote'],
            [/\(/, '@brackets', '@push'],
            [/\)/, '@brackets', '@pop'],
            { include: '@root' }
        ],
        // r"egex string"
        sregexp: [
            [/^.*/, 'invalid'],
            [/[^\\"()\[\]{}]/, 'regexp'],
            [/[()\[\]{}]/, '@brackets'],
            [/\\./, 'operator.scss'],
            [/"[imsx]*/, 'regexp.delim', '@pop']
        ],
        tregexp: [
            [/[^\\"()\[\]{}]/, 'regexp'],
            [/[()\[\]{}]/, '@brackets'],
            [/\\./, 'operator.scss'],
            [/"(?!"")/, 'string'],
            [/"""[imsx]*/, 'regexp.delim', '@pop']
        ],
        // raw"string"
        rsstring: [
            [/^.*/, 'invalid'],
            [/[^\\"]/, 'string'],
            [/\\./, 'string.escape'],
            [/"/, 'string.delim', '@pop']
        ],
        rtstring: [
            [/[^\\"]/, 'string'],
            [/\\./, 'string.escape'],
            [/"(?!"")/, 'string'],
            [/"""/, 'string.delim', '@pop']
        ],
        // "string".
        dsstring: [
            [/^.*/, 'invalid'],
            [/[^\\"\$]/, 'string'],
            [/\$/, '', '@interpolated'],
            [/@escapes/, 'string.escape'],
            [/\\./, 'string.escape.invalid'],
            [/"/, 'string.delim', '@pop']
        ],
        dtstring: [
            [/[^\\"\$]/, 'string'],
            [/\$/, '', '@interpolated'],
            [/@escapes/, 'string.escape'],
            [/\\./, 'string.escape.invalid'],
            [/"(?!"")/, 'string'],
            [/"""/, 'string.delim', '@pop']
        ],
        // interpolated sequence
        interpolated: [
            [/\(/, { token: '', switchTo: '@interpolated_compound' }],
            [/[a-zA-Z_]\w*/, 'identifier'],
            ['', '', '@pop'] // just a $ is interpreted as a $
        ],
        // any code
        interpolated_compound: [[/\)/, '', '@pop'], { include: '@root' }],
        // whitespace & comments
        whitespace: [
            [/[ \t\r\n]+/, ''],
            [/#=/, 'comment', '@multi_comment'],
            [/#.*$/, 'comment']
        ],
        multi_comment: [
            [/#=/, 'comment', '@push'],
            [/=#/, 'comment', '@pop'],
            [/=(?!#)|#(?!=)/, 'comment'],
            [/[^#=]+/, 'comment']
        ]
    }
};
