These are the primitives to define effect handlers and yield operations. More...
Data Structures | |
struct | lh_optag_ |
Operation values. More... | |
struct | lh_operation |
Opereation defintion. More... | |
struct | lh_handlerdef |
Handler definition. More... | |
struct | yieldargs |
Structure to pass multiple arguments from a yield. More... | |
Macros | |
#define | lh_value_cstack_ptr(p) |
Convert a C stack pointer to an lh_value. | |
#define | lh_cstack_ptr_value(r, v) |
Convert an lh_value back to an adjusted C stack pointer. More... | |
#define | lh_value_yieldargs(y) |
Convert a yieldargs structure to a generic value. | |
#define | lh_yieldargs_value(r, v) |
Convert an lh_value back to a yieldargs structure. | |
#define | lh_effect_null |
Null effect. | |
#define | lh_op_null |
The null operation tag is used for the final operation struct in a list of operations. | |
Typedefs | |
typedef struct _lh_resume * | lh_resume |
A "resume" continuation. More... | |
typedef const char *const * | lh_effect |
Effect values. More... | |
typedef const struct lh_optag_ * | lh_optag |
Operation values. More... | |
typedef lh_value() | lh_opfun(lh_resume r, lh_value local, lh_value arg) |
Operation functions are called when that operation is yield ed to. | |
Enumerations | |
enum | lh_opkind { LH_OP_NULL, LH_OP_FORWARD, LH_OP_NORESUMEX, LH_OP_NORESUME, LH_OP_TAIL_NOOP, LH_OP_TAIL, LH_OP_SCOPED, LH_OP_GENERAL } |
Operation kinds. More... | |
Functions | |
lh_value | lh_handle (const lh_handlerdef *def, lh_value local, lh_actionfun *body, lh_value arg) |
Handle a particalur effect. More... | |
lh_value | lh_yield (lh_optag optag, lh_value arg) |
Yield an operation to the nearest enclosing handler. | |
lh_value | lh_yield_local (lh_optag optag) |
lh_yield_local yields to the first enclosing handler for operation optag and returns its local state. More... | |
lh_value | lh_scoped_resume (lh_resume r, lh_value local, lh_value res) |
Resume a continuation. More... | |
lh_value | lh_tail_resume (lh_resume r, lh_value local, lh_value res) |
Final resumption of a scoped continuation. More... | |
void | lh_release (lh_resume r) |
Explicitly release a first-class continuation without resuming. | |
lh_value | lh_call_resume (lh_resume r, lh_value local, lh_value res) |
Resume a first-class contiunation with a specified result. | |
lh_value | lh_release_resume (lh_resume r, lh_value local, lh_value res) |
Resume a first-class contiunation with a specified result. More... | |
void * | lh_cstack_ptr (lh_resume r, void *p) |
Adjust a C stack pointer. More... | |
lh_value | lh_yieldN (lh_optag optag, int argcount,...) |
Yield with multiple arguments. More... | |
const char * | lh_optag_name (lh_optag optag) |
Get the name of an operation tag. | |
const char * | lh_effect_name (lh_effect effect) |
Get the name of an effect tag. | |
These are the primitives to define effect handlers and yield operations.
struct lh_optag_ |
Operation values.
An operation is identified by an effect and index in that effect. There are defined automatically using LH_DEFINE_OPn
macros and can be referred to using LH_OPTAG(effect,opname)
.
Data Fields | ||
---|---|---|
lh_effect | effect | |
long | opidx |
struct lh_operation |
Opereation defintion.
An operation
has a kind, an identifying tag, and an associated operation function.
Data Fields | ||
---|---|---|
lh_opfun * | opfun |
The operation function; use NULL (with LH_OP_FORWARD) to have the operation forwarded to the next enclosing effect (i.e. a direct tail-resume with the same arguments). |
lh_opkind | opkind | Kind of the operation. |
lh_optag | optag | The identifying tag. |
struct lh_handlerdef |
Handler definition.
Data Fields | ||
---|---|---|
lh_effect | effect | The Effect being handled. |
lh_acquirefun * | local_acquire | Called when the local state needs to be acquired. Can be NULL. |
lh_releasefun * | local_release | Called when the local state is released. Can be NULL. |
const lh_operation * | operations |
Definitions of all handled operations ending with an operation with lh_opkind LH_OP_NULL . Can be NULL to handle no operations; Note: all operations must be in the same order here as in the effect definition! (since each operation has a fixed index). |
lh_resultfun * | resultfun | Invoked when the handled action is done; can be NULL in which case the action result is passed unchanged. |
struct yieldargs |
Structure to pass multiple arguments from a yield.
Data Fields | ||
---|---|---|
int | argcount | guaranteed to be >= 0 |
lh_value | args[1] |
allocated to contain argcount arguments |
#define lh_cstack_ptr_value | ( | r, | |
v | |||
) |
Convert an lh_value back to an adjusted C stack pointer.
The pointer is adjusted to now pointing into the heap allocated resumption. This can be used inside operation handlers but use with care.
typedef const char* const* lh_effect |
Effect values.
Operations are identified by a constant string pointer. They are compared by address though so they must be declared as static constants (using #LH_NEWOPTAG)
Operation values.
An operation is identified by an effect and index in that effect. There are defined automatically using LH_DEFINE_OPn
macros and can be referred to using LH_OPTAG(effect,opname)
.
typedef struct _lh_resume* lh_resume |
A "resume" continuation.
This is first-class, and can be stored in data structures etc, and can survive the scope of an operation function. It can be resumed through lh_resume() or lh_release_resume().
enum lh_opkind |
Operation kinds.
When defining the operations that a handler can handle, these are specified to make the handling of operations more efficient. If you are not sure, LH_OP_GENERAL is always safe to use :-) At this point LH_OP_TAIL and LH_OP_NORESUME are most efficient since they do not need to set up a jump point.
void* lh_cstack_ptr | ( | lh_resume | r, |
void * | p | ||
) |
Adjust a C stack pointer.
Inside an operation handler, adjust a pointer that was pointing to the C stack at capture time to point inside the now captured stack. This can be used to pass values by stack reference to operation handlers. Use with care.
lh_value lh_handle | ( | const lh_handlerdef * | def, |
lh_value | local, | ||
lh_actionfun * | body, | ||
lh_value | arg | ||
) |
Handle a particalur effect.
Handles operations yielded in body(arg)
with the given handler definition def
.
Resume a first-class contiunation with a specified result.
Also releases the continuation and it cannot be resumed again!
Resume a continuation.
Use this when not resuming in a tail position.
Final resumption of a scoped continuation.
Only call lh_tail_resume
as the last action of an operation function, i.e. it must occur in tail position of an operation function.
lh_yield_local
yields to the first enclosing handler for operation optag
and returns its local state.
This should be used with care as it violates the encapsulation principle but works well for implicit parameters and to reduce the number of explicit operations for many effects. Note, still forwards through effect handlers that use an lh_opfun
of NULL
, and, more precisely, returns the state for the innermost enclosing handler that does not have a NULL
operation.