Hyperon C
Loading...
Searching...
No Matches
Hyperon Bindings for C

This documentation specifically covers the API for extending Hyperon with modules implemented in C as well as integrating Hyperon into a C project. For a more complete overview of Hyperon, you should look here: TODO: Where?

API Conventions

The HyperonC API is intended to be a light weight layer over the native Rust implementation, and is designed to impose as little runtime performance overhead as possible. It is not necessary to be familiar with Rust to use HyperonC, but it might clarify the paterns because some of the API semantics come directly from ownership and borrowing in Rust.

Object Lifecycle Pattern

When a Hyperon object is created through the creation function, it is given to you, the caller, by value. For example atom_sym() returns an atom_t struct. You own that atom_t and you must free it when it's no longer needed, using the corresponding free function; atom_free() in the case of atom_t.

// Create the atom
atom_t test_atom = atom_sym("test_atom");
// We need to free the atom because we own it
atom_free(test_atom);
void atom_free(atom_t atom)
Frees an atom and all associated resources.
atom_t atom_sym(const char *name)
Create a new Symbol atom with the specified name.
Represents an Atom of any type.

However, if you pass the object by value to another function, that function takes ownership and now you are no longer responsible for freeing the object. For example, atom_vec_push() takes an atom_t argument, passed by value. This means the passed atom is now owned by the vec, and it is the responsibility of the vec to free the atom.

// Create an empty vec (list container) for atoms
atom_vec_t test_vec = atom_vec_new();
// Create a test atom and push it into the vec
// Now the vec takes responsibility for the atom (ownership)
atom_t test_atom = atom_sym("test_atom");
atom_vec_push(&test_vec, test_atom);
// We still own the vec so we must free it
atom_vec_free(test_vec);
void atom_vec_free(struct atom_vec_t vec)
Frees a atom_vec_t
struct atom_vec_t atom_vec_new(void)
Creates a new empty atom_vec_t
void atom_vec_push(struct atom_vec_t *vec, atom_t atom)
Push the atom onto the end of the vec.
Contains a vector (list) of Atoms.
Definition hyperon.h:246

Some functions return pointers or smart pointers (structs with types ending in "ref_t") pointing to other objects. When working with a pointer or ref_t smart pointer, you must be cognizant of the life cycle of the referenced object. For example, atom_vec_get() returns an atom_ref_t to refer to an atom within the vec. That reference will become invalid if the atom_vec_t the pointer refers into is freed or changed in any way. The Rust borrow checker ensures these constraints are never violated, but in C you must take that responsibility yourself.

// Create a vec with an atom
atom_vec_t test_vec = atom_vec_new();
atom_vec_push(&test_vec, atom_sym("test_atom"));
// Borrow the atom back from the vec as a reference
atom_ref_t borrowed_atom = atom_vec_get(&test_vec, 0);
// Print the atom's text description
char buffer[64];
atom_to_str(&borrowed_atom, buffer, 64);
printf("atom = %s", buffer);
// We're done with the vec for some reason, so free it
atom_vec_free(test_vec);
// NO!!!! The atom that `borrowed_atom` points to was freed with the vec
//atom_t new_atom = atom_clone(&borrowed_atom);
uintptr_t atom_to_str(const atom_ref_t *atom, char *buf, uintptr_t buf_len)
Renders a human-readable text description of an atom.
atom_ref_t atom_vec_get(const struct atom_vec_t *vec, uintptr_t idx)
Access an atom at a specified index in a vec.
Refers to an Atom owned by another object.