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

#include "expression.h"

void expression(void);

/**
 * Mod-c
 * By M. Scott Reynolds
 * Date 20 July 2026
 *
 * expression.mc - Expression parsing routines.
 */
#include "parser_common.h"
#include "parser_main.h"
#include "arena.h"
#include "ttype.h"
#include "node.h"
#include "Lexer.h"
/**
 * Parse conditional
 */
Node* parse_conditional(pParser p)
{
    assert(p != nil); /* precondition */
    Node* cond = parse_logical_or(p);
    if (match(p, TOK_QUESTION))
    {
        Node* then_expr = nil;
        Node* else_expr = nil;
        Node* ternary = nil;
        then_expr = TParser__parse_expr(&(*p));
        consume(p, TOK_COLON, "parse_conditional: expected ':' after ternary then branch");
        else_expr = parse_conditional(p);
        ternary = node_create(((*p)).arena, NODE_TERNARY, ((*cond)).token);
        (((*ternary)).ternary).cond = cond;
        (((*ternary)).ternary).then_expr = then_expr;
        (((*ternary)).ternary).else_expr = else_expr;
        /* return value captured before defers */
        Node* __ret_l102 = ternary;
        return __ret_l102;
    }
    /* return value captured before defers */
    Node* __ret_l105 = cond;
    return __ret_l105;
}

/**
 * Parse logical OR
 */
Node* parse_logical_or(pParser p)
{
    assert(p != nil); /* precondition */
    Node* left = parse_logical_and(p);
    while (match(p, TOK_KEYWORD_OR))
    {
        {
            Node* right = nil;
            Node* binary = nil;
            right = parse_logical_and(p);
            if (right == nil)
            {
                error_at(p, "parse_logical_or: expected expression after OR", true);
            }
            binary = node_create(((*p)).arena, NODE_BINARY, ((*left)).token);
            (((*binary)).binary).left = left;
            (((*binary)).binary).right = right;
            (((*binary)).binary).op = TOK_KEYWORD_OR;
            left = binary;
        }
    }
    /* return value captured before defers */
    Node* __ret_l135 = left;
    return __ret_l135;
}

/**
 * Parse logical AND
 */
Node* parse_logical_and(pParser p)
{
    assert(p != nil); /* precondition */
    Node* left = parse_equality(p);
    while (match(p, TOK_KEYWORD_AND))
    {
        {
            Node* right = nil;
            Node* binary = nil;
            right = parse_equality(p);
            if (right == nil)
            {
                error_at(p, "parse_logical_and: expected expression after AND", true);
            }
            binary = node_create(((*p)).arena, NODE_BINARY, ((*left)).token);
            (((*binary)).binary).left = left;
            (((*binary)).binary).right = right;
            (((*binary)).binary).op = TOK_KEYWORD_AND;
            left = binary;
        }
    }
    /* return value captured before defers */
    Node* __ret_l165 = left;
    return __ret_l165;
}

/**
 * Parse equality
 */
Node* parse_equality(pParser p)
{
    assert(p != nil); /* precondition */
    Node* left = parse_relational(p);
    while (true)
    {
        {
            TokenKind op = (((*p)).current).kind;
            if (op == TOK_EQ_EQ || op == TOK_NOT_EQ)
            {
                Node* right = nil;
                Node* binary = nil;
                advance(p);
                right = parse_relational(p);
                if (right == nil)
                {
                    error_at(p, "parse_equality: expected expression after equality operator", true);
                }
                binary = node_create(((*p)).arena, NODE_BINARY, ((*left)).token);
                (((*binary)).binary).left = left;
                (((*binary)).binary).right = right;
                (((*binary)).binary).op = op;
                left = binary;
            }
            else
            {
                                /* INVARIANT (on loop exit) */
                break;
            }
        }
    }
    /* return value captured before defers */
    Node* __ret_l202 = left;
    return __ret_l202;
}

/**
 * Parse relational
 */
