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

#ifndef MODC_MODULE_semantic_H
#define MODC_MODULE_semantic_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;

/**
 * semantic.mc - Semantic analysis pass (phase 1: declaration collection).
 *
 * Walks the AST, builds scoped symbol tables, detects duplicate names.
 * Expression type-checking and const-expressions enforcement come later.
 */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/** Analysis context */

/* === TYPE EXPORT === */
typedef struct TSemanticContext TSemanticContext;
typedef struct TSemanticContext {
    Arena* arena;
    pTSymbolTable scope;
    const char* source_path;
    const char* for_var_name;
    size_t for_var_len;
    pNode enclosing_func;
} TSemanticContext;

/* === TYPE EXPORT === */
typedef TSemanticContext* pTSemanticContext;

/**
* Fatal semantic error with source location from the node's token.
*/

/* === PROC/FUNC EXPORT === */
void semantic_error_at(pNode n, const char* msg);

/**
 * Merge use-site qualifiers (^ / CONST) onto an already-resolved base type.
 */

/**
 * Resolve type TType tree to its concrete form; return a new TType copy.
 * at = AST node for error location (may be nil).
 */

/**
 * Resolve ty in place; sets ty^.resolved_type (idempotent).
 */

/**
 * Name equality (reuse enum style)
 */

/**
 * Struct body for a type name
 */

/**
 * Strip pointer layers (for ^Child formals later; harmless now)
 */

/**
 * Struct body of type 
 */

/**
 * By-value EXTENDS upcast distance.
 * Returns N >= 1 if *actual* may be used where *expected is required by
 * walking N synthetic ".base" members (option A layout).
 * Returns 0 if same type, not both named structs, pointer/array, or not an ancestor.
 */

/**
 * If expr's type exrends expected, record upcast_depth on *expr* for codegen.
 * Does not error on mismatch (assignability still soft elsewhere).
 */

/**
 * Pointer at the use type or its resolved_type. Do not chase first
 * (^Child would become Child).
 */

/**
 * Pointer-to-array (Oberon p[i] peel). Not array-of-pointer (^char[] argv).
 */

/**
 * Designator type
 */

/**
 * True if ty is a named type with the given spelling.
 */

/**
 * Everyday integer-ish names for thin binary/unary typing (not full promotion).
 */

/**
 * Thin expression typing (item 21a). Not full type-checking.
 * Returns a type descriptor or nil when unknown.
 * Prerequisite: semantic_resolve_expr has been run on n when idents/calls matter.
 */

/**
 * Find field => set base_depth
 * Returns true if found; out_depth = # of .base prefixes before field_name
 */

/**
 * Check extends clashes
 */

/**
 * Resolve field types inside a STRUCT ... END type body. 
 */

/**
 * Parse integer literal token (deciman / 0x hex); strip '_' separators.
 */

/**
 * Evaluate a compile-time integer expression.
 * Implementation lives in semantic_try_eval_const_expr
 */

/**
 * Try integer const-fold. true + out_val^ on success.
 * Non-integer CONST (strings, pointers, ...) return false -- not an error.
 */

/**
 * Register enum members as CONST symbols; set TYPE symbol_type.
 * Called from semantic_resolve_type_decls (Pass  1 1/2).
 */

/** 
 * Resolve param / return types inside PROCEDURE/FUNCTION method types.
 */

/**
 * Pass 1 1/2: resolve all top-level TYPE bodies; refresh sym^.symbol_type.
 */

/**
 * FOR control matches
 */

/**
 * If designator is rooted at a forma, return that NODE_PARAM; else nil.
 * Walks IDENT, FIELD_ACCESS, ARRAY_INDEX, and postfix ^ (unary CARET).
 */

/**
 * Forbid writes that violate parameter modes.
 * - CONST formal: no rebind and no mutation through the parameter.
 * - Non-VAR formal: no rebind of the binding (are name on LHS of :=).
 */

/**
 * Forbid FOR control write
 */

/** 
* Define one symbol in the current scope.
*/

