package org.jcnc.snow.compiler.lexer.scanners;

import org.jcnc.snow.compiler.lexer.core.LexerContext;
import org.jcnc.snow.compiler.lexer.token.Token;
import org.jcnc.snow.compiler.lexer.token.TokenType;

/**
 * 未知符号扫描器：兜底处理无法被其他扫描器识别的字符。
 * <p>
 * 用于捕捉非法或未定义的符号序列，生成 {@code UNKNOWN} 类型的 Token。
 * <p>
 * 它会连续读取一段既不是字母、数字、空白符，也不属于常规符号（如 ;、{、"、:、,、(、)、.、+、-、*）的字符序列。
 */
public class UnknownTokenScanner extends AbstractTokenScanner {

    /**
     * 始终返回 true，作为所有扫描器中的兜底处理器。
     * <p>当没有其他扫描器能够处理当前字符时，使用本扫描器。</p>
     *
     * @param c   当前字符
     * @param ctx 当前词法上下文
     * @return 总是返回 true
     */
    @Override
    public boolean canHandle(char c, LexerContext ctx) {
        return true;
    }

    /**
     * 扫描未知或非法的字符序列。
     * <p>跳过字母、数字、空白和已知符号，仅捕获无法识别的符号块。</p>
     *
     * @param ctx  词法上下文
     * @param line 当前行号
     * @param col  当前列号
     * @return {@code UNKNOWN} 类型的 Token，包含无法识别的字符内容
     */
    @Override
    protected Token scanToken(LexerContext ctx, int line, int col) {
        String lexeme = readWhile(ctx, c ->
                !Character.isLetterOrDigit(c) &&
                        !Character.isWhitespace(c) &&
                        c != ';' && c != '{' && c != '"' &&
                        ":,().+-*".indexOf(c) < 0
        );

        return new Token(TokenType.UNKNOWN, lexeme, line, col);
    }
}