Node* parse_relational(pParser p)
{
    assert(p != nil); /* precondition */
    Node* left = parse_shift(p);
    while (true)
    {
        {
            TokenKind op = (((*p)).current).kind;
            if (op == TOK_LESS || op == TOK_LESS_EQ || op == TOK_GREATER || op == TOK_GREATER_EQ)
            {
                Node* right = nil;
                Node* binary = nil;
                advance(p);
                right = parse_shift(p);
                if (right == nil)
                {
                    error_at(p, "parse_relational: expected expression after relational operator", true);
                }
                binary = node_create(((*p)).arena, NODE_BINARY, ((*left)).token);
                (((*binary)).binary).left = left;
                (((*binary)).binary).right = right;
                (((*binary)).binary).op = op;
                left = binary;
            }
            else
            {
                                /* INVARIANT (on loop exit) */
                break;
            }
        }
    }
    /* return value captured before defers */
    Node* __ret_l241 = left;
    return __ret_l241;
}

/**
 * Parse shift
 */
Node* parse_shift(pParser p)
{
    assert(p != nil); /* precondition */
    Node* left = parse_additive(p);
    while (true)
    {
        {
            TokenKind op = (((*p)).current).kind;
            if (op == TOK_BITWISE_LSHIFT || op == TOK_BITWISE_RSHIFT)
            {
                Node* right = nil;
                Node* binary = nil;
                advance(p);
                right = parse_additive(p);
                if (right == nil)
                {
                    error_at(p, "parse_shift: expected expression after shift operator", true);
                }
                binary = node_create(((*p)).arena, NODE_BINARY, ((*left)).token);
                (((*binary)).binary).left = left;
                (((*binary)).binary).right = right;
                (((*binary)).binary).op = op;
                left = binary;
            }
            else
            {
                                /* INVARIANT (on loop exit) */
                break;
            }
        }
    }
    /* return value captured before defers */
    Node* __ret_l279 = left;
    return __ret_l279;
}

/**
 * Parse additive
 */
Node* parse_additive(pParser p)
{
    assert(p != nil); /* precondition */
    Node* left = parse_multiplicative(p);
    while (true)
    {
        {
            TokenKind op = (((*p)).current).kind;
            if (op == TOK_ADD || op == TOK_SUB || op == TOK_BITWISE_OR || op == TOK_KEYWORD_XOR)
            {
                Node* right = nil;
                Node* binary = nil;
                advance(p);
                right = parse_multiplicative(p);
                if (right == nil)
                {
                    error_at(p, "parse_additive: expected expression after additive operator", true);
                }
                binary = node_create(((*p)).arena, NODE_BINARY, ((*left)).token);
                (((*binary)).binary).left = left;
                (((*binary)).binary).right = right;
                (((*binary)).binary).op = op;
                left = binary;
            }
            else
            {
                                /* INVARIANT (on loop exit) */
                break;
            }
        }
    }
    /* return value captured before defers */
    Node* __ret_l317 = left;
    return __ret_l317;
}

/**
 * Parse multiplicative
 */
Node* parse_multiplicative(pParser p)
{
    assert(p != nil); /* precondition */
    Node* left = parse_power(p);
    while (true)
    {
        {
            TokenKind op = (((*p)).current).kind;
            if (op == TOK_MUL || op == TOK_DIV || op == TOK_MOD || op == TOK_KEYWORD_MOD || op == TOK_BITWISE_AND || op == TOK_KEYWORD_DIV)
            {
                Node* right = nil;
                Node* binary = nil;
                advance(p);
                right = parse_power(p);
                if (right == nil)
                {
                    error_at(p, "parse_multiplicative: expected expression after multiplicative", true);
                }
                binary = node_create(((*p)).arena, NODE_BINARY, ((*left)).token);
                (((*binary)).binary).left = left;
                (((*binary)).binary).right = right;
                (((*binary)).binary).op = op;
                left = binary;
            }
            else
            {
                                /* INVARIANT (on loop exit) */
                break;
            }
        }
    }
    /* return value captured before defers */
    Node* __ret_l357 = left;
    return __ret_l357;
}

/**
 * Parse Power
 */
Node* parse_power(pParser p)
{
    assert(p != nil); /* precondition */
    Node* left = parse_unary(p);
    if (match(p, TOK_POWER))
    {
        Node* right = parse_power(p);
        Node* binary = nil;
        if (right == nil)
        {
            error_at(p, "parse_power: expected expression after **", true);
        }
        binary = node_create(((*p)).arena, NODE_BINARY, ((*left)).token);
        (((*binary)).binary).left = left;
        (((*binary)).binary).right = right;
        (((*binary)).binary).op = TOK_POWER;
        /* return value captured before defers */
        Node* __ret_l383 = binary;
        return __ret_l383;
    }
    /* return value captured before defers */
    Node* __ret_l386 = left;
    return __ret_l386;
}