/**
 * Define a symbol, or refine an existing IMPORT in the current scope.
 */

/**
 * Register one IMPORT item in the current scope (foreign / minimal symbol).
 */

/**
 * bind one .mh export into the current scope (listed import or 7a unit entry).
 */

/**
 * Register all names from an IMPORT ... FROM statement.
 * .mh paths: parse export table and register real symbol kinds.
 * .h paths: minimal SYM_KIND_IMPORT placeholders (unchanged).
 */

/**
 * Register a parameter list (NODE_PARAM_LIST or program_decl.params array).
 */

/**
 * Register one builtin type in the semantic prelude (global scop).
 */

/**
 * Install builtin types into the program/module global scope.
 * See docs/grammar.md - bool, byte, char, integer, cardinal, real, string.
 */

/**
 * True for literal spellings the parser still emits as NODE_IDENT.
 * Case-insensitive (Mod-c keyword rules). Remove when lexer owns NIL/TRUE/FALSE.
 */

/**
 * Resolve one identifier use.
 */

/**
 * Build linker name Type__method in arena storage.
 */

/**
 * Symtab registration name: Type__method for qualified decls, plan name otherwise.
 */

/**
 * True if decl is a Type:: method whose first formal type is the owner type
 * (instance method). Formal name is free (Oberon-style; need not be "self").
 * False => static / factory: no formals, or first formal type <> owner, or
 * not a type-qualified method. Poitner first formals are not instance in v1.
 */

/**
 * Type:: methods: instance vs static is determined by first formal type
 * (see semantic_method_is_instance). Both forms are legal at declaration;
 * resolve first formal type early so bad type names still fail here.
 */

/**
 * If ty names TYPE ... = PROCEDURE/FUNCTION ... return NODE_METHOD_TYPE (else nil).
 */

/**
 * semantic_field_type_on
 */

/**
 * semantic_sym_is_method_value
 */

/**
 * Resolve a call target (procedure/function) and its arguments.
 * Type::name uses method_owner from the parser.
 * obj.method (item 21): instance Type__method; receiver prepended in codegen.
 * obj.field: method-typed field call-through (Oberon: no auto-self); callee_expr
 * Ambiguity if both instance method and method-typed field share the name
 * Free name: PROC/FUNC/IMPORT, or VAR/PARAM/LET/CONST of method type.
 * Unresolved free names and Type::name are errors (0.26).
 */

/**
 * Resolve SIZEOF operand: validate type names; designators must not be types.
 */

/**
 * Walk an expression tree and resole identifier/call uses.
 */

/**
 * Register VAR / CONST / LET items from a declaration node.
 */

/**
 * Resolve uses in one statement (no declaration registration).
 */

/**
 * Walk block statements: register local VAR/CONST/LET; recurese into nested BEGIN blocks.
 */

/**
 * Analyze a statement body that may be a BLOCK or a single statement
 */

/* === PROC/FUNC EXPORT === */
void semantic_analyze_stmt_or_block(pTSemanticContext ctx, pNode n);

/**
 * Walk ELSIF chain o an IF node.
 */

/* === PROC/FUNC EXPORT === */
void semantic_resolve_elsif_chain(pTSemanticContext ctx, pNode elsif_node);

/**
 * Analyze a procedure or function body (params + locals in one scope).
 */

/**
 * Synthetic PROC/FUNC decl for this MODULE's entry (same formals as program_decl).
 * Codegen auto-& only looks at NODE_PROC_DECL / NODE_FUNC_DECL.
 */

/**
 * Analyze PROGRAM / MODULE unit
 */

/**
 * Register one top-level (or scope-level) declaration.
 */

/* === PROC/FUNC EXPORT === */
void semantic_register_decl(pTSemanticContext ctx, pNode decl);

/**
 * Entry point: analyze AST after parsing, before codegen.
 * Exits on error; returns normally on success.
 */

/* === PROC/FUNC EXPORT === */
void semantic_analyze(Arena* arena, pNode root, const char* source_path);

void semantic(void);

#endif /* MODC_MODULE_semantic_H */
