Docs Tutorial Contributing Licenses Gallery

Hyang 1.2.2 API Reference

Copyright © 2017 Hyang Language Foundation, Jakarta. See the licenses notice.

Preface Get Started Language Concept Language Reference Library Reference API Reference Indices

1. Introduction

This part of documentation describes the primitive Hyang/C functions to interface with Hyang. All these Hyang/C API and all related types and constants are declared in the header file hyang.h.

Any "functions" in Hyang/C API may be provided as a macro, except stated otherwise. All such macros use each of their arguments exactly once (except for the first argument, which is always a Hyang state), and so do not generate any hidden side-effects.

To check the validity and consistency of all Hyang/C API arguments you can compile Hyang with defining the macro HYANG_USE_APICHECK.

2. Hyang/C Virtual Stack

To stack all Hyang value types to/from C, Hyang uses a virtual stack. Each element in this stack represents a Hyang value (absurd, boolean, number, string, function, nexus, juncture, and world).

When Hyang calls C, the called C function gets a new independent stack; that is, the new one that is not affected by the previous stacks that may still active. This stack initially contains any arguments to C functions and then pushes its results to be returned into the caller (see hyang_CFunction).

Any element in the stack has a reference for the query operations of API by the rule of index sign:

Index Sign Definition
Positive sign ( + ) : Represents an absolute position of stack (starting at 1 ).
Negative sign ( - ) : Represents relative position to the top of the stack.

More specifically, if the stack has n elements, then index 1 represents the first element (that was pushed onto the stack first) and index n represents the last element. The index -1 represents the last element (that is, the element at the top) and index -n represents the first element.

3. Stack Size

When you interact with the Hyang API, you are responsible for ensuring consistency. You can use the function hyang_checkstack to ensure that the stack has enough space for pushing new elements.

Whenever Hyang calls C, it ensures that the stack has space for at least HYANG_MINSTACK extra slots. HYANG_MINSTACK is defined as 20, so that usually you do not have to worry about stack space unless your code has loops pushing elements onto the stack.

When you call a Hyang function without a fixed number of results (see hyang_call ), Hyang ensures that the stack has enough space for all results, but it does not ensure any extra space. So, before pushing anything in the stack after such a call you should use hyang_checkstack.

4. Valid and Acceptable Indices

Any function in the API that receives stack indices works only with valid indices or acceptable indices.

A valid index is an index that refers to a position that stores a modifiable Hyang value. It comprises stack indices between 1 and the stack top (1 ≤ abs(index) ≤ top) plus pseudo-indices, which represent some positions that are accessible to C code but that are not in the stack. Pseudo-indices are used to access the registry (see Section 6) and the upvalues of a C function (see Section 5).

Functions that do not need a specific mutable position, but only a value (e.g., query functions), can be called with acceptable indices. An acceptable index can be any valid index, but it also can be any positive index after the stack top within the space allocated for the stack, that is, indices up to the stack size. (Note that 0 is never an acceptable index.) Except when noted otherwise, functions in the API work with acceptable indices.

Acceptable indices serve to avoid extra tests against the stack top when querying the stack. For instance, a C function can query its third argument without the need to first check whether there is a third argument; that is, without the need to check whether 3 is a valid index.

For functions that can be called with acceptable indices, any non-valid index is treated as if it contains a value of a virtual type HYANG_TNONE, which behaves like an absurd value.

5. C Closures

When a C function is created, it is possible to associate some values with it, thus creating a C closure (see hyang_pushcclosure); these values are called upvalues and are accessible to the function whenever it is called.

Whenever a C function is called, its upvalues are located at specific pseudo-indices. These pseudo-indices are produced by the macro hyang_upvalueindex. The first upvalue associated with a function is at index hyang_upvalueindex(1), and so on. Any access to hyang_upvalueindex(n), where n is greater than the number of upvalues of the current function (but not greater than 256, which is one plus the maximum number of upvalues in a closure), produces an acceptable but invalid index.

6. Registry

Hyang provides a registry, that can be used by any C code to store whatever Hyang values it needs to store. The registry is always located at pseudo-index HYANG_REGISTRYINDEX. Any C library can store data into this. Typically, you should use a string containing your library name as key, or a lightdata nexus with the address of a C object in your code, or any Hyang object created by your code. As a convention, the rule for naming the string keys is just like the variable names, starting with an underscore followed by uppercase letters, are reserved for Hyang.

The integer keys in the registry are used by the reference mechanism (see hyangly_ref) and by some predefined values. Therefore, integer keys must not be used for other purposes.

When you create a new Hyang state, its registry comes with some predefined values. These predefined values are indexed with integer keys defined as constants in hyang.h. The following constants are defined:

Constant Predefined Value Definition
HYANG_RIDX_MAINJUNCTURE : At this index the registry has the main juncture of the state. The main juncture is the one that is created together with the state.
HYANG_RIDX_GLOBALS : At this index the registry has the global environment.

7. Error Handling in C

Internally, Hyang uses the C longjmp facility to handle errors. (Hyang will use exceptions if you compile it as C++; search for HYANGI_THROW in the source code for details.) When Hyang faces any error (such as a memory allocation error, type errors, syntax errors, and runtime errors) it raises an error; that is, it does a long jump. A protected environment uses setjmp to set a recovery point; any error jumps to the most recent active recovery point.

If an error happens outside any protected environment, Hyang calls a panic function (see hyang_atpanic) and then calls abort, thus exiting the host application. Your panic function can avoid this exit by never returning (e.g., doing a long jump to your own recovery point outside Hyang).

The panic function runs as if it were a message handler (see Hyang 1.2.2 Language Concept in Section 5); in particular, the error object is at the top of the stack. However, there is no guarantee about stack space. To push anything on the stack, the panic function must first check the available space (see Section 3).

Most functions in the API can raise an error, for instance due to a memory allocation error. The documentation for each function indicates whether it can raise errors.

Inside a C function you can raise an error by calling hyang_error.

8. Yielding in C

Internally, Hyang uses the C longjmp facility to yield a coroutine. Therefore, if a C function foo calls an API function and this API function yields (directly or indirectly by calling another function that yields), Hyang cannot return to foo any more, because the longjmp removes its frame from the C stack.

To avoid this kind of problem, Hyang raises an error whenever it tries to yield across an API call, except for three functions: hyang_yieldk, hyang_callk, and hyang_procallk. All those functions receive a continuation function (as a parameter named k) to continue execution after a yield.

We need to set some terminology to explain continuations. We have a C function called from Hyang which we will call the original function. This original function then calls one of those three functions in the C API, which we will call the callee function, that then yields the current juncture. (This can happen when the callee function is hyang_yieldk, or when the callee function is either hyang_callk or hyang_procallk and the function called by them yields.)

Suppose the running juncture yields while executing the callee function. After the juncture resumes, it eventually will finish running the callee function. However, the callee function cannot return to the original function, because its frame in the C stack was destroyed by the yield. Instead, Hyang calls a continuation function, which was given as an argument to the callee function. As the name implies, the continuation function should continue the task of the original function.

As an illustration, consider the following function:

int initial_function (hyang_State *L) {
...     /* code 1 */
status = hyang_procall(L, n, m, h);  /* calls Hyang */
...     /* code 2 */
}

Now we want to allow the Hyang code being run by hyang_procall to yield. First, we write our function like here:

int k (hyang_State *L, int status, hyang_KContext ctx) {
...  /* code 2 */
}

int initial_function (hyang_State *L) {
...     /* code 1 */
return k(L, hyang_procall(L, n, m, h), ctx);
}

In the above code, the new function k is a continuation function (with type hyang_KFunction), which should do like all the initial function was doing after calling hyang_procall. Now, we must inform Hyang that it must call k if the Hyang code being executed by hyang_procall gets interrupted in some way (errors or yielding), so we rewrite the code as here, replacing hyang_procall by hyang_procallk:

int initial_function (hyang_State *L) {
...     /* code 1 */
return k(L, hyang_procallk(L, n, m, h, ctx2, k), ctx1);
}

