/* =====================================
 * Generated by Mod-c 0.26.5
 * MODULE parser_common
 * ===================================== */

#include "parser_common.h"

void parser_common(void);

/**
 * TMod-c
 * By M. Scott Reynolds
 * Date 28 March 2026
 *
 * parser_common.mc - Common routines used by parser, declaration, expression, and statement
 * 22 August 2026 - Conversion to .mc
 */
#include "Lexer.h"
#include "arena.h"
#include "dynbuf.h"
#include "stddef.h"
#include "stdio.h"
#include "stdlib.h"
/**
 * One user TYPE name registered for sizeof() disambiguation at parse time.
 * Points into the source buffer (case-sensitive spelling).
 */
size_t SIZE_PARSER_TYPE_NAME(void)
{
    /* return value captured before defers */
    size_t __ret_l44 = ((integer)sizeof(TParserTypeName));
    return __ret_l44;
}

/**
 * Parser state for recursive descent parsing.
 * Holds lexer state, current token, arena for AST nodes, and optional output buffer.
 */
/**
 * Advance to the next token (and print it if debug set show-tokens).
 */
void advance(pParser p)
{
    ((*p)).current = TLexer__next(&((*p)).lexer);
    if (((*p)).show_tokens)
    {
        TToken__print(&((*p)).current);
    }
}

/**
 * Advance to the next token (and print it if debug set show-tokens).
 */
void TParser__advance(TParser* p)
{
    ((*p)).current = TLexer__next(&((*p)).lexer);
    if (((*p)).show_tokens)
    {
        TToken__print(&((*p)).current);
    }
}

/**
 * Check if the current token matches kind without consuming it.
 */
bool check(pParser p, TokenKind kind)
{
    /* return value captured before defers */
    bool __ret_l100 = (((*p)).current).kind == kind;
    return __ret_l100;
}

/**
 * Check if the current token matches kind without consuming it.
 */
bool TParser__check(TParser* p, TokenKind kind)
{
    /* return value captured before defers */
    bool __ret_l109 = (((*p)).current).kind == kind;
    return __ret_l109;
}

/**
 * If current token matches, consume it and return true
 */
bool match(pParser p, TokenKind kind)
{
    if (check(p, kind))
    {
        advance(p);
        /* return value captured before defers */
        bool __ret_l120 = true;
        return __ret_l120;
    }
    /* return value captured before defers */
    bool __ret_l122 = false;
    return __ret_l122;
}

/**
 * If current token matches, consume it and return true
 */
bool TParser__match(TParser* p, TokenKind kind)
{
    if (TParser__check(&(*p), kind))
    {
        TParser__advance(&(*p));
        /* return value captured before defers */
        bool __ret_l133 = true;
        return __ret_l133;
    }
    /* return value captured before defers */
    bool __ret_l135 = false;
    return __ret_l135;
}

/**
 * Check if the current token is one of the comments.
 * Doc comments are processed into their own nodes.
 */
bool check_comment(pParser p)
{
    if (check(p, TOK_COMMENT_SINGLE) || check(p, TOK_COMMENT_MULTI) || check(p, TOK_COMMENT_PASCAL) || check(p, TOK_COMMENT))
    {
        /* return value captured before defers */
        bool __ret_l147 = true;
        return __ret_l147;
    }
    /* return value captured before defers */
    bool __ret_l149 = false;
    return __ret_l149;
}

/**
 * Check if the current token is one of the comments.
 * Doc comments are processed into their own nodes.
 */
bool TParser__check_comment(TParser* p)
{
    if (TParser__check(&(*p), TOK_COMMENT_SINGLE) || TParser__check(&(*p), TOK_COMMENT_MULTI) || TParser__check(&(*p), TOK_COMMENT_PASCAL) || TParser__check(&(*p), TOK_COMMENT))
    {
        /* return value captured before defers */
        bool __ret_l161 = true;
        return __ret_l161;
    }
    /* return value captured before defers */
    bool __ret_l163 = false;
    return __ret_l163;
}

/**
 * Match if one of the comment types
 */
bool match_comment(pParser p)
{
    if (check_comment(p))
    {
        advance(p);
        /* return value captured before defers */
        bool __ret_l174 = true;
        return __ret_l174;
    }
    /* return value captured before defers */
    bool __ret_l176 = false;
    return __ret_l176;
}

