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>
 * 支持的格式示例：
 * <ul>
 *     <li>整数：123、0、45678</li>
 *     <li>小数：3.14、0.5、12.0</li>
 * </ul>
 * <p>
 * 生成的 Token 类型为 {@code NUMBER_LITERAL}。
 */
public class NumberTokenScanner extends AbstractTokenScanner {

    /**
     * 判断是否可以处理当前位置的字符。
     * <p>当字符为数字时，表示可能是数字字面量的起始。</p>
     *
     * @param c   当前字符
     * @param ctx 当前词法上下文
     * @return 如果为数字字符，则返回 true
     */
    @Override
    public boolean canHandle(char c, LexerContext ctx) {
        return Character.isDigit(c);
    }

    /**
     * 执行数字扫描逻辑。
     * <p>连续读取数字字符，允许出现一个小数点，用于识别整数或小数。</p>
     *
     * @param ctx  词法上下文
     * @param line 当前行号
     * @param col  当前列号
     * @return 表示数字字面量的 Token
     */
    @Override
    protected Token scanToken(LexerContext ctx, int line, int col) {
        StringBuilder sb = new StringBuilder();
        boolean hasDot = false;

        while (!ctx.isAtEnd()) {
            char c = ctx.peek();
            if (c == '.' && !hasDot) {
                hasDot = true;
                sb.append(ctx.advance());
            } else if (Character.isDigit(c)) {
                sb.append(ctx.advance());
            } else {
                break;
            }
        }

        return new Token(TokenType.NUMBER_LITERAL, sb.toString(), line, col);
    }
}