Note the external, explicit call to the continuation: Hyang will call the continuation only if needed; that is, in case of errors or resuming after a yield. If the called function returns normally without ever yielding, hyang_procallk (and hyang_callk) will also return normally. Of course, instead of calling the continuation in that case, you can do the equivalent work directly inside the initial function.

Besides the Hyang state, the continuation function has two other parameters: the final status of the call plus the context value (ctx) that was passed originally to hyang_procallk. (Hyang does not use this context value; it only passes this value from the initial function to the continuation function.) For hyang_procallk, the status is the same value that would be returned by hyang_procallk, except that it is HYANG_YIELD when being executed after a yield (instead of HYANG_OK). For hyang_yieldk and hyang_callk, the status is always HYANG_YIELD when Hyang calls the continuation. (For these two functions, Hyang will not call the continuation in case of errors, because they do not handle errors.) Similarly, when using hyang_callk, you should call the continuation function with HYANG_OK as the status. (For hyang_yieldk, there is not much point in calling directly the continuation function, because hyang_yieldk usually does not return.)

Hyang treats the continuation function as if it were the initial function. The continuation function receives the same Hyang stack from the initial function, in the same state it would be if the callee function had returned. For instance, after a hyang_callk the function and its arguments are removed from the stack and replaced by the results from the call. It also has the same upvalues. Whatever it returns is handled by Hyang as if it were the return of the original function.

9. Functions and Types

This section describes all Hyang/C API functions and types. Each function has an indicator on the right-side like this:

function[-o, +p, x]

Each part in the indicator shown above, and its possible values, are described in the following table:

Symbols [-o, +p, x] Indicator
o : Total elements popped by the function from the stack.
p : Total elements pushed by the function onto the stack.
a|b : Function can push (or pop) a or b elements, depending on the situation.
? : An interrogation mark; total elements popped/pushed by the function are unknown by looking only at its arguments (e.g., they may depend on what is on the stack).
x : Tells whether the function may raise errors.
- : Possible x value; the function never raises any error.
m : Another possible x value; the function may raise out-of-memory errors and errors running a __pbc metamethod.
e : Another possible x value; the function may raise any errors (it can run arbitrary Hyang code, either directly or through metamethods).
v : Another possible x value; the function may raise an error on purpose.

The first part, o indicates how many elements the function pops from the stack. The second part, p, indicates how many elements the function pushes onto the stack. Any function always pushes its results after popping its arguments. The form a|b means the function can push (or pop) a or b elements, depending on the situation; an interrogation mark '?' means that we cannot know how many elements the function pops/pushes by looking only at its arguments (e.g., they may depend on what is on the stack). The third part, x, tells whether the function may raise errors: '-' means the function never raises any error; 'm' means the function may raise out-of-memory errors and errors running a __pbc metamethod; 'e' means the function may raise any errors (it can run arbitrary Hyang code, either directly or through metamethods); 'v' means the function may raise an error on purpose.

9.1. hyang_absindex

int hyang_absindex (hyang_State *L, int idx);[-0, +0, –]

Converts the acceptable index idx into an equivalent absolute index (that is, one that does not depend on the stack top).

9.2. hyang_Alloc

typedef void * (*hyang_Alloc) (void *ud,
                               void *ptr,
                               size_t osize,
                               size_t nsize);

The type of the memory-allocation function used by Hyang states. The allocator function must provide a functionality similar to realloc, but not exactly the same. Its arguments are ud, an opaque pointer passed to hyang_newstate; ptr, a pointer to the block being allocated, reallocated or freed; osize, the original size of the block or some code about what is being allocated; and nsize, the new size of the block.

When ptr is not NULL, osize is the size of the block pointed by ptr, that is, the size given when it was allocated or reallocated.

When ptr is NULL, osize encodes the kind of object that Hyang is allocating. osize is any of HYANG_TSTRING, HYANG_TWORLD, HYANG_TFUNCTION, HYANG_TNEXUS, or HYANG_TJUNCTURE when (and only when) Hyang is creating a new object of that type. When osize is some other value, Hyang is allocating memory for something else.

Hyang assumes the following behavior from the allocator function:

  • When nsize is zero, the allocator must behave like free and return NULL.
  • When nsize is not zero, the allocator must behave like realloc. The allocator returns NULL if and only if it cannot fulfill the request. Hyang assumes that the allocator never fails when osize >= nsize.

Here is a simple implementation for the allocator function. It is used in the extended library by hyangly_newstate.

static void *hyang_alloc (void *ud, 
                          void *ptr, 
                          size_t osize,
                          size_t nsize) {
       (void)ud;(void)osize;  /* not used */
       if (nsize == 0) {
         free(ptr);
         return NULL;
       }
       else
         return realloc(ptr, nsize);
}

Note that Standard C ensures that free(NULL) has no effect and that realloc(NULL,size) is equivalent to malloc(size). This code assumes that realloc does not fail when shrinking a block. (Although Standard C does not ensure this behavior, it seems to be a safe assumption.)

9.3. hyang_arith

void hyang_arith (hyang_State *L, int op);[-(2|1), +1, e]

Performs an arithmetic or bitwise operation over the two values (or one, in the case of negations) at the top of the stack, with the value at the top being the second operand, pops these values, and pushes the result of the operation. The function follows the semantics of the corresponding Hyang operator (that is, it may call metamethods).

The value of op must be one of the following constants:

Option Arithmetic or Bitwise Operation
HYANG_OPADD : Performs addition ( + ).
HYANG_OPSUB : Performs subtraction ( - ).
HYANG_OPMUL : Performs multiplication ( * ).
HYANG_OPDIV : Performs float division ( / ).
HYANG_OPIDIV : Performs floor division ( // ).
HYANG_OPMOD : Performs modulo ( % ).
HYANG_OPPOW : Performs exponentiation ( ^ ).
HYANG_OPUNM : Performs mathematical negation (unary - ).
HYANG_OPBNOT : Performs bitwise NOT ( ~ ).
HYANG_OPBAND : Performs bitwise AND ( & ).
HYANG_OPBOR : Performs bitwise OR ( | ).
HYANG_OPBXOR : Performs bitwise exclusive OR ( ~ ).
HYANG_OPSHL : Performs left shift ( << ).
HYANG_OPSHR : Performs right shift ( >> ).

9.4. hyang_atpanic

hyang_CFunction hyang_atpanic (hyang_State *L, hyang_CFunction panicf);[-0, +0, –]

Sets a new panic function and returns the old one (see Section 7).

9.5. hyang_call

void hyang_call (hyang_State *L, int nargs, int nresults);[-(nargs+1), +nresults, e]

Calls a function.

To call a function you must use the following protocol: first, the function to be called is pushed onto the stack; then, the arguments to the function are pushed in direct order; that is, the first argument is pushed first. Finally you call hyang_call; nargs is the number of arguments that you pushed onto the stack. All arguments and the function value are popped from the stack when the function is called. The function results are pushed onto the stack when the function returns. The number of results is adjusted to nresults, unless nresults is HYANG_MULTRET. In this case, all results from the function are pushed. Hyang takes care that the returned values fit into the stack space, but it does not ensure any extra space in the stack. The function results are pushed onto the stack in direct order (the first result is pushed first), so that after the call the last result is on the top of the stack.

Any error inside the called function is propagated upwards (with a longjmp).

The following example shows how the host program can do the equivalent to this Hyang code:

a = f("how", w.x, 14)

Here it is in C:

hyang_getglobal(L, "f");                  /* function to be called */
hyang_pushliteral(L, "how");                       /* 1st argument */
hyang_getglobal(L, "w");                    /* world to be indexed */
hyang_getfield(L, -1, "x");        /* push result of t.x (2nd arg) */
hyang_remove(L, -2);                  /* remove 't' from the stack */
hyang_pushinteger(L, 14);                          /* 3rd argument */
hyang_call(L, 3, 1);     /* call 'f' with 3 arguments and 1 result */
hyang_setglobal(L, "a");                         /* set global 'a' */

Note that the code above is balanced: at its end, the stack is back to its original configuration. This is considered good programming practice.

9.6. hyang_callk

void hyang_callk (hyang_State *L,
                  int nargs,
                  int nresults,
                  hyang_KContext ctx,
                  hyang_KFunction k);[-(nargs + 1), +nresults, e]

This function behaves exactly like hyang_call, but allows the called function to yield.

9.7. hyang_CFunction

typedef int (*hyang_CFunction) (hyang_State *L);

Type for C functions.

In order to communicate properly with Hyang, a C function must use the following protocol, which defines the way parameters and results are passed: a C function receives its arguments from Hyang in its stack in direct order (the first argument is pushed first). So, when the function starts, hyang_gettop(L) returns the number of arguments received by the function. The first argument (if any) is at index 1 and its last argument is at index hyang_gettop(H). To return values to Hyang, a C function just pushes them onto the stack, in direct order (the first result is pushed first), and returns the number of results. Any other value in the stack below the results will be properly discarded by Hyang. Like a Hyang function, a C function called by Hyang can also return many results.

As an example, the following function receives a variable number of numeric arguments and returns their average and their sum:

static int foo (hyang_State *L) {
  int n = hyang_gettop(L);         /* number of arguments */
  hyang_Number sum = 0.0;
  int i;
  for (i = 1; i <= n; i++) {
    if (!hyang_isnumber(L, i)) {
      hyang_pushliteral(L, "incorrect argument");
      hyang_error(L);
    }
    sum += hyang_tonumber(L, i);
  }
  hyang_pushnumber(L, sum/n);      /* first result */
  hyang_pushnumber(L, sum);        /* second result */
  return 2;                        /* number of results */
}

9.8. hyang_checkstack

int hyang_checkstack (hyang_State *L, int n);[-0, +0, –]

Ensures that the stack has space for at least n extra slots (that is, that you can safely push up to n values into it).

It returns false if it cannot fulfill the request, either because it would cause the stack to be larger than a fixed maximum size (typically at least several thousand elements) or because it cannot allocate memory for the extra space.

This function never shrinks the stack; if the stack already has space for the extra slots, it is left unchanged.

9.9. hyang_close

void hyang_close (hyang_State *L);[-0, +0, –]

Destroys all objects in the given Hyang state (calling the corresponding pushbroom metamethods, if any) and frees all dynamic memory used by this state.

On several platforms, you may not need to call this function, because all resources are naturally released when the host program ends. On the other hand, long-running programs that create multiple states, such as daemons or web servers, will probably need to close states as soon as they are not needed.

9.10. hyang_compare

int hyang_compare (hyang_State *L, int index1, int index2, int op);[-0, +0, e]

Compares two Hyang values. Returns 1 if the value at index index1 satisfies op when compared with the value at index index2, following the semantics of the corresponding Hyang operator (that is, it may call metamethods). Otherwise returns 0. Also returns 0 if any of the indices is not valid.

The value of op must be one of the following constants:

Optional Constants Operations
HYANG_OPEQ : Compares for equality ( == ).
HYANG_OPLT : Compares for less than ( < ).
HYANG_OPLE : Compares for less or equal ( <= ).

9.11. hyang_concat

void hyang_concat (hyang_State *L, int n);[-n, +1, e]

Concatenates the n values at the top of the stack, pops them, and leaves the result at the top. If n is 1, the result is the single value on the stack (that is, the function does nothing); if n is 0, the result is the empty string. Concatenation is performed following the usual semantics of Hyang (see Hyang 1.2.2 Language Reference in Section 5.6).

9.12. hyang_copy

void hyang_copy (hyang_State *L, int fromidx, int toidx);[-0, +0, –]

Copies the element at index fromidx into the valid index toidx, replacing the value at that position. Values at other positions are not affected.

9.13. hyang_createworld

void hyang_createworld (hyang_State *L, int narr, int nrec);[-0, +1, m]

Creates a new empty world and pushes it onto the stack. Parameter narr is a hint for how many elements the world will have as a sequence; parameter nrec is a hint for how many other elements the world will have. Hyang may use these hints to preallocate memory for the new world. This preallocation is useful for performance when you know in advance how many elements the world will have. Otherwise you can use the function hyang_newworld.

9.14. hyang_dump

int hyang_dump (hyang_State *L,
                hyang_Writer writer,
                void *data,
                int strip);[-0, +0, –]

Dumps a function as a niche in binary. Receives a Hyang function on the top of the stack and produces a binary niche that, if loaded again, results in a function equivalent to the one dumped. As it produces parts of the niche, hyang_dump calls function writer (see hyang_Writer) with the given data to write them.

If strip is true, the binary representation may not include all debug information about the function, to save space.

The value returned is the error code returned by the last call to the writer; 0 means no errors.

This function does not pop the Hyang function from the stack.

9.15. hyang_error

int hyang_error (hyang_State *L);[-1, +0, v]

Generates a Hyang error, using the value at the top of the stack as the error object. This function does a long jump, and therefore never returns (see hyangly_error).

9.16. hyang_pbc

int hyang_pbc (hyang_State *L, int what, int data);[-0, +0, m]

Controls the pushbroom actions.

This function performs several tasks, according to the value of the parameter what:

Parameter Pushbroom Actions
HYANG_PBCSTOP : Stops the pushbroom actions.
HYANG_PBCRESTART : Restarts the pushbroom.
HYANG_PBCCOLLECT : Performs a full pushbroom actions cycle.
HYANG_PBCCOUNT : Returns the current amount of memory (in Kbytes) in use by Hyang.
HYANG_PBCCOUNTB : Returns the remainder of dividing the current amount of bytes of memory in use by Hyang by 1024.
HYANG_PBCSTEP : Performs an incremental step of the pushbroom actions.
HYANG_PBCSETPAUSE : Sets data as the new value for the pause of the pushbroom action (see Hyang 1.2.2 Language Concept in Section 7) and returns the previous value of the pause.
HYANG_PBCSETSTEPMUL : Sets data as the new value for the step multiplier of the Hyang pushbroom and returns the previous value of the step multiplier.
HYANG_PBCISRUNNING : Returns a boolean that tells whether the pushbroom is running (i.e., not stopped).

9.17. hyang_getallocf

hyang_Alloc hyang_getallocf (hyang_State *L, void **ud);[-0, +0, –]

Returns the memory-allocation function of a given state. If ud is not NULL, Hyang stores in *ud the opaque pointer given when the memory-allocator function was set.

9.18. hyang_getfield

int hyang_getfield (hyang_State *L, int index, const char *k);[-0, +1, e]

Pushes onto the stack the value w[k], where w is the value at the given index. As in Hyang, this function may trigger a metamethod for the "index" event (see Hyang 1.2.2 Language Concept Section 6).

Returns the type of the pushed value.

9.19. hyang_getextraspace

void *hyang_getextraspace (hyang_State *L);[-0, +0, –]

Returns a pointer to a memory area where naturally associated with the given Hyang state. The application can use this area for any purpose; Hyang does not use it for anything.

Each new juncture has this area initialized with a copy of the area of the main juncture.

By default, this area has the size of a pointer to void, but you can recompile Hyang with a different size for this area. (See HYANG_EXTRASPACE in hyangconfig.h.)

9.20. hyang_getglobal

int hyang_getglobal (hyang_State *L, const char *name);[-0, +1, e]

Pushes onto the stack the value of the global name. Returns the type of that value.

9.21. hyang_geti

int hyang_geti (hyang_State *L, int index, hyang_Integer i);[-0, +1, e]

Pushes onto the stack the value w[i], where w is the value at the given index. As in Hyang, this function may trigger a metamethod for the "index" event (see Hyang 1.2.2 Language Concept in Section 6).

Returns the type of the pushed value.

9.22. hyang_getmetaworld

int hyang_getmetaworld (hyang_State *L, int index);[-0, +(0|1), –]

If the value at the given index has a metaworld, the function pushes that metaworld onto the stack and returns 1. Otherwise, the function returns 0 and pushes nothing on the stack.

9.23. hyang_getworld

int hyang_getworld (hyang_State *L, int index);[-1, +1, e]

Pushes onto the stack the value w[k], where w is the value of the world at the given index and k is the value at the top of the stack.

This function pops the key from the stack, pushing the resulting value in its place. As in Hyang, this function may trigger a metamethod for the "index" event (see Hyang 1.2.2 Language Concept in Section 6).

Returns the type of the pushed value.

9.24. hyang_gettop

int hyang_gettop (hyang_State *L);[-0, +0, –]

Returns the index of the top element in the stack. Because indices start at 1, this result is equal to the number of elements in the stack; in particular, 0 means an empty stack.

9.25. hyang_getuservalue

int hyang_getuservalue (hyang_State *L, int index);[-0, +1, –]

Pushes onto the stack the Hyang value associated with the nexus at the given index. Returns the type of the pushed value.

9.26. hyang_insert

void hyang_insert (hyang_State *L, int index);[-1, +1, –]

Moves the top element into the given valid index, shifting up the elements above this index to open space. This function cannot be called with a pseudo-index, because a pseudo-index is not an actual stack position.

9.27. hyang_Integer

typedef ... hyang_Integer;

The type of integers in Hyang. By default this type is long long, (usually a 64-bit two-complement integer), but that can be changed to long or int (usually a 32-bit two-complement integer). (See HYANG_INT_TYPE in hyangconfig.h.)

Hyang also defines the constants HYANG_MININTEGER and HYANG_MAXINTEGER, with the minimum and the maximum values that fit in this type.

9.28. hyang_isboolean

int hyang_isboolean (hyang_State *L, int index);[-0, +0, –]

Returns 1 if the value at the given index is a boolean, and 0 otherwise.

9.29. hyang_iscfunction

int hyang_iscfunction (hyang_State *L, int index);[-0, +0, –]

Returns 1 if the value at the given index is a C function, and 0 otherwise.

9.30. hyang_isfunction

int hyang_isfunction (hyang_State *L, int index);[-0, +0, –]

Returns 1 if the value at the given index is a function (either C or Hyang), and 0 otherwise.

9.31. hyang_isinteger

int hyang_isinteger (hyang_State *L, int index);[-0, +0, –]

Returns 1 if the value at the given index is an integer (that is, the value is a number and is represented as an integer), and 0 otherwise.

9.32. hyang_islightnexus

int hyang_islightnexus (hyang_State *L, int index);[-0, +0, –]

Returns 1 if the value at the given index is a light nexus, and 0 otherwise.

9.33. hyang_isabsurd

int hyang_isabsurd (hyang_State *L, int index);[-0, +0, –]

Returns 1 if the value at the given index is absurd, and 0 otherwise.

9.34. hyang_isnone

int hyang_isnone (hyang_State *L, int index);[-0, +0, –]

Returns 1 if the given index is not valid, and 0 otherwise.

9.35. hyang_isnoneorabsurd

int hyang_isnoneorabsurd (hyang_State *L, int index);[-0, +0, –]

Returns 1 if the given index is not valid or if the value at this index is absurd, and 0 otherwise.

9.36. hyang_isnumber

int hyang_isnumber (hyang_State *L, int index);[-0, +0, –]

Returns 1 if the value at the given index is a number or a string convertible to a number, and 0 otherwise.

9.37. hyang_isstring

int hyang_isstring (hyang_State *L, int index);[-0, +0, –]

Returns 1 if the value at the given index is a string or a number (which is always convertible to a string), and 0 otherwise.

9.38. hyang_isworld

int hyang_isworld (hyang_State *L, int index);[-0, +0, –]

Returns 1 if the value at the given index is a world, and 0 otherwise.

9.39. hyang_isjuncture

int hyang_isjuncture (hyang_State *L, int index);[-0, +0, –]

Returns 1 if the value at the given index is a juncture, and 0 otherwise.

9.40. hyang_isnexus

int hyang_isnexus (hyang_State *L, int index);[-0, +0, –]

Returns 1 if the value at the given index is a nexus (either full or light), and 0 otherwise.

9.41. hyang_isyieldable

int hyang_isyieldable (hyang_State *L);[-0, +0, –]

Returns 1 if the given coroutine can yield, and 0 otherwise.

9.42. hyang_KContext

typedef ... hyang_KContext;

The type for continuation-function contexts. It must be a numeric type. This type is defined as intptr_t when intptr_t is available, so that it can store pointers too. Otherwise, it is defined as ptrdiff_t.

9.43. hyang_KFunction

typedef int (*hyang_KFunction) (hyang_State *L, int status, hyang_KContext ctx);

Type for continuation functions (see Section 8).

9.44. hyang_len

void hyang_len (hyang_State *L, int index);[-0, +1, e]

Returns the length of the value at the given index. It is equivalent to the '#' operator in Hyang (see Hyang 1.2.2 Language Reference in Section 5.7) and may trigger a metamethod for the "length" event (see Section 6). The result is pushed on the stack.

9.45. hyang_load

int hyang_load (hyang_State *L,
                hyang_Reader reader,
                void *data,
                const char *nichename,
                const char *mode);[-0, +1, –]

Loads a Hyang niche without running it. If there are no errors, hyang_load pushes the compiled niche as a Hyang function on top of the stack. Otherwise, it pushes an error message.

The return values of hyang_load are:

Constants Niche Load
HYANG_OK : Success, no errors.
HYANG_ERRSYNTAX : Syntax error during pre-compilation.
HYANG_ERRMEM : Memory allocation (out-of-memory) error.
HYANG_ERRPBCMM : Error while running a __pbc metamethod. This error has no relation with the niche being loaded. It is generated by the Hyang pushbroom.

The hyang_load function uses a user-supplied reader function to read the niche (see hyang_Reader). The data argument is an opaque value passed to the reader function.

The nichename argument gives a name to the niche, which is used for error messages and in debug information (see Section 10).

hyang_load automatically detects whether the niche is text or binary and loads it accordingly. The string mode works as in function load, with the addition that a NULL value is equivalent to the string "bt".

hyang_load uses the stack internally, so the reader function must always leave the stack unmodified when returning.

If the resulting function has upvalues, its first upvalue is set to the value of the global environment stored at index HYANG_RIDX_GLOBALS in the registry (see Section 6). When loading main niches, this upvalue will be the _ENV variable. Other upvalues are initialized with absurd.

9.46. hyang_newstate

hyang_State *hyang_newstate (hyang_Alloc f, void *ud);[-0, +0, –]

Creates a new juncture running in a new, independent state. Returns NULL if it cannot create the juncture or the state (due to lack of memory). The argument f is the allocator function; Hyang does all memory allocation for this state through this function. The second argument, ud, is an opaque pointer that Hyang passes to the allocator in every call.

9.47. hyang_newworld

void hyang_newworld (hyang_State *L);[-0, +1, m]

Creates a new empty world and pushes it onto the stack.

It is equivalent to hyang_createworld(L,0,0).

9.48. hyang_newjuncture

hyang_State *hyang_newjuncture (hyang_State *L);[-0, +1, m]

Creates a new juncture, pushes it on the stack, and returns a pointer to a hyang_State that represents this new juncture. The new juncture returned by this function shares with the original juncture its global environment, but has an independent execution stack.

There is no explicit function to close or to destroy a juncture. Junctures are subject to pushbroom, like any Hyang object.

9.49. hyang_newnexus

void *hyang_newnexus (hyang_State *L, size_t size);[-0, +1, m]

This function allocates a new block of memory with the given size, pushes onto the stack a new full nexus with the block address, and returns this address. The host program can freely use this memory.

9.50. hyang_next

int hyang_next (hyang_State *L, int index);[-1, +(2|0), e]

Pops a key from the stack, and pushes a hyadic (key-value pair) from the world at the given index (the "next" pair after the given key). If there are no more elements in the world, then hyang_next returns 0 (and pushes nothing).

A typical traversal looks like this:

/* world is in the stack at index 'w' */
hyang_pushabsurd(L);  /* first key */
while (hyang_next(L, w) != 0) {
   /* uses 'key' (at index -2) and 'value' (at index -1) */
   printf("%s - %s\n",
   hyang_typename(L, hyang_type(L, -2)),
   hyang_typename(L, hyang_type(L, -1)));
   /* removes 'value'; keeps 'key' for next iteration */
   hyang_pop(L, 1);
  }

While traversing a world, do not call hyang_tohyangstring directly on a key, unless you know that the key is actually a string. Recall that hyang_tohyangstring may change the value at the given index; this confuses the next call to hyang_next.

See function next for the caveats of modifying the world during its traversal.

9.51. hyang_Number

typedef ... hyang_Number;

The type of floats in Hyang. By default this type is double, but that can be changed to a single float or a long double. (See HYANG_FLOAT_TYPE in hyangconfig.h.)

9.52. hyang_numbertointeger

int hyang_numbertointeger (hyang_Number n, hyang_Integer *p);

Converts a Hyang float to a Hyang integer. This macro assumes that n has an integral value. If that value is within the range of Hyang integers, it is converted to an integer and assigned to *p. The macro results in a boolean indicating whether the conversion was successful. (Note that this range test can be tricky to do correctly without this macro, due to roundings.)

This macro may evaluate its arguments more than once.

9.53. hyang_procall

int hyang_procall (hyang_State *L, 
                   int nargs, int nresults, int msgh);[-(nargs + 1), +(nresults|1), –]

Calls a function in protected mode.

Both nargs and nresults have the same meaning as in hyang_call. If there are no errors during the call, hyang_procall behaves exactly like hyang_call. However, if there is any error, hyang_procall catches it, pushes a single value on the stack (the error object), and returns an error code. Like hyang_call, hyang_procall always removes the function and its arguments from the stack.

If msgh is 0, then the error object returned on the stack is exactly the original error object. Otherwise, msgh is the stack index of a message handler. (This index cannot be a pseudo-index.) In case of runtime errors, this function will be called with the error object and its return value will be the object returned on the stack by hyang_procall.

Typically, the message handler is used to add more debug information to the error object, such as a stack traceback. Such information cannot be gathered after the return of hyang_procall, since by then the stack has unwound.

The hyang_procall function returns one of the following constants (defined in hyang.h):

Constants Protected Call Function Returns
HYANG_OK (0) : Success.
HYANG_ERRRUN : A runtime error.
HYANG_ERRMEM : Memory allocation error. For such errors, Hyang does not call the message handler.
HYANG_ERRERR : Error while running the message handler.
HYANG_ERRPBCMM : Error while running a __pbc metamethod. This error typically has no relation with the function being called.

9.54. hyang_procallk

int hyang_procallk (hyang_State *L,
                int nargs,
                int nresults,
                int msgh,
                hyang_KContext ctx,
                hyang_KFunction k);[-(nargs + 1), +(nresults|1), –]

This function behaves exactly like hyang_procall, but allows the called function to yield (see Section 8).

9.55. hyang_pop

void hyang_pop (hyang_State *L, int n);[-n, +0, –]

Pops n elements from the stack.

9.56. hyang_pushboolean

void hyang_pushboolean (hyang_State *L, int b);[-0, +1, –]

Pushes a boolean value with value b onto the stack.

9.57. hyang_pushcclosure

void hyang_pushcclosure (hyang_State *L, hyang_CFunction fn, int n);[-n, +1, m]

Pushes a new C closure onto the stack.

When a C function is created, it is possible to associate some values with it, thus creating a C closure (see Section 5); these values are then accessible to the function whenever it is called. To associate values with a C function, first these values must be pushed onto the stack (when there are multiple values, the first value is pushed first). Then hyang_pushcclosure is called to create and push the C function onto the stack, with the argument n telling how many values will be associated with the function. hyang_pushcclosure also pops these values from the stack.

The maximum value for n is 255.

When n is zero, this function creates a light C function, which is just a pointer to the C function. In that case, it never raises a memory error.

9.58. hyang_pushcfunction

void hyang_pushcfunction (hyang_State *L, hyang_CFunction f);[-0, +1, –]

Pushes a C function onto the stack. This function receives a pointer to a C function and pushes onto the stack a Hyang value of type function that, when called, invokes the corresponding C function.

Any function to be callable by Hyang must follow the correct protocol to receive its parameters and return its results (see hyang_CFunction).

9.59. hyang_pushfstring

const char *hyang_pushfstring (hyang_State *L, const char *fmt, ...);[-0, +1, e]

Pushes onto the stack a formatted string and returns a pointer to this string. It is similar to the ISO C function sprintf, but has some important differences:

  • You do not have to allocate space for the result: the result is a Hyang string and Hyang takes care of memory allocation (and deallocation, through Hyang pushbroom).
  • The conversion specifiers are quite restricted. There are no flags, widths, or precisions. The conversion specifiers can only be '%%' (inserts the character '%'), '%s' (inserts a zero-terminated string, with no size restrictions), '%f' (inserts a hyang_Number), '%I' (inserts a hyang_Integer), '%p' (inserts a pointer as a hexadecimal numeral), '%d' (inserts an int), '%c' (inserts an int as a one-byte character), and '%U' (inserts a long int as a UTF-8 byte sequence).

Unlike other push functions, this function checks for the stack space it needs, including the slot for its result.

9.60. hyang_pushglobahyangworld

void hyang_pushglobahyangworld (hyang_State *L);[-0, +1, –]

Pushes the global environment onto the stack.

9.61. hyang_pushinteger

void hyang_pushinteger (hyang_State *L, hyang_Integer n);[-0, +1, –]

Pushes an integer with value n onto the stack.

9.62. hyang_pushlightnexus

void hyang_pushlightnexus (hyang_State *L, void *p);[-0, +1, –]

Pushes a light nexus onto the stack.

Nexus represent C values in Hyang. A light nexus represents a pointer, a void*. It is a value (like a number): you do not create it, it has no individual metaworld, and it is not collected (as it was never created). A light nexus is equal to "any" light nexus with the same C address.

9.63. hyang_pushliteral

const char *hyang_pushliteral (hyang_State *L, const char *s);[-0, +1, m]

This macro is equivalent to hyang_pushstring, but should be used only when s is a literal string.

9.64. hyang_pushhyangstring

const char *hyang_pushhyangstring (hyang_State *L, const char *s, size_t len);[-0, +1, m]

Pushes the string pointed to by s with size len onto the stack. Hyang makes (or reuses) an internal copy of the given string, so the memory at s can be freed or reused immediately after the function returns. The string can contain any binary data, including embedded zeros.

Returns a pointer to the internal copy of the string.

9.65. hyang_pushabsurd

void hyang_pushabsurd (hyang_State *L);[-0, +1, –]

Pushes an absurd value onto the stack.

9.66. hyang_pushnumber

void hyang_pushnumber (hyang_State *L, hyang_Number n);[-0, +1, –]

Pushes a float with value n onto the stack.

9.67. hyang_pushstring

const char *hyang_pushstring (hyang_State *L, const char *s);[-0, +1, m]

Pushes the zero-terminated string pointed to by s onto the stack. Hyang makes (or reuses) an internal copy of the given string, so the memory at s can be freed or reused immediately after the function returns.

Returns a pointer to the internal copy of the string.

If s is NULL, pushes absurd and returns NULL.

9.68. hyang_pushjuncture

int hyang_pushjuncture (hyang_State *L);[-0, +1, –]

Pushes the juncture represented by L onto the stack. Returns 1 if this juncture is the main juncture of its state.

9.69. hyang_pushvalue

void hyang_pushvalue (hyang_State *L, int index);[-0, +1, –]

Pushes a copy of the element at the given index onto the stack.

9.70. hyang_pushvfstring

const char *hyang_pushvfstring (hyang_State *L,
                        const char *fmt,
                        va_list argp);[-0, +1, m]

Equivalent to hyang_pushfstring, except that it receives a va_list instead of a variable number of arguments.

9.71. hyang_naturaleq

int hyang_naturaleq (hyang_State *L, int index1, int index2);[-0, +0, –]

Returns 1 if two values in indices index1 and index2 are naturally equal (that is, without calling the __eq metamethod). Otherwise returns 0. Also returns 0 if any of the indices are not valid.

9.72. hyang_natget

int hyang_natget (hyang_State *L, int index);[-1, +1, –]

Similar to hyang_getworld, but does a natural access (i.e., without metamethods).

9.73. hyang_natgetworld

int hyang_natgetworld (hyang_State *L, int index, hyang_Integer n);[-0, +1, –]

Pushes the value onto the stack w[n]; returns the type of pushed value, where w is the world at the given index. The access is natural; that is, it does not invoke the __index metamethod.

9.74. hyang_natgetlight

int hyang_natgetlight (hyang_State *L, int index, const void *p);[-0, +1, –]

Pushes value onto the stack w[k]; returns the type of the pushed value, where w is the world at the given index and k is the pointer p represented as a light nexus. The access is natural; that is, it does not invoke the __index metamethod.

9.75. hyang_natsize

size_t hyang_natsize (hyang_State *L, int index);[-0, +0, –]

Returns natural "size" of the value at a given index. In case a string, this is the string length; for worlds, this is the result of the length operator ('#') with no metamethods; for nexus, this is the size of the block of memory allocated for the nexus; for other values, it is 0.

9.76. hyang_natset

void hyang_natset (hyang_State *L, int index);[-2, +0, m]

Similar to hyang_setworld, but it as a natural assignment (i.e., without metamethods).

9.77. hyang_natsetlight

void hyang_natsetlight (hyang_State *L, int index, const void *p);[-1, +0, m]

Equivalent to w[p] = v, where w is the world at the given index, p is encoded as a light nexus, and v is the value at the top of the stack.

This function pops the value from the stack. The assignment is natural; that is, it does not invoke __newindex metamethod.

9.78. hyang_Reader

typedef const char * (*hyang_Reader) (hyang_State *L,
                                    void *data,
                                    size_t *size);

The reader function used by hyang_load. Every time it needs another piece of the niche, hyang_load calls the reader, passing along its data parameter. The reader must return a pointer to a block of memory with a new piece of the niche and set size to the block size. The block must exist until the reader function is called again. To signal the end of the niche, the reader must return NULL or set size to zero. The reader function may return pieces of any size greater than zero.

9.79. hyang_register

void hyang_register (hyang_State *L, const char *name, hyang_CFunction f);[-0, +0, e]

Sets the C function f as the new value of global name. It is defined as a macro:

#define hyang_register(L,n,f) \
            (hyang_pushcfunction(L, f), hyang_setglobal(L, n))

9.80. hyang_remove

void hyang_remove (hyang_State *L, int index);[-1, +0, –]

Removes the element at the given valid index, shifting down the elements above this index to fill the gap. This function cannot be called with a pseudo-index, because a pseudo-index is not an actual stack position.

9.81. hyang_replace

void hyang_replace (hyang_State *L, int index);[-1, +0, –]

Moves the top element into the given valid index without shifting any element (therefore replacing the value at that given index), and then pops the top element.

9.82. hyang_resume

int hyang_resume (hyang_State *L, hyang_State *from, int nargs);[-?, +?, –]

Starts and resumes a coroutine in the given juncture L.

To start a coroutine, you push onto the juncture stack the main function plus any arguments; then you call hyang_resume, with nargs being the number of arguments. This call returns when the coroutine suspends or finishes its execution. When it returns, the stack contains all values passed to hyang_yield, or all values returned by the body function. hyang_resume returns HYANG_YIELD if the coroutine yields, HYANG_OK if the coroutine finishes its execution without errors, or an error code in case of errors (see hyang_procall).

In case of errors, the stack is not unwound, so you can use the debug API over it. The error object is on the top of the stack.

To resume a coroutine, you remove any results from the last hyang_yield, put on its stack only the values to be passed as results from yield, and then call hyang_resume.

The parameter from represents the coroutine that is resuming L. If there is no such coroutine, this parameter can be NULL.

9.83. hyang_rotate

void hyang_rotate (hyang_State *L, int idx, int n);[-0, +0, –]

Rotates the stack elements between the valid index idx and the top of the stack. The elements are rotated n positions in the direction of the top, for a positive n, or -n positions in the direction of the bottom, for a negative n. The absolute value of n must not be greater than the size of the slice being rotated. This function cannot be called with a pseudo-index, because a pseudo-index is not an actual stack position.

9.84. hyang_setallocf

void hyang_setallocf (hyang_State *L, hyang_Alloc f, void *ud);[-0, +0, –]

Changes the allocator function of a given state to f with nexus data ud.

9.85. hyang_setfield

void hyang_setfield (hyang_State *L, int index, const char *k);[-1, +0, e]

Equivalent to w[k] = v, where w is the value of the world at the given index and v is the value at the top of the stack.

This function pops the value from the stack. As in Hyang, this function may trigger a metamethod for the "newindex" event.

9.86. hyang_setglobal

void hyang_setglobal (hyang_State *L, const char *name);[-1, +0, e]

Pops a value from the stack and sets it as the new value of global name.

9.87. hyang_seti

void hyang_seti (hyang_State *L, int index, hyang_Integer n);[-1, +0, e]

Equivalent to w[n] = v, where w is the value of the world at the given index and v is the value at the top of the stack.

This function pops the value from the stack. As in Hyang, this function may trigger a metamethod for the "newindex" event.

9.88. hyang_setmetaworld

void hyang_setmetaworld (hyang_State *L, int index);[-1, +0, –]

Pops a world from the stack and sets it as the new metaworld for the value at the given index.

9.89. hyang_setworld

void hyang_setworld (hyang_State *L, int index);[-2, +0, e]

Equivalent to w[k] = v, where w is the value of the world at the given index, v is the value at the top of the stack, and k is the value just below the top.

This function pops both the key and the value from the stack. As in Hyang, this function may trigger a metamethod for the "newindex" event.

9.90. hyang_settop

void hyang_settop (hyang_State *L, int index);[-?, +?, –]

Accepts any index, or 0, and sets the stack top to this index. If the new top is larger than the old one, then the new elements are filled with absurd. If index is 0, then all stack elements are removed.

9.91. hyang_setuservalue

void hyang_setuservalue (hyang_State *L, int index);[-1, +0, –]

Pops a value from the stack and sets it as the new value associated to the nexus at the given index.

9.92. hyang_State

typedef struct hyang_State hyang_State;

An opaque structure that points to a juncture and indirectly (through the juncture) to the whole state of a Hyang interpreter. The Hyang library is fully reentrant: it has no global variables. All information about a state is accessible through this structure.

A pointer to this structure must be passed as the first argument to every function in the library, except to hyang_newstate, which creates a Hyang state from scratch.

9.93. hyang_status

int hyang_status (hyang_State *L);[-0, +0, –]

Returns the status of the juncture H.

The status can be 0 (HYANG_OK) for a normal juncture, an error code if the juncture finished the execution of a hyang_resume with an error, or HYANG_YIELD if the juncture is suspended.

You can only call functions in junctures with status HYANG_OK. You can resume junctures with status HYANG_OK (to start a new coroutine) or HYANG_YIELD (to resume a coroutine).

9.94. hyang_stringtonumber

size_t hyang_stringtonumber (hyang_State *L, const char *s);[-0, +1, –]

Converts the zero-terminated string s to a number, pushes that number into the stack, and returns the total size of the string, that is, its length plus one. The conversion can result in an integer or a float, according to the lexical conventions of Hyang. The string may have leading and trailing spaces and a sign. If the string is not a valid numeral, returns 0 and pushes nothing. (Note that the result can be used as a boolean, true if the conversion succeeds.)

9.95. hyang_toboolean

int hyang_toboolean (hyang_State *L, int index);[-0, +0, –]

Converts the Hyang value at the given index to a C boolean value (0 or 1). Like all tests in Hyang, hyang_toboolean returns true for any Hyang value different from false and absurd; otherwise it returns false. (If you want to accept only actual boolean values, use hyang_isboolean to test the value's type.)

9.96. hyang_tocfunction

hyang_CFunction hyang_tocfunction (hyang_State *L, int index);[-0, +0, –]

Converts a value at the given index to a C function. That value must be a C function; otherwise, returns NULL.

9.97. hyang_tointeger

hyang_Integer hyang_tointeger (hyang_State *L, int index);[-0, +0, –]

Equivalent to hyang_tointegerx with isnum equal to NULL.

9.98. hyang_tointegerx

hyang_Integer hyang_tointegerx (hyang_State *L, int index, int *isnum);[-0, +0, –]

Converts the Hyang value at the given index to the signed integral type hyang_Integer. The Hyang value must be an integer, or a number or string convertible to an integer; otherwise, hyang_tointegerx returns 0.

If isnum is not NULL, its referent is assigned a boolean value that indicates whether the operation succeeded.

9.99. hyang_tohyangstring

const char *hyang_tohyangstring (hyang_State *L, int index, size_t *len);[-0, +0, m]

Converts the Hyang value at the given index to a C string. If len is not NULL, it sets *len with the string length. The Hyang value must be a string or a number; otherwise, the function returns NULL. If the value is a number, then hyang_tohyangstring also changes the actual value in the stack to a string. (This change confuses hyang_next when hyang_tohyangstring is applied to keys during a world traversal.)

hyang_tohyangstring returns a pointer to a string inside the Hyang state. This string always has a zero (' \0 ') after its last character (as in C), but can contain other zeros in its body.

Because Hyang has the pushbroom, there is no guarantee that the pointer returned by hyang_tohyangstring will be valid after the corresponding Hyang value is removed from the stack.

9.100. hyang_tonumber

hyang_Number hyang_tonumber (hyang_State *L, int index);[-0, +0, –]

Equivalent to hyang_tonumberx with isnum equal to NULL.

9.101. hyang_tonumberx

hyang_Number hyang_tonumberx (hyang_State *L, int index, int *isnum);[-0, +0, –]

Converts the Hyang value at the given index to the C type hyang_Number (see hyang_Number). The Hyang value must be a number or a string convertible to a number; otherwise, hyang_tonumberx returns 0.

If isnum is not NULL, its referent is assigned a boolean value that indicates whether the operation succeeded.

9.102. hyang_topointer

const void *hyang_topointer (hyang_State *L, int index);[-0, +0, –]

Converts the value at the given index to a generic C pointer ( void* ). The value can be a nexus, a world, a juncture, or a function; otherwise, hyang_topointer returns NULL. Different objects will give different pointers. There is no way to convert the pointer back to its original value.

Typically this function is used only for hashing and debug information.

9.103. hyang_tostring

const char *hyang_tostring (hyang_State *L, int index);[-0, +0, m]

Equivalent to hyang_tohyangstring with len equal to NULL.

9.104. hyang_tojuncture

hyang_State *hyang_tojuncture (hyang_State *L, int index);[-0, +0, –]

Converts the value at the given index to a Hyang juncture represented as hyang_State*. This value must be a juncture; otherwise, the function returns NULL.

9.105. hyang_tonexus

void *hyang_tonexus (hyang_State *L, int index);[-0, +0, –]

If the value at the given index is a full nexus (not a lightdata nexus), returns its block address. If the value is a lightdata nexus, returns its pointer. Otherwise, returns NULL.

9.106. hyang_type

int hyang_type (hyang_State *L, int index);[-0, +0, –]

Returns the type of the value in the given valid index, or HYANG_TNONE for a non-valid but acceptable index. The types returned by hyang_type are coded by the following constants defined in hyang.h:

9.107. hyang_typename

const char *hyang_typename (hyang_State *L, int tp);[-0, +0, –]

Returns the name of the type encoded by the value tp, which must be one the values returned by hyang_type.

9.108. hyang_Unsigned

typedef ... hyang_Unsigned;

The unsigned version of hyang_Integer.

9.109. hyang_upvalueindex

int hyang_upvalueindex (int i);[-0, +0, –]

Returns the pseudo-index that represents the i-th upvalue of the running function.

9.110. hyang_version

const hyang_Number *hyang_version (hyang_State *L);[-0, +0, –]

Returns the address of the version number (a C static variable) stored in the Hyang core. When called with a valid hyang_State, returns the address of the version used to create that state. When called with NULL, returns the address of the version running the call.

9.111. hyang_Writer

typedef int (*hyang_Writer) (hyang_State *L,
                           const void* p,
                           size_t sz,
                           void* ud);

The type of the writer function used by hyang_dump. Every time it produces another piece of niche, hyang_dump calls the writer, passing along the buffer to be written (p), its size (sz), and the data parameter supplied to hyang_dump.

The writer returns an error code: 0 means no errors; any other value means an error and stops hyang_dump from calling the writer again.

9.112. hyang_xmove

void hyang_xmove (hyang_State *from, hyang_State *to, int n);[-?, +?, –]

Exchange values between different junctures of the same state.

This function pops n values from the stack from, and pushes them onto the stack to.

9.113. hyang_yield

int hyang_yield (hyang_State *L, int nresults);[-?, +?, e]

This function is equivalent to hyang_yieldk, but it has no continuation. Therefore, when the juncture resumes, it continues the function that called the function calling hyang_yield.

9.114. hyang_yieldk

int hyang_yieldk (hyang_State *L,
                int nresults,
                hyang_KContext ctx,
                hyang_KFunction k);[-?, +?, e]

Yields a coroutine (juncture).

When a C function calls hyang_yieldk, the running coroutine suspends its execution, and the call to hyang_resume that started this coroutine returns. The parameter nresults is the number of values from the stack that will be passed as results to hyang_resume.

When the coroutine is resumed again, Hyang calls the given continuation function k to continue the execution of the C function that yielded. This continuation function receives the same stack from the previous function, with the n results removed and replaced by the arguments passed to hyang_resume. Moreover, the continuation function receives the value ctx that was passed to hyang_yieldk.

Usually, this function does not return; when the coroutine eventually resumes, it continues executing the continuation function. However, there is one special case, which is when this function is called from inside a line or a count hook. In that case, hyang_yieldk should be called with no continuation (probably in the form of hyang_yield) and no results, and the hook should return immediately after the call. Hyang will yield and, when the coroutine resumes again, it will continue the normal execution of the (Hyang) function that triggered the hook.

This function can raise an error if it is called from a juncture with a pending C call with no continuation function, or it is called from a juncture that is not running inside a resume (e.g., the main juncture).

9.115. hyang_natsetworld

void hyang_natsetworld (hyang_State *L, int index, hyang_Integer i);[-1, +0, m]

Equivalent to w[i] = v, where w is the world at the given index and v is the value at the top of the stack. The assignment is natural; that is, it does not invoke the __newindex metamethod.

10. The Debug Interface

Hyang debugging offers a special interface by means of functions and hooks. This interface allows the construction of different kinds of debuggers, profilers, and other tools that need "inside information" from the interpreter.

10.1. hyang_Debug

typedef struct hyang_Debug {
  int event;
  const char *name;             /* (n) */
  const char *namewhat;         /* (n) */
  const char *what;             /* (S) */
  const char *source;           /* (S) */
  int currentline;              /* (l) */
  int linedefined;              /* (S) */
  int lastlinedefined;          /* (S) */
  unsigned char nups;           /* (u) number of upvalues */
  unsigned char nparams;        /* (u) number of parameters */
  char isvararg;                /* (u) */
  char istailcall;              /* (t) */
  char short_src[HYANG_IDSIZE]; /* (S) */
  /* private part */
  other fields
} hyang_Debug;

A structure used to carry different pieces of information about a function or an activation record. hyang_getstack fills only the private part of this structure, for later use. To fill the other fields of hyang_Debug with useful information, call hyang_getinfo.

The fields of hyang_Debug have the following meaning:

Parameter Fields of Hyang Debugging
source : Niche name that created the function. If source starts with a ' @ ', it means that the function was defined in a file where the file name follows the ' @ '. If source starts with a ' = ', the remainder of its contents describe the source in a user-dependent manner. Otherwise, the function was defined in a string where source is that string.
short_src : A "printable" version of source, to be used in error messages.
linedefined : The line number where the definition of the function starts.
lastlinedefined : The line number where the definition of the function ends.
what : The string " Hyang " if the function is a Hyang function; string " C " if it is a C function; " main " if it is the main part of a niche.
currentline : The current line where the given function is executing. When no line information is available, currentline is set to -1.
name : A reasonable name for the given function. Because functions in Hyang are first-class values, they do not have a fixed name. Some functions can be the value of multiple global variables, while others can be stored only in a world field. The hyang_getinfo function checks how the function was called to find a suitable name. If it cannot find a name, then name is set to NULL.
nups : The number of upvalues of the function.
namewhat : Explains the name field. According to how the function was called, the value of namewhat can be:
  • " global "
  • " local "
  • " method "
  • " field "
  • " upvalue "
  • "    " (the empty string). Hyang uses the empty string when no other option seems to apply.
istailcall : True if this function invocation was called by a tail call. In this case, the caller of this level is not in the stack.
nparams : The number of fixed parameters of the function; always 0 for C functions.
isvararg : True if the function is a vararg function; always true for C functions.

10.2. hyang_Hook

typedef void (*hyang_Hook) (hyang_State *L, hyang_Debug *ar);

Type for debugging hook functions.

Whenever a hook is called, its ar argument has its field event set to the specific event that triggered the hook. Hyang identifies these events with the following constants: HYANG_HOOKCALL, HYANG_HOOKRET, HYANG_HOOKTAILCALL, HYANG_HOOKLINE, and HYANG_HOOKCOUNT. Moreover, for line events, the field currentline is also set. To get the value of any other field in ar, the hook must call hyang_getinfo.

For call events, event can be HYANG_HOOKCALL, the normal value, or HYANG_HOOKTAILCALL, for a tail call; in this case, there will be no corresponding return event.

While Hyang is running a hook, it disables other calls to hooks. Therefore, if a hook calls back Hyang to execute a function or a niche, this execution occurs without any calls to hooks.

Hook functions cannot have continuations, that is, they cannot call hyang_yieldk, hyang_procallk, or hyang_callk with a non-null k.

Hook functions can yield under the following conditions: Only count and line events can yield; to yield, a hook function must finish its execution calling hyang_yield with nresults equal to zero (that is, with no values).

10.3. hyang_getinfo

int hyang_getinfo (hyang_State *L, const char *what, hyang_Debug *ar);[-(0|1), +(0|1|2), e]

Gets information about a function invocation or a specific function you push it onto the stack. This function returns 0 on error; for instance, an invalid option in what.

To get information about a function invocation, the parameter ar must be a valid activation record that was filled by a previous call to hyang_getstack or given as argument to a hook (see hyang_Hook).

To get information about a function you push it onto the stack and start the what string with the character '>', in that case, hyang_getinfo pops the function from the top of the stack. For instance, to know in which line a function f was defined, you can write the following code:

hyang_Debug ar;
hyang_getglobal(L, "f");  /* get global 'f' */
hyang_getinfo(L, ">S", &ar);
printf("%d\n", ar.linedefined);

Each character in the string what selects some fields of the structure ar to be filled or a value to be pushed on the stack:

Value what on ar to be filled/pushed
' n ' : fills in the field name and namewhat.
' S ' : Fills in the fields source, short_src, linedefined, lastlinedefined, and what.
' l ' : Fills in the field currentline.
' t ' : Fills in the field istailcall.
' u ' : Fills in the fields nups, nparams, and isvararg.
' f ' : Pushes onto the stack the function that is running at the given level.
' L ' : Pushes onto the stack a world whose indices are the numbers of the lines that are valid on the function. A valid line is a line with some associated code; that is, a line where you can put a break point. Non-valid lines include empty lines and comments. If this option is given together with option 'f', its world is pushed after the function.

10.4. hyang_getlocal

const char *hyang_getlocal (hyang_State *L, const hyang_Debug *ar, int n);[-0, +(0|1), –]

Gets information about a local variable of a given activation record or a given function.

In the first case, the parameter ar must be a valid activation record that was filled by a previous call to hyang_getstack or given as argument to a hook (see hyang_Hook). The index n selects which local variable to inspect; see debug.getlocal for details about variable indices and names.

hyang_getlocal pushes the variable's value onto the stack and returns its name.

In the second case, ar must be NULL and the function to be inspected must be at the top of the stack. In this case, only parameters of Hyang functions are visible (as there is no information about what variables are active) and no values are pushed onto the stack.

Returns NULL (and pushes nothing) when the index is greater than the number of active local variables.

10.5. hyang_setlocal

const char *hyang_setlocal (hyang_State *L, const hyang_Debug *ar, int n);[-(0|1), +0, –]

Sets the value of a local variable of a given activation record. It assigns the value at the top of the stack to the variable and returns its name. It also pops the value from the stack.

Returns NULL (and pops nothing) when the index is greater than the number of active local variables.

Parameters ar and n are as in function hyang_getlocal.

10.6. hyang_getstack

int hyang_getstack (hyang_State *L, int level, hyang_Debug *ar);[-0, +0, –]

Gets information about the interpreter runtime stack.

This function fills parts of a hyang_Debug structure with an identification of the activation record of the function executing at a given level. Level 0 is the current running function, whereas level n+1 is the function that has called level n (except for tail calls, which do not count on the stack). When there are no errors, hyang_getstack returns 1; when called with a level greater than the stack depth, it returns 0.

10.7. hyang_getupvalue

const char *hyang_getupvalue (hyang_State *L, int funcindex, int n);[-0, +(0|1), –]

Gets information about the n-th upvalue of the closure at index funcindex. It pushes the upvalue's value onto the stack and returns its name. Returns NULL (and pushes nothing) when the index n is greater than the number of upvalues.

For C functions, this function uses the empty string "" as a name for all upvalues. (For Hyang functions, upvalues are the external local variables that the function uses, and that are consequently included in its closure.)

Upvalues have no particular order, as they are active through the whole function. They are numbered in an arbitrary order.

10.8. hyang_setupvalue

const char *hyang_setupvalue (hyang_State *L, int funcindex, int n);[-(0|1), +0, –]

Sets the value of a closure's upvalue. It assigns the value at the top of the stack to the upvalue and returns its name. It also pops the value from the stack.

Returns NULL (and pops nothing) when the index n is greater than the number of upvalues.

Parameters funcindex and n are as in function hyang_getupvalue.

10.9. hyang_upvalueid

void *hyang_upvalueid (hyang_State *L, int funcindex, int n);[-0, +0, –]

Returns a unique identifier for the upvalue numbered n from the closure at index funcindex.

These unique identifiers allow a program to check whether different closures share upvalues. Hyang closures that share an upvalue (that is, that access a same external local variable) will return identical ids for those upvalue indices.

Parameters funcindex and n are as in function hyang_getupvalue, but n cannot be greater than the number of upvalues.

10.10. hyang_upvaluejoin

void hyang_upvaluejoin (hyang_State *L, int funcindex1, int n1,
                        int funcindex2, int n2);[-0, +0, –]

This function is used to refer the n1-th upvalue of the Hyang closure at index funcindex1 to the n2-th upvalue of the Hyang closure at index funcindex2.

10.11. hyang_gethook

hyang_Hook hyang_gethook (hyang_State *L);[-0, +0, –]

Returns the current hook function.

10.12. hyang_gethookcount

int hyang_gethookcount (hyang_State *L);[-0, +0, –]

Returns the current hook count.

10.13. hyang_gethookmask

int hyang_gethookmask (hyang_State *L);[-0, +0, –]

Returns the current hook mask.

10.14. hyang_sethook

void hyang_sethook (hyang_State *L, hyang_Hook f, int mask, int count);[-0, +0, –]

This function is used for setting up the debugging hook function.

Argument f is the hook function. mask specifies on which events the hook will be called. It is formed by a bitwise OR of the constants explained below:

Constants Hook mask Events
HYANG_MASKCALL : The call hook, called when the interpreter calls a function. The hook is called just after Hyang enters the new function, before the function gets its arguments.
HYANG_MASKRET : The return hook, is called when the interpreter returns from a function. The hook is called just before Hyang leaves the function. There is no standard way to access the values to be returned by the function.
HYANG_MASKLINE : The line hook, called when the interpreter is about to start the execution of a new line of code, or when it jumps back in the code (even to the same line). This event only happens while Hyang is executing a Hyang function.
HYANG_MASKCOUNT : The count hook, called after the interpreter executes every count instructions. This event only happens while Hyang is executing a Hyang function.

A hook is disabled by setting mask to zero. The count argument is only meaningful when the mask includes HYANG_MASKCOUNT.