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

Type struct construction, dispatch, and GC hooks for the type system. More...

#include "x-type.h"
#include "x-eval.h"
#include "x-heap.h"
#include "x-obj.h"
#include "x-type/prim.h"
#include "x-type/symbol.h"
#include "x-type/int.h"

Macros

#define nil   NULL
 
#define pair(X, Y)   (x_mkspair(p_base, X_OBJ_FLAG_NONE, (X), (Y)))
 
#define atom(X)   (x_mksatom(p_base, X_OBJ_FLAG_NONE, (X)))
 

Functions

x_obj_tx_type_struct_make (x_obj_t *p_base, struct x_type_t type)
 
x_obj_tx_type_save_units (x_obj_t *p_obj, x_int_t *buf, x_int_t n, const int *kinds, int nkinds)
 
x_obj_tx_type_save_default (x_obj_t *p_base, x_obj_t *p_args)
 The default save: the units the type's shape declares, each with the kind the shape's mask gives it (a bare count: all references). Args are already evaluated: (obj buf).
 
static x_obj_tx_type_ops_lookup (x_obj_t *p_base, x_obj_t *p_ops, x_obj_t *p_sym)
 
static int x_type_from_has (x_obj_t *p_base, x_obj_t *p_type, x_obj_t *p_name)
 
int x_type_op_try (x_obj_t *p_base, x_char_t *op, x_obj_t *p_a, x_obj_t *p_b, x_obj_t **pp_result)
 
x_obj_tx_type_struct_get (x_obj_t *p_base, x_obj_t *p_args)
 
x_obj_tx_type_prim_type_name (x_obj_t *p_base, x_obj_t *p_args)
 
x_int_t x_type_units_count (x_obj_t *p_units)
 
x_int_t x_type_units_mask (x_obj_t *p_units)
 
x_int_t x_type_units_described (x_obj_t *p_units)
 
int x_type_unit_kind (x_int_t mask, x_int_t i, x_int_t described)
 
x_obj_tx_type_prim_units (x_obj_t *p_base, x_obj_t *p_args)
 
x_obj_tx_type_prim_length (x_obj_t *p_base, x_obj_t *p_args)
 
x_obj_tx_type_heap_mark (x_obj_t *p_base, x_obj_t *p_obj, x_obj_flag_t flags)
 
void x_type_heap_free (x_obj_t *p_base, x_obj_t *p_obj)
 

Variables

x_satom_t x_type_save_default_prim = x_obj_set(x_type_atom_obj, X_OBJ_FLAG_NONE, { (x_obj_t *)&x_type_save_default })
 

Detailed Description

Type struct construction, dispatch, and GC hooks for the type system.

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

Macro Definition Documentation

◆ atom

#define atom (   X)    (x_mksatom(p_base, X_OBJ_FLAG_NONE, (X)))

◆ nil

#define nil   NULL

◆ pair

#define pair (   X,
 
)    (x_mkspair(p_base, X_OBJ_FLAG_NONE, (X), (Y)))

Function Documentation

◆ x_type_from_has()

static int x_type_from_has ( x_obj_t p_base,
x_obj_t p_type,
x_obj_t p_name 
)
static

◆ x_type_heap_free()

void x_type_heap_free ( x_obj_t p_base,
x_obj_t p_obj 
)

GC free hook for typed heap objects.

If the object's type has a free callback, invokes it to release type-specific resources before the heap cell is reclaimed.

Parameters
p_basex_obj_t* – Base (execution context)
p_objx_obj_t* – Object being freed

◆ x_type_heap_mark()

x_obj_t * x_type_heap_mark ( x_obj_t p_base,
x_obj_t p_obj,
x_obj_flag_t  flags 
)

GC mark hook for typed heap objects.

For child base objects (type == x_eval_obj), returns the data pointer so the GC traverses the base's pair tree. For custom types, calls the type's mark callback if present. Otherwise falls back to a generic N-slot traversal using the units count.

Parameters
p_basex_obj_t* – Base (execution context)
p_objx_obj_t* – Object being marked
flagsx_obj_flag_t – GC mark flags
Returns
x_obj_t* – Data pointer for base objects, or NULL

◆ x_type_op_try()

int x_type_op_try ( x_obj_t p_base,
x_char_t op,
x_obj_t p_a,
x_obj_t p_b,
x_obj_t **  pp_result 
)

Try generic-operator dispatch for a binary op; 1 if dispatched.

◆ x_type_ops_lookup()

static x_obj_t * x_type_ops_lookup ( x_obj_t p_base,
x_obj_t p_ops,
x_obj_t p_sym 
)
static

◆ x_type_prim_length()

x_obj_t * x_type_prim_length ( x_obj_t p_base,
x_obj_t p_args 
)

Return the length for an object. x-lang: (length obj)

Dispatches to pair or atom length primitives for built-in types. For custom types, calls the type's length hook function.

