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

Type system and sandboxing primitives for x-lang. More...

#include "x-prim.h"
#include "x-alist.h"
#include "x-eval.h"
#include "x-heap.h"
#include "x-type.h"
#include <stddef.h>
#include <setjmp.h>
#include "x-token.h"
#include "x-type/char.h"
#include "x-type/comment.h"
#include "x-type/buffer.h"
#include "x-type/int.h"
#include "x-type/list.h"
#include "x-type/operative.h"
#include "x-type/prim.h"
#include "x-type/procedure.h"
#include "x-type/ptr.h"
#include "x-type/iter.h"
#include "x-type/str.h"
#include "x-type/symbol.h"
#include "x-type/whitespace.h"

Functions

x_obj_tx_prim_type_build_struct (x_obj_t *p_base, x_obj_t *p_name_atom, x_obj_t *p_handlers)
 Build a type struct from a handlers alist.
 
static x_obj_tx_prim_make_type (x_obj_t *p_base, x_obj_t *p_args)
 Create and register a runtime type.
 
static x_obj_tx_prim_make_instance (x_obj_t *p_base, x_obj_t *p_args)
 Create an instance of a runtime-defined type.
 
static x_obj_tx_prim_typep (x_obj_t *p_base, x_obj_t *p_args)
 Test whether an object's type matches a given handle.
 
static x_obj_tx_prim_type_of (x_obj_t *p_base, x_obj_t *p_args)
 Return the type handle (name atom) for an object.
 
static x_obj_tx_prim_type_set_shape (x_obj_t *p_base, x_obj_t *p_args)
 Declare a type's unit shape.
 
static x_obj_tx_prim_make_obj (x_obj_t *p_base, x_obj_t *p_args)
 Allocate a typed object with n slots, all initialized to NULL.
 
x_obj_tx_prim_op1 (x_obj_t *p_base, x_obj_t *p_args, x_obj_t *(*op)(x_obj_t *, x_obj_t *))
 
x_obj_tx_prim_type_register (x_obj_t *p_base, x_obj_t *p_args)
 Register all type-system and sandboxing primitives.
 

Detailed Description

Type system and sandboxing primitives for x-lang.

Provides runtime type creation (make-type), type introspection (type-of, type?, type-name), object allocation (make-obj, make-instance), sandboxed interpreter creation (make-base), cross-base evaluation (base-eval, base-bind), tokenization helpers (make-token-base, token-read-string, buffer-token), and iteration (iter). Slot access (obj ref / obj set!) is pure x-lang now: boot/data.x + boot/reflect.x implement it reflectively over tools/contract/obj-layout.x.

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

Function Documentation

◆ x_prim_make_instance()

static x_obj_t * x_prim_make_instance ( x_obj_t p_base,
x_obj_t p_args 
)
static

Create an instance of a runtime-defined type.

x-lang form:

(make-instance type-handle data)

Looks up the type by its handle atom in the base's type alist and allocates a pair-sized object of that type with p_data as its first slot.

Parameters
p_baseBase (execution context).
p_argsUnevaluated: (self type-handle data).
Returns
New typed instance, or NULL if the type handle is not found.

◆ x_prim_make_obj()

static x_obj_t * x_prim_make_obj ( x_obj_t p_base,
x_obj_t p_args 
)
static

Allocate a typed object with n slots, all initialized to NULL.

x-lang form:

(make-obj type-handle n)

Looks up the type by handle, allocates an object with n pointer-sized slots, and zero-fills all slots. Used for vector-like custom types.

Parameters
p_baseBase (execution context).
p_argsUnevaluated: (self type-handle n).
Returns
New object with n NULL slots, or NULL if type not found.
See also
x_prim_make_type

◆ x_prim_make_type()

static x_obj_t * x_prim_make_type ( x_obj_t p_base,
x_obj_t p_args 
)
static

Create and register a runtime type.

x-lang form:

(make-type name handlers-alist)

Duplicates the name string into an owned atom, builds the type struct from the handlers alist, and prepends it to the base's type alist.