/**
 * True when SIZEOF '(' should parse a type-specifier, not a designator.
 */
static bool parser_sizeof_operand_is_type(pParser p)
{
    assert(p != nil); /* precondition */
    if ((((*p)).current).kind == TOK_CARET || (((*p)).current).kind == TOK_KEYWORD_POINTER || (((*p)).current).kind == TOK_KEYWORD_CONST || (((*p)).current).kind == TOK_KEYWORD_ARRAY)
    {
        /* return value captured before defers */
        bool __ret_l401 = true;
        return __ret_l401;
    }
    if ((((*p)).current).kind == TOK_IDENT)
    {
        /* return value captured before defers */
        bool __ret_l404 = type_is_builtin_name((((*p)).current).start, (((*p)).current).length) || TParser__is_user_type_name(&(*p), (((*p)).current).start, (((*p)).current).length);
        return __ret_l404;
    }
    /* return value captured before defers */
    bool __ret_l407 = false;
    return __ret_l407;
}

/**
 * Parse SIZEOF expression
 * 	Grammar: "SIZEOF" "(" ( type-identifier | designator ) ")" 
 */
pNode parse_sizeof(pParser p)
{
    assert(p != nil); /* precondition */
    TToken tok = ((*p)).current;
    Node* n = nil;
    consume(p, TOK_KEYWORD_SIZEOF, "parse_sizeof: expected SIZEOF");
    consume(p, TOK_LPAREN, "parse_sizeof: expected '(' afer SIZEOF");
    n = node_create(((*p)).arena, NODE_SIZEOF, tok);
    if (parser_sizeof_operand_is_type(p))
    {
        (((*n)).sizeof_expr).is_type = true;
        ((((*n)).sizeof_expr).target).sizeof_type = TParser__parse_return_type(&(*p));
    }
    else
    {
        Node* designator = TParser__parse_designator(&(*p));
        if (designator == nil)
        {
            error_at(p, "parse_sizeof: expected type or designator inside SIZEOF", true);
        }
        (((*n)).sizeof_expr).is_type = false;
        ((((*n)).sizeof_expr).target).designator = designator;
    }
    consume(p, TOK_RPAREN, "parse_sizeof: expected ')' after SIZEOF");
    /* return value captured before defers */
    pNode __ret_l440 = n;
    return __ret_l440;
}

/**
 * Parse INC / DEC as either statement or expression.
 * When used in expressions, the code generator will add protective
 * parentheses around compound forms to preserve precedence.
 *
 * Grammar (expression form):
 * 		inc-dec-expr = "INC" "(" designator [ "," expression ] ")"
 * 					 | "DEC" "(" designator [ "," expression ] ")"
 */
pNode parse_inc_dec_expr(pParser p)
{
    assert(p != nil); /* precondition */
    TToken tok = ((*p)).current;
    bool is_inc = match(p, TOK_KEYWORD_INC);
    Node* designator = nil;
    Node* step = nil;
    Node* n = nil;
    if (!is_inc)
    {
        consume(p, TOK_KEYWORD_DEC, "parse_inc_dec_expr: expected INC or DEC");
    }
    consume(p, TOK_LPAREN, "parse_inc_dec_expr: expected '(' after INC/DEC");
    designator = TParser__parse_designator(&(*p));
    if (designator == nil)
    {
        error_at(p, "parse_inc_dec_expr: expected designator in INC/DEC", true);
    }
    if (match(p, TOK_COMMA))
    {
        step = TParser__parse_expr(&(*p));
        if (step == nil)
        {
            error_at(p, "parse_inc_dec_expr: expected expression after comma in INC/DEC", true);
        }
    }
    consume(p, TOK_RPAREN, "parse_inc_dec_expr: expected ')' after INC/DEC arguments");
    n = node_create(((*p)).arena, (is_inc ? NODE_INC : NODE_DEC), tok);
    (((*n)).binary).left = designator;
    (((*n)).binary).right = step;
    (((*n)).binary).op = (is_inc ? TOK_ADD : TOK_SUB);
    /* return value captured before defers */
    pNode __ret_l488 = n;
    return __ret_l488;
}

/**
 * Parse unary
 */
