x-engine-c v0.2.13
The C engine for x-lang
Loading...
Searching...
No Matches
x-obj.c File Reference

Implementation of the x-expr object system. More...

#include "x-base.h"

Functions

int x_obj_isnil (x_obj_t *p_base, x_obj_t *p_obj)
 
x_obj_tx_obj_alloc (x_obj_t *p_base, x_obj_t *p_type, x_obj_flag_t flags, size_t units)
 
x_obj_tx_obj_make_va (x_obj_t *p_base, x_obj_t *p_type, x_obj_flag_t flags, size_t units, va_list ap)
 
x_obj_tx_obj_make (x_obj_t *p_base, x_obj_t *p_type, x_obj_flag_t flags, size_t units,...)
 
void x_obj_free (x_obj_t *p_base, x_obj_t *p_obj)
 
x_obj_tx_obj_prim_type_name (x_obj_t *p_base, x_obj_t *p_args)
 
x_char_tx_obj_type_name (x_obj_t *p_base, x_obj_t *p_obj)
 
x_obj_tx_atom_prim_units (x_obj_t *p_base, x_obj_t *p_args)
 
x_obj_tx_pair_prim_units (x_obj_t *p_base, x_obj_t *p_args)
 
x_obj_tx_obj_prim_units (x_obj_t *p_base, x_obj_t *p_args)
 
x_int_t x_obj_units (x_obj_t *p_base, x_obj_t *p_obj)
 
x_obj_tx_atom_prim_length (x_obj_t *p_base, x_obj_t *p_args)
 
x_obj_tx_pair_prim_length (x_obj_t *p_base, x_obj_t *p_args)
 
x_obj_tx_obj_prim_length (x_obj_t *p_base, x_obj_t *p_args)
 
x_int_t x_obj_length (x_obj_t *p_base, x_obj_t *p_obj)
 
x_obj_tx_obj_push_field (x_obj_t *p_base, x_obj_t **p_field, x_obj_t *p_value, x_obj_flag_t flags)
 
x_obj_tx_obj_pop_field (x_obj_t *p_base, x_obj_t **p_field)
 
x_obj_tx_obj_push (x_obj_t *p_base, x_obj_t *p_args)
 
x_obj_tx_obj_pop (x_obj_t *p_base, x_obj_t *p_args)
 
void x_obj_error (x_obj_t *p_base, x_char_t *message, x_obj_t *p_obj)
 

Variables

x_satom_t x_type_atom_obj = x_obj_set(NULL, X_OBJ_FLAG_NONE, {.s = (x_char_t *)X_TYPE_ATOM_NAME})
 
x_satom_t x_type_pair_obj = x_obj_set(NULL, X_OBJ_FLAG_NONE, {.s = (x_char_t *)X_TYPE_PAIR_NAME})
 
x_satom_t x_type_units_atom_obj = x_obj_set(NULL, X_OBJ_FLAG_NONE, {.i = X_OBJ_UNITS_ATOM})
 
x_satom_t x_type_units_pair_obj = x_obj_set(NULL, X_OBJ_FLAG_NONE, {.i = X_OBJ_UNITS_PAIR})
 
x_satom_t x_type_length_atom_obj = x_obj_set(NULL, X_OBJ_FLAG_NONE, {.i = X_OBJ_LENGTH_ATOM})
 
x_satom_t x_type_length_pair_obj = x_obj_set(NULL, X_OBJ_FLAG_NONE, {.i = X_OBJ_LENGTH_PAIR})
 
x_satom_t x_true_obj = x_obj_set(NULL, X_OBJ_FLAG_NONE, {.s = (x_char_t *)X_OBJ_TRUE_TEXT})
 
x_satom_t x_false_obj = x_obj_set(NULL, X_OBJ_FLAG_NONE, {.s = (x_char_t *)X_OBJ_FALSE_TEXT})
 

Detailed Description

Implementation of the x-expr object system.

Defines the built-in static type and value objects and the routines for allocating, freeing, introspecting, and stack-manipulating objects. See x-obj.h for the object model and the primitive/wrapper function convention.

Author
Jon Ruttan (jonru.nosp@m.ttan.nosp@m.@gmai.nosp@m.l.co.nosp@m.m)

