/* =====================================
 * Generated by Mod-c 0.26.5
 * HEADER declaration MODULE
 * ===================================== */

#ifndef MODC_MODULE_declaration_H
#define MODC_MODULE_declaration_H

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

#define nil ((void *)0)
#define NIL nil
typedef uint8_t byte;
typedef const char* string;
typedef int integer;
typedef unsigned int cardinal;
typedef float real;

/**
 * TMod-c
 * By M. Scott Reynolds
 * Date 30 July 2026
 *
 * Declaration parsing routines.
 */

/* === IMPORT === */
#include "arena.h"

/* === IMPORT === */
#include "node.h"

/* === IMPORT === */
#include "parser_common.h"

/* === IMPORT === */
#include "parser_main.h"

/* === IMPORT === */
#include "stddef.h"

/* === IMPORT === */
#include "stdio.h"

/* === IMPORT === */
#include "stdlib.h"

/* === IMPORT === */
#include "string.h"

/* === IMPORT === */
#include "Lexer.h"

/* === IMPORT === */
#include "ttype.h"

/* === TYPE EXPORT === */
typedef Node* pNode;

/* === PROC/FUNC EXPORT === */
pNode parse_item(pParser p, NodeKind node_kind);

/**
 * Apply grouped trailing type propagation for a comma list of items
 * under a single VAR / CONST / LET.
 *
 * This is a semantic rule (not a grammar rule) described in docs:
 *  - The rightmost explicit type propagates leftward to proceeding bare names.
 *  - An item with "=" but no ":" type is left with TYPE==NULL (for inference)
 *  - and does not block or reset propagation for names to its left.
 *  - A bare name (no ":" and no "=") with no pending type to its right is an error.
 *
 * Works for NODE_VAR_ITEM, NODE_CONST_ITEM, and NODE_LET_ITEM because they
 * alias the same struct layout in hte Node union, and parse_item always
 * writes the fields via the var_item member.
 */

/**
 * Parse VAR declaration (multi-item grouped trailing type)
 *
 * Uses apply_grouped_trailing_types() for the right-to-left type propagation rule.
 * See docs/langauge_report for the full semantic description.
 *
 * @param p         Parser state
 * @param exported  Whether EXPORT was seen before VAR
 * @param is_extern If the VAR has external definition (cannot also be static)
 * @param is_static If the VAR has static definition (cannot also be external)
 * @return          Parsed VAR_DECL node (exists on fatal error)
 */

/* === PROC/FUNC EXPORT === */
pNode parse_var_decl(pParser p, bool exported, bool is_extern, bool is_static);

/**
 * Parse CONST declaration (multi-item grouped trailing type)
 *
 * Uses apply_grouped_trailing_types() for the right-to-left type propagation rule.
 * See docs/langauge_report.md for the full semantic description.
 *
 * @param p         Parser state
 * @param exported  Whether EXPORT was seen before CONST
 * @return          Parsed CONST_DECL node (exists on fatal error)
 */

/* === PROC/FUNC EXPORT === */
pNode parse_const_decl(pParser p, bool exported);

/* === PROC/FUNC EXPORT === */
pNode parse_let_decl(pParser p, bool exported);

/**
 * Parses TYPE declarations (multi-item support per grammar)
 *
 * Grammar (simplified for phase 1):
 *  type-def = "TYPE" time-item { "," type-item } end-of-statement
 *  type-item = identifier "=" type-expression
 */

/* === PROC/FUNC EXPORT === */
pNode parse_type_decl(pParser p, bool exported);

/**
 * Parse EXTERN TYPE declaration
 * Grammar: "EXTERN" [ "EXPORT" ] "TYPE" identifier [ "=" type-expression ] EOS
 * Caller has already consumed EXTERN and optional EXPORT.
 */

/* === PROC/FUNC EXPORT === */
pNode parse_extern_type_decl(pParser p, bool exported);

/**
 * Parse a single parameter: identifer : type
 * Returns a NODE_PARAM node
 */

/* === PROC/FUNC EXPORT === */
pNode parse_param(pParser p);

/**
 * Parse optional parameter list: ( param, {, param } )
 * Returns nil if no opening '(' is present, otherwise returns a NODE_PARAM_LIST node.
 * The list node owns the dynamic array of parameters (allocated in arena).
 */

/* === PROC/FUNC EXPORT === */
pNode parse_param_list(pParser p);

/**
 * Parse PROCEDURE or FUNCTION declaration.
 * Grammar:
 *      method-prototype = [ "RECURSIVE" ] ( "PROCEDURE" | "FUNCTION" )
 *          qualified-method_name formal_parameters EOS ;
 *      qualified-method-name = type-identifier "::" identifier | identifier ;
 *
 * Instance methods pass self as the first formal parameter, e.g.
 *  function Counter::get(self: Counter): integer
 *
 * Returns NODE_PROC_DECL or NODE_FUNC_DECL.
 * Exits on fatal error.
 */

/* === PROC/FUNC EXPORT === */
pNode parse_proc_or_func_decl(pParser p, bool exported, bool is_recursive, bool is_extern);

/**
 * Parse STRUCT type expression (RHS of TYPE declaration)
 * Grammar:
 *      struct-type = STRUCT [EXTENDS qualident]
 *          { field-decl EOS }
 *
 * Returns a NODE_STRUCT_DECL node (is_union = false).
 */

/* === PROC/FUNC EXPORT === */
pNode parse_struct_type(pParser p);

/**
 * Parse UNION type expression (RHS of TYPE declaration).
 * Grammar:
 *      union-type = UNION
 *          { field-decl EOS } 
 *
 * Returns a NODE_STRUCT_DECL node with .is_union set to true
 */

/* === PROC/FUNC EXPORT === */
pNode parse_union_type(pParser p);

/**
 * Parse a method type (PROCEDURE or FUNCTION siangature unsed as a type).
 * Grammar:
 *      method-type = ( "PROCEDRE" | "FUNCTION" ) format_parameters
 *
 * This is used on the right-hand size of TYPE declarations, and can
 * also appear in parameter types and variable declarations.
 * 
 * Returns a NODE_METHOD_TYPE node.
 */

/* === PROC/FUNC EXPORT === */
pNode parse_method_type(pParser p);

/**
 * Parse one enum member: identifer [ "=" const-exprssion ]
 */

/**
 * Parse ENUM type epxression (RHOS of TYPE declaration).
 * Grammar: 
 *      enum-type = "ENUM" [ EOS ] enum-decl { "," enum-decl } [","] [ EOS ] "END" ;
 *      enum-decl = identifier [ "=" const-expression ] ;
 *
 * Returns NODE_ENUM_TYPE, Outer TYPE_DECL supplies the type name.
 */

/* === PROC/FUNC EXPORT === */
pNode parse_enum_type(pParser p);

void declaration(void);

#endif /* MODC_MODULE_declaration_H */
