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

INFIX_API INFIX_NODISCARD infix_registry_tinfix_registry_create (void)
 Creates a new, empty named type registry.
 
INFIX_API INFIX_NODISCARD infix_registry_tinfix_registry_clone (const infix_registry_t *)
 Creates a deep copy of an existing type registry.
 
INFIX_API void infix_registry_destroy (infix_registry_t *)
 Destroys a type registry and frees all associated memory.
 
INFIX_API INFIX_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()

INFIX_API INFIX_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:33
INFIX_API INFIX_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:522

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. Critically, if a forward declaration is found, a placeholder infix_type is created immediately to ensure subsequent lookups succeed.
  • Pass 2 (Parse & Copy): The function iterates through the definitions indexed in Pass 1. For each one, it calls the main signature parser to create a raw type graph. This graph is then copied into the registry's arena. If a placeholder already exists from Pass 1, the new definition is copied in-place over the placeholder to preserve existing pointers.
  • 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 (either fully defined or as valid placeholders), resolution succeeds for all recursive references.
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_clone()

INFIX_API INFIX_NODISCARD infix_registry_t * infix_registry_clone ( const infix_registry_t src)

Creates a deep copy of an existing type registry.

This copies all defined types and their dependency graphs into a new registry with its own arena. This is essential for thread safety in languages that spawn threads by cloning interpreter state (like Perl).

Parameters
[in]registryThe registry to clone.
Returns
A pointer to the new registry, or nullptr on failure.

Creates a deep copy of an existing type registry.

Parameters
srcThe source registry to clone.
Returns
A new registry containing deep copies of all types in 'src', or NULL on failure.

◆ infix_registry_create()

INFIX_API INFIX_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()

INFIX_API 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.