import * as monaco from "monaco-editor-core"

export default <monaco.languages.IMonarchLanguage>{
    defaultToken: '',
    tokenPostfix: '.qasm',

    // 关键字
    keywords: [
        'OPENQASM',
        'include',
        'qreg',
        'creg',
        'gate',
        'measure',
        'reset',
        'barrier',
        'if',
        'sin',
        'cos',
        'tan',
        'exp',
        'ln',
        'sqrt',
        'pi',
    ],

    // 量子门操作
    gates: [
        'u1',
        'u2',
        'u3',
        'x',
        'y',
        'z',
        'h',
        's',
        't',
        'sdg',
        'tdg',
        'rx',
        'ry',
        'rz',
        'cx',
        'cy',
        'cz',
        'ch',
        'ccx',
        'crz',
        'cu1',
        'cu3',
    ],

    // 运算符和标点符号
    operators: [
        '=',
        '>',
        '<',
        '!',
        '~',
        '?',
        ':',
        '==',
        '!=',
        '<=',
        '>=',
        '&&',
        '||',
        '+',
        '-',
        '*',
        '/',
        '%',
        '^',
    ],

    // 符号
    symbols: /[=><!~?:&|+\-*\/\^%]+/,

    // 转义字符
    escapes:
        /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,

    // 整个语法规则
    tokenizer: {
        root: [
            // 标识符和关键字
            [
                /[a-z_$][\w$]*/,
                {
                    cases: {
                        '@keywords': 'keyword',
                        '@gates': 'type',
                        '@default': 'identifier',
                    },
                },
            ],

            // 数字
            [/\d*\.\d+([eE][\-+]?\d+)?/, 'number.float'],
            [/\d+/, 'number'],

            // 分隔符
            [/[;,.]/, 'delimiter'],

            // 字符串
            [/"([^"\\]|\\.)*$/, 'string.invalid'], // 非终止字符串
            [/"/, { token: 'string.quote', bracket: '@open', next: '@string' }],

            // 注释
            [/\/\/.*$/, 'comment'],

            // 括号
            [/[{}()\[\]]/, '@brackets'],

            // 运算符
            [
                /@symbols/,
                {
                    cases: {
                        '@operators': 'operator',
                        '@default': '',
                    },
                },
            ],

            // 空白字符
            [/\s+/, 'white'],
        ],

        string: [
            [/[^\\"]+/, 'string'],
            [/@escapes/, 'string.escape'],
            [/\\./, 'string.escape.invalid'],
            [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' }],
        ],
    },
};