Function Documentation

◆ x_atom_prim_length()

x_obj_t * x_atom_prim_length ( x_obj_t p_base,
x_obj_t p_args 
)

Primitive: the logical length of an atom.

Parameters
p_baseBase (execution context; unused).
p_argsArgument pair (unused).
Returns
The static atom x_type_length_atom_obj (value X_OBJ_LENGTH_ATOM).

◆ x_atom_prim_units()

x_obj_t * x_atom_prim_units ( x_obj_t p_base,
x_obj_t p_args 
)

Primitive: the data-unit count of an atom.

Parameters
p_baseBase (execution context; unused).
p_argsArgument pair (unused).
Returns
The static atom x_type_units_atom_obj (value X_OBJ_UNITS_ATOM).

◆ x_obj_alloc()

x_obj_t * x_obj_alloc ( x_obj_t p_base,
x_obj_t p_type,
x_obj_flag_t  flags,
size_t  units 
)

Allocate an uninitialized object.

Allocates space for units data units plus the standard metadata header. When the base configures extra metadata units (see x_base_field_obj_meta_extra()), that many leading units are also reserved; the returned pointer is advanced past them and X_OBJ_FLAG_META is set so x_obj_free() can recover the original allocation. When X_HEAP is enabled the object is linked onto the base's heap chain (and, under X_PROFILE, the allocation counter is incremented). The type and flags slots are set; the data units are left uninitialized.

Parameters
p_baseBase (execution context), or NULL to allocate without a base.
p_typeThe type object to assign, or NULL.
flagsInitial object flags.
unitsNumber of data units to allocate.
Returns
The new object, or NULL on allocation failure when no full base is attached (scratch/fixture use: the caller owns the null-check). With a full base attached the failure does not return – the runtime does not null-check allocations, so this function reports through the embedder-armed message (when set) and stops the process instead of handing back a NULL that would surface as a SIGSEGV in whatever code was running.
Note
When the base arms an allocation ceiling (see x_base_field_alloc_limit()), reaching it makes this function report through the base error path and stop the process rather than allocate past it – the runaway-memory guard.

◆ x_obj_error()

void x_obj_error ( x_obj_t p_base,
x_char_t message,
x_obj_t p_obj 
)

Output an error message to stderr.

If the error hook is set in the base, delegates to it via a cast to void (*)(x_obj_t *, x_char_t *, x_obj_t *) – this differs from x_fn_t because error handlers take raw arguments (not a pair list). Otherwise, extracts the object's string text (if it is a static atom) and calls x_error().

Parameters
p_baseBase (execution context).
messageError message string.
p_objRelated object for context, or NULL.

◆ x_obj_free()

void x_obj_free ( x_obj_t p_base,
x_obj_t p_obj 
)

Free an object and any resources it owns.

If the object has X_OBJ_FLAG_OWN set, the allocation referenced by its first datum is freed first. When X_HEAP is enabled and X_OBJ_FLAG_META is set, the original allocation address is recovered by stepping back over the extra metadata units before freeing. This does not unlink the object from the heap chain – x_heap_sweep() relinks the chain around freed objects.

Parameters
p_baseBase (execution context; used to size extra metadata units).
p_objThe object to free.

◆ x_obj_isnil()

int x_obj_isnil ( x_obj_t p_base,
x_obj_t p_obj 
)

Test whether an object is nil.

nil is represented by a NULL object pointer. p_base is accepted for calling-convention uniformity but is not used.

Parameters
p_baseBase (execution context; unused).
p_objThe object to test.
Returns
Non-zero if p_obj is nil (NULL), zero otherwise.

◆ x_obj_length()

x_int_t x_obj_length ( x_obj_t p_base,
x_obj_t p_obj 
)

Get an object's logical length as an integer.

Builds the argument pair, calls x_obj_prim_length(), and unwraps the result.

Parameters
p_baseBase (execution context).
p_objThe object to inspect.
Returns
The logical length, defaulting to 0 when unknown.

◆ x_obj_make()

x_obj_t * x_obj_make ( x_obj_t p_base,
x_obj_t p_type,
x_obj_flag_t  flags,
size_t  units,
  ... 
)

