/**
 * @file scanner.h
 * @brief Declares the line tokenizer.
 *
 * Ported from basicscanner.go. The scanner's own cursor state lives on the
 * runtime rather than in a separate struct -- the reference's BasicScanner holds
 * a back-pointer to the runtime and reaches through it for the token array
 * anyway, so a second object bought nothing.
 *
 * Its three keyword maps are gone: the token type for a name comes from the one
 * dispatch table in verbs.h.
 */

#ifndef _AKBASIC_SCANNER_H_
#define _AKBASIC_SCANNER_H_

#include <akerror.h>

#include <akbasic/runtime.h>

/** @brief Reset the scanner cursor. */
akerr_ErrorContext AKERR_NOIGNORE *akbasic_scanner_zero(akbasic_Runtime *obj);

/**
 * @brief Tokenize one source line into the active environment's token array.
 *
 * Returns the line as the scanner left it through `dest`: an integer literal in
 * token position 0 is consumed as a line number rather than emitted as a token,
 * and the line is rewritten to everything after it with leading spaces stripped.
 * The REPL depends on that rewrite, which is why the line comes back out.
 *
 * @param obj Object to initialize, inspect, or modify.
 * @param line Source line to scan.
 * @param dest Output destination for the possibly-rewritten line; may be NULL.
 * @param len Size of `dest`.
 */
akerr_ErrorContext AKERR_NOIGNORE *akbasic_scanner_scan(akbasic_Runtime *obj, const char *line, char *dest, size_t len);

#endif // _AKBASIC_SCANNER_H_