Node* parse_unary(pParser p)
{
    assert(p != nil); /* precondition */
    TokenKind op = {0};
    skip_layout_breaks(p);
    op = (((*p)).current).kind;
    if (op == TOK_KEYWORD_SIZEOF)
    {
        /* return value captured before defers */
        Node* __ret_l507 = parse_sizeof(p);
        return __ret_l507;
    }
    if (op == TOK_KEYWORD_INC || op == TOK_KEYWORD_DEC)
    {
        /* return value captured before defers */
        Node* __ret_l512 = parse_inc_dec_expr(p);
        return __ret_l512;
    }
    if (op == TOK_NOT || op == TOK_SUB || op == TOK_ADD || op == TOK_KEYWORD_NOT || op == TOK_BITWISE_NOT || op == TOK_AT)
    {
        TToken tok = {0};
        Node* operand = nil;
        Node* unary = nil;
        tok = ((*p)).current;
        advance(p);
        operand = parse_unary(p);
        if (operand == nil)
        {
            error_at(p, "parse_unary: expected expression after unary operator", true);
        }
        unary = node_create(((*p)).arena, NODE_UNARY, tok);
        (((*unary)).unary).operand = operand;
        (((*unary)).unary).op = op;
        /* return value captured before defers */
        Node* __ret_l534 = unary;
        return __ret_l534;
    }
    /* return value captured before defers */
    Node* __ret_l537 = parse_cast(p);
    return __ret_l537;
}

/**
 * Parse cast expression
 * Grammar:
 * 	cast-expression = "CAST" "(" type-specifier "," expression ")"
 * 		| postfix-expression "AS" type-specifier 
 * 		| postfix-expression ;
 */
Node* parse_cast(pParser p)
{
    assert(p != nil); /* precondition */
    Node* expr = {0};
    if (match(p, TOK_KEYWORD_CAST))
    {
        TType* target = {0};
        Node* e = {0};
        Node* cast_node = {0};
        consume(p, TOK_LPAREN, "parse_cast: expected '(' after CAST");
        target = TParser__parse_parameter_type(&(*p));
        consume(p, TOK_COMMA, "parse_cast: expected ',' after type in CAST");
        e = TParser__parse_expr(&(*p));
        consume(p, TOK_RPAREN, "parse_cast: expected ')' after CAST expression");
        cast_node = node_create(((*p)).arena, NODE_CAST, ((*p)).current);
        (((*cast_node)).cast_expr).expr = e;
        (((*cast_node)).cast_expr).target_type = target;
        /* return value captured before defers */
        Node* __ret_l571 = cast_node;
        return __ret_l571;
    }
    expr = parse_postfix(p);
    if (expr == nil)
    {
        /* return value captured before defers */
        Node* __ret_l577 = nil;
        return __ret_l577;
    }
    if (match(p, TOK_KEYWORD_AS))
    {
        TType* target = {0};
        Node* cast_node = {0};
        target = TParser__parse_parameter_type(&(*p));
        cast_node = node_create(((*p)).arena, NODE_CAST, ((*expr)).token);
        (((*cast_node)).cast_expr).expr = expr;
        (((*cast_node)).cast_expr).target_type = target;
        /* return value captured before defers */
        Node* __ret_l590 = cast_node;
        return __ret_l590;
    }
    /* return value captured before defers */
    Node* __ret_l593 = expr;
    return __ret_l593;
}

/**
 * Parse comma-separated argument list into an existing NODE_CALL.
 * Caller must have already consumed '('.
 */
static void parse_call_arguments(pParser p, pNode call)
{
    assert(p != nil); /* precondition */
    while (!check(p, TOK_RPAREN) && !check(p, TOK_EOF))
    {
        {
            pNode arg = TParser__parse_expr(&(*p));
            if (arg == nil)
            {
                error_at(p, "parse_call_arguments: expected expression as function argument", true);
            }
            arena_append_ptr(((*p)).arena, (ppvoid)(&(((*call)).call).args), &(((*call)).call).argc, &(((*call)).call).arg_capacity, arg);
            if (!match(p, TOK_COMMA))
            {
                                /* INVARIANT (on loop exit) */
                break;
            }
        }
    }
    consume(p, TOK_RPAREN, "parse_call_arguments: expected ')' after function call arguments");
}

/**
 * Parse postfix
 */