Allocate an object and initialize its data units from varargs.

Variadic wrapper around x_obj_make_va(); the x_mksatom() and x_mkspair() macros build on it.

Parameters
p_baseBase (execution context), or NULL.
p_typeThe type object to assign, or NULL.
flagsInitial object flags.
unitsNumber of data units, followed by that many x_obj_t * args.
Returns
The new object, or NULL on allocation failure.

◆ x_obj_make_va()

x_obj_t * x_obj_make_va ( x_obj_t p_base,
x_obj_t p_type,
x_obj_flag_t  flags,
size_t  units,
va_list  ap 
)

Allocate an object and initialize its data units from a va_list.

Calls x_obj_alloc(), then assigns units consecutive data units from ap (each consumed as an x_obj_t *).

Parameters
p_baseBase (execution context), or NULL.
p_typeThe type object to assign, or NULL.
flagsInitial object flags.
unitsNumber of data units to allocate and initialize.
apVariable argument list supplying the data units.
Returns
The new object, or NULL on allocation failure.

◆ x_obj_pop()

x_obj_t * x_obj_pop ( x_obj_t p_base,
x_obj_t p_args 
)

Callable wrapper for x_obj_pop_field().

Follows the x_fn_t convention. p_args is (field-ptr) where field-ptr is an atom wrapping the x_obj_t ** field address.

Parameters
p_baseBase (execution context).
p_argsArgument pair whose first element wraps the field address.
Returns
The popped value.

◆ x_obj_pop_field()

x_obj_t * x_obj_pop_field ( x_obj_t p_base,
x_obj_t **  p_field 
)

Pop the head value from a pair-list stack.

Returns the current head (x_firstobj(*p_field)) and advances *p_field to its rest. The popped pair is not freed; under X_HEAP the collector reclaims it.

Parameters
p_baseBase (execution context; unused).
p_fieldAddress of the field to pop from (updated in place).
Returns
The former head value.

◆ x_obj_prim_length()

x_obj_t * x_obj_prim_length ( x_obj_t p_base,
x_obj_t p_args 
)

Primitive: dispatch an object's logical length by type.

Returns x_pair_prim_length() for pairs and x_atom_prim_length() for atoms or nil-typed objects; for other types the base's length hook (x_base_field_hook_length()) is consulted.

Parameters
p_baseBase (execution context).
p_argsPair list whose first element is the subject object.
Returns
An integer atom with the logical length, or NULL.

◆ x_obj_prim_type_name()

x_obj_t * x_obj_prim_type_name ( x_obj_t p_base,
x_obj_t p_args 
)

Primitive: resolve an object's type object.

Follows the x_fn_t convention: p_args is a pair whose first element is the object to inspect. Built-in atoms and pairs, and any object with a nil type slot, return their type slot directly; for other types the base's type-name hook (x_base_field_hook_type_name()) is consulted.

Parameters
p_baseBase (execution context).
p_argsPair list whose first element is the subject object.
Returns
The type object, or NULL if the subject is nil or no type is found.

◆ x_obj_prim_units()

x_obj_t * x_obj_prim_units ( x_obj_t p_base,
x_obj_t p_args 
)

Primitive: dispatch an object's data-unit count by type.

Returns x_pair_prim_units() for pairs and x_atom_prim_units() for atoms or nil-typed objects; for other types the base's units hook (x_base_field_hook_units()) is consulted.

Parameters
p_baseBase (execution context).
p_argsPair list whose first element is the subject object.
Returns
An integer atom with the unit count, or NULL.

◆ x_obj_push()

x_obj_t * x_obj_push ( x_obj_t p_base,
x_obj_t p_args 
)

Callable wrapper for x_obj_push_field().

Follows the x_fn_t convention. p_args is (field-ptr value [flags]) where field-ptr is an atom wrapping the x_obj_t ** field address, value is the object to push, and the optional third element is an integer atom of flags (default X_OBJ_FLAG_NONE).

Parameters
p_baseBase (execution context).
p_argsArgument pair list as described above.
Returns
The pushed value.

◆ x_obj_push_field()

