/*
 * This file is part of MQT QFR library which is released under the MIT license.
 * See file README.md or go to https://www.cda.cit.tum.de/research/quantum/ for more information.
 */

#pragma once

#include "dd/Definitions.hpp"

#include <map>
#include <string>

namespace qasm {

    struct Token {
        enum class Kind {
            include,
            none,
            identifier,
            number,
            plus,
            semicolon,
            eof,
            lpar,
            rpar,
            lbrack,
            rbrack,
            lbrace,
            rbrace,
            comma,
            minus,
            times,
            nninteger,
            real,
            qreg,
            creg,
            gate,
            pi,
            measure,
            openqasm,
            probabilities,
            sin,
            cos,
            tan,
            exp,
            ln,
            sqrt,
            div,
            power,
            string,
            gt,
            barrier,
            opaque,
            _if,
            eq,
            reset,
            snapshot,
            swap,
            ugate,
            cxgate,
            mcx_gray,
            mcx_recursive,
            mcx_vchain,
            mcphase,
            sxgate,
            sxdggate,
            comment
        };

        Kind        kind    = Kind::none;
        int         line    = 0;
        int         col     = 0;
        int         val     = 0;
        dd::fp      valReal = 0.0;
        std::string str;

        Token() = default;
        Token(Kind kind, int line, int col):
            kind(kind), line(line), col(col) {}
    };

    static std::map<Token::Kind, std::string> KindNames{
            {Token::Kind::none, "none"},
            {Token::Kind::include, "include"},
            {Token::Kind::identifier, "<identifier>"},
            {Token::Kind::number, "<number>"},
            {Token::Kind::plus, "+"},
            {Token::Kind::semicolon, ";"},
            {Token::Kind::eof, "EOF"},
            {Token::Kind::lpar, "("},
            {Token::Kind::rpar, ")"},
            {Token::Kind::lbrack, "["},
            {Token::Kind::rbrack, "]"},
            {Token::Kind::lbrace, "{"},
            {Token::Kind::rbrace, "}"},
            {Token::Kind::comma, ","},
            {Token::Kind::minus, "-"},
            {Token::Kind::times, "*"},
            {Token::Kind::nninteger, "<nninteger>"},
            {Token::Kind::real, "<real>"},
            {Token::Kind::qreg, "qreg"},
            {Token::Kind::creg, "creg"},
            {Token::Kind::ugate, "U"},
            {Token::Kind::cxgate, "CX"},
            {Token::Kind::swap, "swap"},
            {Token::Kind::gate, "gate"},
            {Token::Kind::mcx_gray, "mcx_gray"},
            {Token::Kind::mcx_recursive, "mcx_recursive"},
            {Token::Kind::mcx_vchain, "mcx_vchain"},
            {Token::Kind::mcphase, "mcphase"},
            {Token::Kind::sxgate, "sx"},
            {Token::Kind::sxdggate, "sxdg"},
            {Token::Kind::pi, "pi"},
            {Token::Kind::measure, "measure"},
            {Token::Kind::openqasm, "openqasm"},
            {Token::Kind::probabilities, "probabilities"},
            {Token::Kind::opaque, "opaque"},
            {Token::Kind::sin, "sin"},
            {Token::Kind::cos, "cos"},
            {Token::Kind::tan, "tan"},
            {Token::Kind::exp, "exp"},
            {Token::Kind::ln, "ln"},
            {Token::Kind::sqrt, "sqrt"},
            {Token::Kind::div, "/"},
            {Token::Kind::power, "^"},
            {Token::Kind::string, "string"},
            {Token::Kind::gt, ">"},
            {Token::Kind::barrier, "barrier"},
            {Token::Kind::_if, "if"},
            {Token::Kind::eq, "=="},
            {Token::Kind::reset, "reset"},
            {Token::Kind::comment, "//"}};

} // namespace qasm
