infix
A JIT-Powered FFI Library for C
Loading...
Searching...
No Matches
Named Type Registry

APIs for defining, storing, and reusing complex types by name. More...

Collaboration diagram for Named Type Registry:

Functions

c23_nodiscard infix_registry_tinfix_registry_create (void)
 Creates a new, empty named type registry.
 
void infix_registry_destroy (infix_registry_t *)
 Destroys a type registry and frees all associated memory.
 
c23_nodiscard infix_status infix_register_types (infix_registry_t *, const char *)
 Parses a string of type definitions and adds them to a registry.
 

Detailed Description

APIs for defining, storing, and reusing complex types by name.

Function Documentation

◆ infix_register_types()

c23_nodiscard infix_status infix_register_types ( infix_registry_t registry,
const char *  definitions 
)

Parses a string of type definitions and adds them to a registry.

This is the primary way to populate a registry. Definitions are separated by semicolons. The parser supports forward declarations (@Name;) and out-of-order definitions, making it easy to define mutually recursive types.

Parameters
[in]registryThe registry to populate.
[in]definitionsA semicolon-separated string of definitions.
Returns
INFIX_SUCCESS on success, or an error code on failure.
const char* my_types =
"@Point = { x: double, y: double };" // Define a struct
"@Node;" // Forward-declare Node
"@List = { head: *@Node };" // Use the forward declaration
"@Node = { value: int, next: *@Node };" // Define the recursive struct
;
infix_registry_t * registry
Definition 008_registry_introspection.c:35
c23_nodiscard infix_status infix_register_types(infix_registry_t *, const char *)
Parses a string of type definitions and adds them to a registry.
Definition type_registry.c:460

This function uses a robust three-pass approach to handle complex dependencies, including out-of-order and mutually recursive definitions.

  • Pass 1 (Scan & Index): The entire definition string is scanned. The parser identifies every type name being defined (@Name = ...) or forward-declared (@Name;). It creates an entry for each name in the registry's hash table and stores a pointer to the start of its definition body, without parsing it yet. This pass ensures that all type names are known before any parsing begins.
  • Pass 2 (Parse & Copy): The function iterates through the definitions indexed in Pass 1. For each one, it calls the main signature parser (_infix_parse_type_internal) on the definition body to create a raw, unresolved infix_type graph. This graph is then deep-copied into the registry's permanent arena. At the end of this pass, every defined name has a corresponding (but still unresolved) type graph associated with it in the registry.
  • Pass 3 (Resolve & Layout): The function iterates through all the newly created types from Pass 2. For each one, it performs the "Resolve" and "Layout" stages. Because all type graphs now exist, any @Name reference encountered during resolution is guaranteed to find a corresponding entry in the registry, successfully connecting the graph.
Parameters
[in]registryThe registry to populate.
[in]definitionsA semicolon-separated string of definitions.
Returns
INFIX_SUCCESS on success, or an error code on failure.

◆ infix_registry_create()

c23_nodiscard infix_registry_t * infix_registry_create ( void  )

Creates a new, empty named type registry.

A registry acts as a dictionary for infix types, allowing you to define complex structs, unions, or aliases once and refer to them by name (e.g., @MyStruct) in any signature string. This is essential for managing complex, recursive, or mutually-dependent types.

Returns
A pointer to the new registry, or nullptr on allocation failure. The returned handle must be freed with infix_registry_destroy.

◆ infix_registry_destroy()

void infix_registry_destroy ( infix_registry_t registry)

Destroys a type registry and frees all associated memory.

This includes freeing the registry handle itself, its internal hash table, and all infix_type objects that were created as part of a definition.

Parameters
[in]registryThe registry to destroy. Safe to call with nullptr.

This includes freeing the registry handle itself and its internal arena, which in turn frees the hash table, all entry structs, and all canonical infix_type objects that were created as part of a type definition.

Parameters
[in]registryThe registry to destroy. Safe to call with nullptr.