/**
 * Match if one of the comment types
 */
bool TParser__match_comment(TParser* p)
{
    if (TParser__check_comment(&(*p)))
    {
        TParser__advance(&(*p));
        /* return value captured before defers */
        bool __ret_l187 = true;
        return __ret_l187;
    }
    /* return value captured before defers */
    bool __ret_l189 = false;
    return __ret_l189;
}

/**
 * Return true if end-of-statement (EOS)
 */
bool checkEOS(pParser p)
{
    if (check(p, TOK_SEMICOLON) || check(p, TOK_NEWLINE) || check_comment(p))
    {
        /* return value captured before defers */
        bool __ret_l200 = true;
        return __ret_l200;
    }
    /* return value captured before defers */
    bool __ret_l202 = false;
    return __ret_l202;
}

/**
 * Return true if end-of-statement (EOS)
 */
bool TParser__checkEOS(TParser* p)
{
    if (TParser__check(&(*p), TOK_SEMICOLON) || TParser__check(&(*p), TOK_NEWLINE) || TParser__check_comment(&(*p)))
    {
        /* return value captured before defers */
        bool __ret_l213 = true;
        return __ret_l213;
    }
    /* return value captured before defers */
    bool __ret_l215 = false;
    return __ret_l215;
}

/**
 * Match end-of-statement (semicolon or newline)
 * Return true if either was consumed.
 * This allows comments to appear after a statement on the same line.
 */
bool matchEOS(pParser p)
{
    bool consumed = false;
    if (match(p, TOK_SEMICOLON))
    {
        consumed = true;
    }
    if (match(p, TOK_NEWLINE))
    {
        consumed = true;
    }
    while (check_comment(p))
    {
        {
            advance(p);
            consumed = true;
        }
    }
    /* return value captured before defers */
    bool __ret_l244 = consumed;
    return __ret_l244;
}

/**
 * Match end-of-statement (semicolon or newline)
 * Return true if either was consumed.
 * This allows comments to appear after a statement on the same line.
 */
bool TParser__matchEOS(TParser* p)
{
    bool consumed = false;
    if (TParser__match(&(*p), TOK_SEMICOLON))
    {
        consumed = true;
    }
    if (TParser__match(&(*p), TOK_NEWLINE))
    {
        consumed = true;
    }
    while (TParser__check_comment(&(*p)))
    {
        {
            TParser__advance(&(*p));
            consumed = true;
        }
    }
    /* return value captured before defers */
    bool __ret_l273 = consumed;
    return __ret_l273;
}

/**
 * Skip empty statements: blank lines, comments, etc.
 */
void skip_empty_statements(pParser p)
{
    while (check(p, TOK_NEWLINE) || check(p, TOK_SEMICOLON) || check_comment(p))
    {
        {
            advance(p);
        }
    }
}

/**
 * Skip empty statements: blank lines, comments, etc.
 */
void TParser__skip_empty_statements(TParser* p)
{
    while (TParser__check(&(*p), TOK_NEWLINE) || TParser__check(&(*p), TOK_SEMICOLON) || TParser__check_comment(&(*p)))
    {
        {
            TParser__advance(&(*p));
        }
    }
}

/**
 * Skip layout-only breaks between list items (newlines, comments).
 * Does not consume ';' - that remains a statement terminator.
 */
void skip_layout_breaks(pParser p)
{
    while (check(p, TOK_NEWLINE) || check_comment(p))
    {
        {
            advance(p);
        }
    }
}

/**
 * Skip layout-only breaks between list items (newlines, comments).
 * Does not consume ';' - that remains a statement terminator.
 */
void TParser__skip_layout_breaks(TParser* p)
{
    while (TParser__check(&(*p), TOK_NEWLINE) || TParser__check_comment(&(*p)))
    {
        {
            TParser__advance(&(*p));
        }
    }
}

/**
 * Check if current token is an assignment
 */