Parameters
p_baseBase (execution context).
p_argsUnevaluated: (self name-string handlers-alist).
Returns
The type name atom (handle for type? / make-instance lookups).
See also
x_prim_type_build_struct

◆ x_prim_op1()

x_obj_t * x_prim_op1 ( x_obj_t p_base,
x_obj_t p_args,
x_obj_t *(*)(x_obj_t *, x_obj_t *)  op 
)

Evaluate one argument and pass it as a 1-element list to a type operation.

The argument list is built on the stack (no heap allocation), so these wrappers stay safe inside reader/tokenizer callbacks. C primitives receive unevaluated args, hence the explicit x_eargs before delegating.

Parameters
p_baseBase (execution context).
p_argsUnevaluated: (self obj).
opThe type operation to drive with the evaluated object.
Returns
Whatever the operation returns.

◆ x_prim_type_build_struct()

x_obj_t * x_prim_type_build_struct ( x_obj_t p_base,
x_obj_t p_name_atom,
x_obj_t p_handlers 
)

Build a type struct from a handlers alist.

Iterates a table of known handler field names (call, eval, write, display, length, analyse, delimit, read, error, from, to, units, free, mark, iter), looks each up in p_handlers via alist association, and populates the corresponding x_type_t slot.

Parameters
p_baseBase (execution context) used for symbol lookup and allocation.
p_name_atomAtom for the type name.
p_handlersAlist mapping handler name symbols to closures.
Returns
Heap-allocated type struct object.

◆ x_prim_type_of()

static x_obj_t * x_prim_type_of ( x_obj_t p_base,
x_obj_t p_args 
)
static

Return the type handle (name atom) for an object.

x-lang form:

(type-of obj)

Delegates to the C-level x_type_prim_type_name to retrieve the type's name atom, which serves as the canonical handle for type operations.

Parameters
p_baseBase (execution context).
p_argsUnevaluated: (self obj).
Returns
Type name atom, or NULL for nil/untyped objects.

◆ x_prim_type_register()

x_obj_t * x_prim_type_register ( x_obj_t p_base,
x_obj_t p_args 
)

Register all type-system and sandboxing primitives.

Binds: make-type, base-make-type, make-instance, make-obj, type?, type-of, buffer-token, make-token-base, make-base, base-eval, base-bind, token-read, token-read-string. ((iter new) is pure x-lang now: boot/reflect.x dispatches the type tree's iter handler over the layout contracts.) (obj-ref / obj-set! / type-name are pure x-lang now: boot/data.x + boot/reflect.x implement them reflectively over the layout contracts.) ((obj retag!) is pure x-lang too: boot/reflect.x writes the type header slot over the layout contract – retired from C by the #101 ruling.)

Parameters
p_baseBase (execution context) to bind primitives into.
p_argsUnused.
Returns
p_base.

◆ x_prim_type_set_shape()

static x_obj_t * x_prim_type_set_shape ( x_obj_t p_base,
x_obj_t p_args 
)
static

Declare a type's unit shape.

x-lang form:

(type set-shape! type count mask)
static void x_obj_t int count
Definition x-prim.h:57

Installs the pair form of the p_units slot: count keeps both of the bare form's meanings (fixed, or negative for dynamic-size), and mask gives each unit its kind – see X_TYPE_UNIT_REF.

The shape must be a STRUCTURAL pair, which is why this is a primitive at all: x builds list-pairs only, and the readers discriminate the two forms of the slot by x_obj_type_isspair() – one pointer comparison on a path the collector walks per object. A list-pair here would be read as a bare count, and the count would be the pair's first data word.

Parameters
p_baseBase (execution context).
p_argsUnevaluated: (self type count mask).
Returns
The type struct, or nil if it was nil.

◆ x_prim_typep()

static x_obj_t * x_prim_typep ( x_obj_t p_base,
x_obj_t p_args 
)
static

Test whether an object's type matches a given handle.

x-lang form:

(type? obj type-handle)

Compares the name atom pointer of the object's type against p_handle.

Parameters
p_baseBase (execution context).
p_argsUnevaluated: (self obj type-handle).
Returns
#t if the type matches, #f otherwise.