// parser.h -- DVX BASIC parser (recursive descent)
//
// Single-pass compiler: reads tokens from the lexer and emits
// p-code directly via the code generator. No AST. Forward
// references to SUBs/FUNCTIONs are resolved via backpatching.
//
// Embeddable: no DVX dependencies, pure C.

#ifndef DVXBASIC_PARSER_H
#define DVXBASIC_PARSER_H

#include "lexer.h"
#include "codegen.h"
#include "symtab.h"
#include "../runtime/vm.h"

#include <stdint.h>
#include <stdbool.h>

// ============================================================
// Parser state
// ============================================================

typedef struct {
    BasLexerT    lex;
    BasCodeGenT  cg;
    BasSymTabT   sym;
    char         error[1024];
    bool         hasError;
    int32_t      errorLine;
    int32_t      prevLine;      // line of the previous token (for error reporting)
    int32_t      lastUdtTypeId;  // index of last resolved UDT type from resolveTypeName
    int32_t      optionBase;         // default array lower bound (0 or 1)
    bool         optionCompareText;  // true = case-insensitive string comparison
    bool         optionExplicit;     // true = variables must be declared with DIM
    uint8_t      defType[26];        // default type per letter (A-Z), set by DEFINT etc.
    char         currentProc[BAS_MAX_TOKEN_LEN]; // name of current SUB/FUNCTION
    // Per-form init block tracking
    int32_t      formInitJmpAddr;    // code position of JMP to patch (-1 = none)
    int32_t      formInitCodeStart;  // code position where init block starts (-1 = none)
} BasParserT;

// ============================================================
// API
// ============================================================

// Initialize parser with source text.
void basParserInit(BasParserT *p, const char *source, int32_t sourceLen);

// Parse the entire source and generate p-code.
// Returns true on success, false on error (check p->error).
bool basParse(BasParserT *p);

// Build a module from the parsed code. Returns NULL on error.
// Caller owns the module and must free with basModuleFree().
BasModuleT *basParserBuildModule(BasParserT *p);

// Free parser resources.
void basParserFree(BasParserT *p);

#endif // DVXBASIC_PARSER_H