x_obj_t * x_obj_push_field ( x_obj_t p_base,
x_obj_t **  p_field,
x_obj_t p_value,
x_obj_flag_t  flags 
)

Push a value onto a pair-list stack.

Replaces *p_field with a new pair (p_value . old), so the field becomes a stack whose head is p_value. Used to save and restore base fields and to grow the heap hook/root lists.

Parameters
p_baseBase (execution context) for allocation.
p_fieldAddress of the field to push onto (updated in place).
p_valueThe value to push.
flagsFlags for the new pair.
Returns
The pushed value (p_value).

◆ x_obj_type_name()

x_char_t * x_obj_type_name ( x_obj_t p_base,
x_obj_t p_obj 
)

Get an object's type name as a C string.

Builds the argument pair, calls x_obj_prim_type_name(), and unwraps the resulting type object's string value.

Parameters
p_baseBase (execution context).
p_objThe object to inspect.
Returns
The type-name string, or X_TYPE_NIL_NAME if the object has no resolvable type.

◆ x_obj_units()

x_int_t x_obj_units ( x_obj_t p_base,
x_obj_t p_obj 
)

Get an object's data-unit count as an integer.

Builds the argument pair, calls x_obj_prim_units(), and unwraps the result.

Parameters
p_baseBase (execution context).
p_objThe object to inspect.
Returns
The data-unit count, defaulting to X_OBJ_UNITS_ATOM when unknown.

◆ x_pair_prim_length()

x_obj_t * x_pair_prim_length ( x_obj_t p_base,
x_obj_t p_args 
)

Primitive: the logical length of a pair.

Parameters
p_baseBase (execution context; unused).
p_argsArgument pair (unused).
Returns
The static atom x_type_length_pair_obj (value X_OBJ_LENGTH_PAIR).

◆ x_pair_prim_units()

x_obj_t * x_pair_prim_units ( x_obj_t p_base,
x_obj_t p_args 
)

Primitive: the data-unit count of a pair.

Parameters
p_baseBase (execution context; unused).
p_argsArgument pair (unused).
Returns
The static atom x_type_units_pair_obj (value X_OBJ_UNITS_PAIR).

Variable Documentation

◆ x_false_obj

x_satom_t x_false_obj = x_obj_set(NULL, X_OBJ_FLAG_NONE, {.s = (x_char_t *)X_OBJ_FALSE_TEXT})

Canonical false atom (value X_OBJ_FALSE_TEXT).

◆ x_true_obj

Canonical true atom (value X_OBJ_TRUE_TEXT).

◆ x_type_atom_obj

x_satom_t x_type_atom_obj = x_obj_set(NULL, X_OBJ_FLAG_NONE, {.s = (x_char_t *)X_TYPE_ATOM_NAME})

Built-in static atom type; its value is the "ATOM" type-name string.

◆ x_type_length_atom_obj

x_satom_t x_type_length_atom_obj = x_obj_set(NULL, X_OBJ_FLAG_NONE, {.i = X_OBJ_LENGTH_ATOM})

Static atom holding the atom length, returned by x_atom_prim_length().

◆ x_type_length_pair_obj

x_satom_t x_type_length_pair_obj = x_obj_set(NULL, X_OBJ_FLAG_NONE, {.i = X_OBJ_LENGTH_PAIR})

Static atom holding the pair length, returned by x_pair_prim_length().

◆ x_type_pair_obj

x_satom_t x_type_pair_obj = x_obj_set(NULL, X_OBJ_FLAG_NONE, {.s = (x_char_t *)X_TYPE_PAIR_NAME})

Built-in static pair type; its value is the "PAIR" type-name string.

◆ x_type_units_atom_obj

x_satom_t x_type_units_atom_obj = x_obj_set(NULL, X_OBJ_FLAG_NONE, {.i = X_OBJ_UNITS_ATOM})

Static atom holding the atom data-unit count, returned by x_atom_prim_units().

◆ x_type_units_pair_obj

x_satom_t x_type_units_pair_obj = x_obj_set(NULL, X_OBJ_FLAG_NONE, {.i = X_OBJ_UNITS_PAIR})

Static atom holding the pair data-unit count, returned by x_pair_prim_units().