Parameters
p_basex_obj_t* – Base (execution context)
p_argsx_obj_t* – (object)
Returns
x_obj_t* – Integer length, or NULL

◆ x_type_prim_type_name()

x_obj_t * x_type_prim_type_name ( x_obj_t p_base,
x_obj_t p_args 
)

Return the type name for an object. x-lang: (type-name obj)

For stack atoms/pairs and untyped objects, returns the raw type pointer. For heap-typed objects, extracts the name from the type struct.

Parameters
p_basex_obj_t* – Base (execution context)
p_argsx_obj_t* – (object)
Returns
x_obj_t* – Type name object, or NULL

◆ x_type_prim_units()

x_obj_t * x_type_prim_units ( x_obj_t p_base,
x_obj_t p_args 
)

Return the unit count for an object. x-lang: (units obj)

Dispatches to pair or atom unit primitives for built-in types. For custom types, reads the type's units count.

Parameters
p_basex_obj_t* – Base (execution context)
p_argsx_obj_t* – (object)
Returns
x_obj_t* – Integer unit count, or NULL

◆ x_type_save_default()

x_obj_t * x_type_save_default ( x_obj_t p_base,
x_obj_t p_args 
)

The default save: the units the type's shape declares, each with the kind the shape's mask gives it (a bare count: all references). Args are already evaluated: (obj buf).

The default save handler: every unit the type's units shape declares.

◆ x_type_save_units()

x_obj_t * x_type_save_units ( x_obj_t p_obj,
x_int_t buf,
x_int_t  n,
const int *  kinds,
int  nkinds 
)

Write n at buf[0] and the units of p_obj as [kind][word] pairs after it, kinds from kinds (the last repeats); every C save handler's helper. Returns p_obj.

◆ x_type_struct_get()

x_obj_t * x_type_struct_get ( x_obj_t p_base,
x_obj_t p_args 
)

Retrieve or create a type struct by name.

First checks the type alist cache. On miss, calls the callable in rest of p_args to construct the type, then caches it in the type alist for future lookups.

Parameters
p_basex_obj_t* – Base (execution context)
p_argsx_obj_t* – (type-name . constructor-callable)
Returns
x_obj_t* – Type struct

◆ x_type_struct_make()

x_obj_t * x_type_struct_make ( x_obj_t p_base,
struct x_type_t  type 
)

Construct a type struct from a type descriptor.

Builds the canonical nested-pair structure that represents a type in the type alist: name-stack, data-stack, heap group (mark, make, free, clone, units, length), proc group (call, eval), cvt group (from, to), IO group (analyse, delimit, read, write, display, error), iter group, and ops group.

Parameters
p_basex_obj_t* – Base (execution context) (for allocation)
typestruct x_type_t – Type descriptor with all hook pointers
Returns
x_obj_t* – Newly allocated type struct (pair tree)

◆ x_type_unit_kind()

int x_type_unit_kind ( x_int_t  mask,
x_int_t  i,
x_int_t  described 
)

The kind of unit i.

Units at or past described take the kind of the last described unit. That is the repeat rule, and it is how a dynamic-size type says what its payload units are without a marker.

Parameters
maskx_int_t – The kind mask
ix_int_t – Unit index
describedx_int_t – Fields the mask describes
Returns
int – One of X_TYPE_UNIT_REF .. X_TYPE_UNIT_FOREIGN

◆ x_type_units_count()

x_int_t x_type_units_count ( x_obj_t p_units)

The declared unit count, from either form of a p_units slot.

A bare INT atom is the count itself; a pair is (count . mask) and the count is its first. Negative keeps its dynamic-size meaning in both.

Parameters
p_unitsx_obj_t* – A type's p_units slot, or NULL
Returns
x_int_t – The count, or 0 when the slot is unset

◆ x_type_units_described()

x_int_t x_type_units_described ( x_obj_t p_units)

How many leading units the mask describes before the repeat rule applies.

A fixed count describes exactly its own units. A dynamic count of -k describes the k leading units plus the kind of the payload that follows them – k + 1 fields – so a count of -1 with mask (ref, ref) covers slot 0 and the slot-0-many payload units after it, with no repeat marker.

Note that the slot-0-counted convention holds its length as a heap INTEGER OBJECT, so slot 0 is X_TYPE_UNIT_REF, not X_TYPE_UNIT_WORD – see the kind documentation in x-type.h.

Parameters
p_unitsx_obj_t* – A type's p_units slot, or NULL
Returns
x_int_t – Described field count, capped at the mask's capacity

◆ x_type_units_mask()

x_int_t x_type_units_mask ( x_obj_t p_units)

The per-unit kind mask, from either form of a p_units slot.

The bare-count form has no mask; 0 is the honest answer for it, since X_TYPE_UNIT_REF is 0 and "every unit a reference" is what a bare count has always meant.

Parameters
p_unitsx_obj_t* – A type's p_units slot, or NULL
Returns
x_int_t – The mask, or 0

Variable Documentation

◆ x_type_save_default_prim