pNode parse_postfix(pParser p)
{
    assert(p != nil); /* precondition */
    pNode expr = parse_primary(p);
    while (true)
    {
        {
            if (check(p, TOK_LPAREN))
            {
                if (((*expr)).kind == NODE_FIELD_ACCESS)
                {
                    pNode call = nil;
                    pNode recv = (((*expr)).field_access).record_;
                    call = node_create(((*p)).arena, NODE_CALL, ((*expr)).token);
                    (((*call)).call).name = (((*expr)).field_access).field_name;
                    (((*call)).call).name_len = (((*expr)).field_access).field_len;
                    (((*call)).call).method_owner = nil;
                    (((*call)).call).method_owner_len = 0;
                    (((*call)).call).receiver_expr = recv;
                    (((*call)).call).callee_expr = expr;
                    (((*call)).call).args = nil;
                    (((*call)).call).argc = 0;
                    (((*call)).call).arg_capacity = 0;
                    consume(p, TOK_LPAREN, "parse_postfix: expected '(' after method name");
                    parse_call_arguments(p, call);
                    expr = call;
                }
                else
                {
                    expr = parse_call(p, ((*expr)).token);
                }
            }
            else if (check(p, TOK_LBRACKET))
            {
                expr = parse_array_index(p, expr);
            }
            else if (match(p, TOK_DOT))
            {
                TToken field_tok = {0};
                pNode field_node = nil;
                if ((((*p)).current).kind != TOK_IDENT)
                {
                    error_at(p, "parse_postfix: expected identifier after '.'", true);
                }
                field_tok = ((*p)).current;
                advance(p);
                field_node = node_create(((*p)).arena, NODE_FIELD_ACCESS, field_tok);
                (((*field_node)).field_access).record_ = expr;
                (((*field_node)).field_access).field_name = (field_tok).start;
                (((*field_node)).field_access).field_len = (field_tok).length;
                expr = field_node;
            }
            else if (match(p, TOK_CARET))
            {
                pNode unary = node_create(((*p)).arena, NODE_UNARY, ((*p)).current);
                (((*unary)).unary).op = TOK_CARET;
                (((*unary)).unary).operand = expr;
                expr = unary;
            }
            else
            {
                                /* INVARIANT (on loop exit) */
                break;
            }
        }
    }
    /* return value captured before defers */
    pNode __ret_l699 = expr;
    return __ret_l699;
}

/**
 * Parse primary
 */
pNode parse_primary(pParser p)
{
    assert(p != nil); /* precondition */
    if (check(p, TOK_KEYWORD_SIZEOF))
    {
        /* return value captured before defers */
        pNode __ret_l712 = parse_sizeof(p);
        return __ret_l712;
    }
    if ((((*p)).current).kind == TOK_IDENT)
    {
        TToken ident_tok = ((*p)).current;
        pNode ident = nil;
        advance(p);
        if (check(p, TOK_COLON_COLON))
        {
            TToken method_tok = {0};
            pNode call = nil;
            advance(p);
            if ((((*p)).current).kind != TOK_IDENT)
            {
                error_at(p, "parse_primary: expected method name after '::'", true);
            }
            method_tok = ((*p)).current;
            advance(p);
            if (!check(p, TOK_LPAREN))
            {
                error_at(p, "parse_primary: expected '(' after qualified method name", true);
            }
            call = node_create(((*p)).arena, NODE_CALL, method_tok);
            (((*call)).call).name = (method_tok).start;
            (((*call)).call).name_len = (method_tok).length;
            (((*call)).call).method_owner = (ident_tok).start;
            (((*call)).call).method_owner_len = (ident_tok).length;
            (((*call)).call).receiver_expr = nil;
            (((*call)).call).callee_expr = nil;
            (((*call)).call).args = nil;
            (((*call)).call).argc = 0;
            (((*call)).call).arg_capacity = 0;
            consume(p, TOK_LPAREN, "parse_primary: expected '(' after qualified method name");
            parse_call_arguments(p, call);
            /* return value captured before defers */
            pNode __ret_l749 = call;
            return __ret_l749;
        }
        if (check(p, TOK_LPAREN))
        {
            /* return value captured before defers */
            pNode __ret_l753 = parse_call(p, ident_tok);
            return __ret_l753;
        }
        ident = node_create(((*p)).arena, NODE_IDENT, ident_tok);
        (((*ident)).ident).value = (ident_tok).start;
        (((*ident)).ident).length = (ident_tok).length;
        /* return value captured before defers */
        pNode __ret_l759 = ident;
        return __ret_l759;
    }
    else if ((((*p)).current).kind == TOK_STRING || (((*p)).current).kind == TOK_NUMBER || (((*p)).current).kind == TOK_CHAR)
    {
        pNode lit = node_create(((*p)).arena, NODE_LITERAL, ((*p)).current);
        (((*lit)).literal).value = (((*p)).current).start;
        (((*lit)).literal).length = (((*p)).current).length;
        advance(p);
        /* return value captured before defers */
        pNode __ret_l768 = lit;
        return __ret_l768;
    }
    else if (match(p, TOK_LPAREN))
    {
        pNode inner = TParser__parse_expr(&(*p));
        pNode paren = nil;
        if (inner == nil)
        {
            error_at(p, "parse_primary: expected expression inside parentheses", true);
        }
        consume(p, TOK_RPAREN, "parse_primary: expected ')' after parenthesized expression");
        paren = node_create(((*p)).arena, NODE_PAREN, ((*inner)).token);
        (((*paren)).paren).expr = inner;
        /* return value captured before defers */
        pNode __ret_l780 = paren;
        return __ret_l780;
    }
    if (check(p, TOK_LBRACE))
    {
        /* return value captured before defers */
        pNode __ret_l785 = parse_array_literal(p);
        return __ret_l785;
    }
    /* return value captured before defers */
    pNode __ret_l788 = nil;
    return __ret_l788;
}

