import { assert } from "../../assert.js";
import DataType from "./DataType.js";
import ParserError from "./ParserError.js";
import Token from "./Token.js";
import TokenType from "./TokenType.js";

const RX_IDENTIFIER_CHAR = /^[a-zA-Z0-9_]/;
/**
 * @readonly
 * @type {RegExp}
 */
export const RX_IDENTIFIER_FIRST_CHAR = /^[a-zA-Z_]/;

/**
 * Read C99 style IDENTIFIER token
 * @param {string} text
 * @param {number} cursor
 * @param {number} length
 * @returns {Token}
 */
export function readIdentifierToken(text, cursor, length) {
    assert.isString(text, 'text');
    assert.isNonNegativeInteger(cursor, 'cursor');
    assert.isNonNegativeInteger(length, 'length');

    let i = cursor;


    const firstChar = text.charAt(i);

    if (!RX_IDENTIFIER_FIRST_CHAR.test(firstChar)) {
        throw new ParserError(i, `Expected first character to match /${RX_IDENTIFIER_FIRST_CHAR.toString()}/, instead got '${firstChar}'`, text);
    }

    i++;

    for (; i < length; i++) {
        const char = text.charAt(i);

        if (!RX_IDENTIFIER_CHAR.test(char)) {
            break;
        }
    }

    const value = text.substring(cursor, i);

    return new Token(value, cursor, i, TokenType.Identifier, DataType.String);
}