bool check_assignment(pParser p)
{
    if (check(p, TOK_COLON_EQ) || check(p, TOK_MUL_EQ) || check(p, TOK_DIV_EQ) || check(p, TOK_MOD_EQ) || check(p, TOK_ADD_EQ) || check(p, TOK_SUB_EQ) || check(p, TOK_LSHIFT_EQ) || check(p, TOK_RSHIFT_EQ) || check(p, TOK_AND_EQ) || check(p, TOK_OR_EQ) || check(p, TOK_BITWISE_NOT_EQ))
    {
        /* return value captured before defers */
        bool __ret_l341 = true;
        return __ret_l341;
    }
    /* return value captured before defers */
    bool __ret_l343 = false;
    return __ret_l343;
}

/**
 * Check if current token is an assignment
 */
bool TParser__check_assignment(TParser* p)
{
    if (TParser__check(&(*p), TOK_COLON_EQ) || TParser__check(&(*p), TOK_MUL_EQ) || TParser__check(&(*p), TOK_DIV_EQ) || TParser__check(&(*p), TOK_MOD_EQ) || TParser__check(&(*p), TOK_ADD_EQ) || TParser__check(&(*p), TOK_SUB_EQ) || TParser__check(&(*p), TOK_LSHIFT_EQ) || TParser__check(&(*p), TOK_RSHIFT_EQ) || TParser__check(&(*p), TOK_AND_EQ) || TParser__check(&(*p), TOK_OR_EQ) || TParser__check(&(*p), TOK_BITWISE_NOT_EQ))
    {
        /* return value captured before defers */
        bool __ret_l363 = true;
        return __ret_l363;
    }
    /* return value captured before defers */
    bool __ret_l365 = false;
    return __ret_l365;
}

/**
 * Report error. Fatal errors cause immediate program exit.
 */
void error_at(pParser p, const char* msg, bool fatal)
{
    if (fatal)
    {
        if ((((*p)).current).kind == TOK_ERROR && (((*p)).current).error_msg != nil)
        {
            fprintf(stderr, "FATAL ERROR: line %d col %d: %s\n", (((*p)).current).line, (((*p)).current).column, (((*p)).current).error_msg);
        }
        else
        {
            fprintf(stderr, "FATAL ERROR: line %d col %d: %s (got %s)\n", (((*p)).current).line, (((*p)).current).column, msg, TokenKind__string((((*p)).current).kind));
        }
        exit(1);
    }
    else
    {
        fprintf(stderr, "WARNING: line %d col %d: %s (got %s)\n", (((*p)).current).line, (((*p)).current).column, msg, TokenKind__string((((*p)).current).kind));
    }
}

/**
 * Report error. Fatal errors cause immediate program exit.
 */
void TParser__error_at(TParser* p, const char* msg, bool fatal)
{
    if (fatal)
    {
        if ((((*p)).current).kind == TOK_ERROR && (((*p)).current).error_msg != nil)
        {
            fprintf(stderr, "FATAL ERROR: line %d col %d: %s\n", (((*p)).current).line, (((*p)).current).column, (((*p)).current).error_msg);
        }
        else
        {
            fprintf(stderr, "FATAL ERROR: line %d col %d: %s (got %s)\n", (((*p)).current).line, (((*p)).current).column, msg, TokenKind__string((((*p)).current).kind));
        }
        exit(1);
    }
    else
    {
        fprintf(stderr, "WARNING: line %d col %d: %s (got %s)\n", (((*p)).current).line, (((*p)).current).column, msg, TokenKind__string((((*p)).current).kind));
    }
}

/**
 * Consume a token of the expected kind or report fata error.
 */
void consume(pParser p, TokenKind kind, const char* msg)
{
    skip_layout_breaks(p);
    if (!match(p, kind))
    {
        error_at(p, msg, true);
    }
}

/**
 * Consume a token of the expected kind or report fata error.
 */
void TParser__consume(TParser* p, TokenKind kind, const char* msg)
{
    TParser__skip_layout_breaks(&(*p));
    if (!TParser__match(&(*p), kind))
    {
        TParser__error_at(&(*p), msg, true);
    }
}

/**
 * Return true if we've reached the end of the input.
 */
bool isEOF(pParser p)
{
    /* return value captured before defers */
    bool __ret_l440 = check(p, TOK_EOF);
    return __ret_l440;
}

/**
 * Return true if we've reached the end of the input.
 */
bool TParser__isEOF(TParser* p)
{
    /* return value captured before defers */
    bool __ret_l449 = TParser__check(&(*p), TOK_EOF);
    return __ret_l449;
}


void parser_common(void)
{
}