/**
 * Parse call
 */
pNode parse_call(pParser p, TToken ident_token)
{
    assert(p != nil); /* precondition */
    pNode call = node_create(((*p)).arena, NODE_CALL, ident_token);
    (((*call)).call).name = (ident_token).start;
    (((*call)).call).name_len = (ident_token).length;
    (((*call)).call).method_owner = nil;
    (((*call)).call).method_owner_len = 0;
    (((*call)).call).receiver_expr = nil;
    (((*call)).call).callee_expr = nil;
    (((*call)).call).args = nil;
    (((*call)).call).argc = 0;
    (((*call)).call).arg_capacity = 0;
    consume(p, TOK_LPAREN, "parse_call: expected '(' after function name");
    parse_call_arguments(p, call);
    /* return value captured before defers */
    pNode __ret_l815 = call;
    return __ret_l815;
}

/**
 * Parse array literal: "{" expression { "," expression } [ "," ] "}" 
 * Returns NODE_ARRAY_LITERAL node.
 * Exits on fatal error (unbalanced braces, etc.).
 */
pNode parse_array_literal(pParser p)
{
    TToken open_token = ((*p)).current;
    pNode lit = nil;
    advance(p);
    lit = node_create(((*p)).arena, NODE_ARRAY_LITERAL, open_token);
    (((*lit)).array_literal).elements = nil;
    (((*lit)).array_literal).count = 0;
    (((*lit)).array_literal).capacity = 0;
    if (match(p, TOK_RBRACE))
    {
        /* return value captured before defers */
        pNode __ret_l837 = lit;
        return __ret_l837;
    }
    do
    {
        {
            pNode elem = TParser__parse_expr(&(*p));
            if (elem == nil)
            {
                                /* INVARIANT (on loop exit) */
                break;
            }
            arena_append_ptr(((*p)).arena, (ppvoid)(&(((*lit)).array_literal).elements), &(((*lit)).array_literal).count, &(((*lit)).array_literal).capacity, elem);
            match(p, TOK_COMMA);
        }
    }
    while (!(check(p, TOK_RBRACE) || isEOF(p)));
    consume(p, TOK_RBRACE, "parse_array_literal: expected '}' after array literal");
    /* return value captured before defers */
    pNode __ret_l858 = lit;
    return __ret_l858;
}

/**
 * Parse array indexing: left [ index ]
 */
pNode parse_array_index(pParser p, pNode left)
{
    TToken bracket = ((*p)).current;
    pNode index_expr = nil;
    pNode n = nil;
    advance(p);
    index_expr = TParser__parse_expr(&(*p));
    if (index_expr == nil)
    {
        error_at(p, "parse_array_index: expected index expression inside []", true);
    }
    consume(p, TOK_RBRACKET, "parse_array_index: expected ']' after array index");
    n = node_create(((*p)).arena, NODE_ARRAY_INDEX, bracket);
    (((*n)).array_index).array_ = left;
    (((*n)).array_index).index = index_expr;
    /* return value captured before defers */
    pNode __ret_l884 = n;
    return __ret_l884;
}


void expression(void)
{
}
