API Reference - Lily

Summary
API Reference - Lily
Basic typedefs
Types
lily_bytestring_valHolds a ByteString value.
lily_container_valHolds a variant, user-defined class, List, or Tuple.
lily_coroutine_valHolds a Coroutine value.
lily_file_valHolds a File value.
lily_foreign_valHolds a foreign class.
lily_function_valHolds a Function (could be native or foreign).
lily_generic_valHolds some kind of pointer value (usually, to be cast to a foreign class).
lily_hash_valHolds a Hash value.
lily_string_valHolds a String value.
lily_valueA complete value with class and flag information.
ConfigurationThe configuration struct and related functions.
lily_configAll interpreter config info goes here.
Functions
lily_config_initInitialize a config to default values.
lily_config_getFetch an interpreter’s config struct.
State Management
Functions
lily_new_stateCreate a new interpreter.
lily_free_stateDestroy an interpreter and any values it holds.
Parsing/RenderingParse or render some input.
Functions
lily_load_filePrepare a file for the interpreter.
lily_load_stringPrepare a string for the interpreter.
lily_parse_contentParse content prepared for the interpreter.
lily_render_contentParse content prepared for the interpreter.
lily_parse_exprParse an expression prepared for the interpreter.
Error CaptureCapture error information after a failed parse/render.
Functions
lily_error_messageFetch the message and traceback of the last failed parse/render.
lily_error_message_no_traceFetch only the message of the last failed parse/render.
Configuring renderRender hook and related functions.
Types
lily_render_funcInvoked when template mode needs to render content.
Configuring importThe import hook and functions it uses.
Types
lily_import_funcInvoked to find a module after registered modules have been tried.
lily_call_entry_funcAn dynaload entry in the call_table corresponding to the info_table.
Functions
lily_default_import_funcThis is the default import hook.
lily_import_fileImport a file for the interpreter.
lily_import_libraryLoad a library from a given path.
lily_import_library_dataLoad a preloaded library.
lily_import_stringLoad a string (context path, then content) as a library.
lily_import_use_local_dirUse a local directory for upcoming imports.
lily_import_use_package_dirUse a package directory for upcoming imports.
lily_import_current_root_dirReturn the directory of the package that the source import belongs to.
Class id macrosClass ids for predefined classes.
Macros
LILY_ID_UNSETFalse identity for testing if a value is unset.
LILY_ID_INTEGERIdentity of the Integer class.
LILY_ID_DOUBLEIdentity of the Double class.
LILY_ID_STRINGIdentity of the String class.
LILY_ID_BYTEIdentity of the Byte class.
LILY_ID_BYTESTRINGIdentity of the ByteString class.
LILY_ID_BOOLEANIdentity of the Boolean class.
LILY_ID_FUNCTIONIdentity of the Function class.
LILY_ID_LISTIdentity of the List class.
LILY_ID_HASHIdentity of the Hash class.
LILY_ID_TUPLEIdentity of the Tuple class.
LILY_ID_FILEIdentity of the File class.
LILY_ID_OPTIONIdentity of the Option enum.
LILY_ID_SOMEIdentity of the Some variant.
LILY_ID_NONEIdentity of the None variant.
LILY_ID_RESULTIdentity of the Result enum.
LILY_ID_FAILUREIdentity of the Failure variant of Result.
LILY_ID_SUCCESSIdentity of the Success variant of Result.
LILY_ID_EXCEPTIONIdentity of the Exception class.
LILY_ID_IOERRORIdentity of the IOError class.
LILY_ID_KEYERRORIdentity of the KeyError class.
LILY_ID_RUNTIMEERRORIdentity of the RuntimeError class.
LILY_ID_VALUEERRORIdentity of the ValueError class.
LILY_ID_INDEXERRORIdentity of the IndexError class.
LILY_ID_DBZERRORIdentity of the DivisionByZero class.
LILY_ID_UNITIdentity of the Unit class.
LILY_ID_COROUTINEIdentity of the Coroutine class.
Raw value operationsFunctions that interact with raw values.
Functions
lily_bytestring_rawGet the raw buffer behind a ByteString.
lily_bytestring_lengthGet the size (in bytes) of a ByteString.
lily_con_getFetch an element from a container.
lily_con_setSet an element into a container.
lily_con_set_from_stack(Stack: -1) Set an element into a container from the stack.
lily_con_sizeReturn the number of occupied values in a container.
lily_file_for_readReturn the underlying FILE * of a File (if in read mode), or raise IOError.
lily_file_for_writeReturn the underlying FILE * of a File (if in write mode), or raise IOError.
lily_function_is_foreignReturn 1 if the Function has a foreign implementation, 0 otherwise.
lily_function_is_nativeReturn 1 if the Function has a native implementation, 0 otherwise.
lily_hash_getLook for a given key within a Hash.
lily_hash_setSet ‘key’ to ‘value’ within a given hash.
lily_hash_set_from_stack(Stack: -2) lily_hash_set, but key and value come from the stack.
lily_hash_take(Stack: +1?)
lily_list_insertInsert a value, pushing others to the right.
lily_list_reserveReserve N elements in a List.
lily_list_take(Stack: +1) Take an element out of a List, pushing it onto the stack.
lily_list_pushPush a value onto the end of a List.
lily_string_rawReturns the raw buffer behind a String.
lily_string_lengthReturns the size (in bytes) of a String buffer.
Argument handlingFetch and/or test arguments passed to a foreign function.
Functions
lily_arg_booleanFetch a Boolean from the stack.
lily_arg_byteFetch a Byte from the stack.
lily_arg_bytestringFetch a ByteString from the stack.
lily_arg_containerFetch a user-defined class, (non-empty) variant, List, or Tuple.
lily_arg_coroutineFetch a Coroutine from the stack.
lily_arg_doubleFetch a Double from the stack.
lily_arg_fileFetch a File from the stack.
lily_arg_functionFetch a Function from the stack.
lily_arg_genericFetch a pointer-based (foreign) value from the stack.
lily_arg_hashFetch a Hash from the stack.
lily_arg_integerFetch a Integer from the stack.
lily_arg_stringFetch a String from the stack.
lily_arg_string_rawFetch the underlying buffer of a String from the stack.
lily_arg_valueFetch a complete value with flags and class information.
lily_arg_countHow many arguments the function being called was given.
lily_arg_isaCheck if an argument has an exact class id.
Macros
lily_arg_is_failureCalls lily_arg_isa with LILY_ID_FAILURE.
lily_arg_is_noneCalls lily_arg_isa with LILY_ID_NONE.
lily_arg_is_someCalls lily_arg_isa with LILY_ID_SOME.
lily_arg_is_successCalls lily_arg_isa with LILY_ID_SUCCESS.
Stack pushingPushing values onto the stack.
Functions
lily_push_boolean(Stack: +1) Push a Boolean value onto the stack.
lily_push_byte(Stack: +1) Push a Byte value onto the stack.
lily_push_bytestring(Stack: +1) Push a ByteString value onto the stack.
lily_push_double(Stack: +1) Push a Double value onto the stack.
lily_push_empty_variant(Stack: +1) Push an empty variant (such as None) onto the stack.
lily_push_file(Stack: +1) Push a file onto the stack (interpreter takes it over).
lily_push_foreign(Stack: +1) Push a foreign class value onto the stack.
lily_push_hash(Stack: +1) Push a new Hash with ‘size’ slots reserved onto the stack.
lily_push_instance(Stack: +1) Push a user-defined class instance with ‘size’ values onto the stack.
lily_push_integer(Stack: +1) Push a new Integer onto the stack.
lily_push_list(Stack: +1) Push a List with ‘size’ values onto the stack.
lily_push_string(Stack: +1) Push a String wrapping over ‘source’ onto the stack.
lily_push_string_sized(Stack: +1) Push a String of ‘size’ bytes from ‘source’ onto the stack.
lily_push_super(Stack: +1) Push a superclass onto the stack.
lily_push_tuple(Stack: +1) Push a Tuple with ‘size’ values onto the stack.
lily_push_unit(Stack: +1) Push the unit value (of class Unit) onto the stack.
lily_push_value(Stack: +1) Push a full value onto the stack.
lily_push_variant(Stack: +1) Push a variant of ‘class_id’ and ‘size’ values onto the stack.
Macros
lily_push_failureShorthand for lily_push_variant with LILY_ID_FAILURE.
lily_push_noneShorthand for lily_push_empty_variant with LILY_ID_NONE.
lily_push_someShorthand for lily_push_some with LILY_ID_SOME.
lily_push_successShorthand for lily_push_success with LILY_ID_SUCCESS.
Returning a valueAll foreign functions must finish by returning a value.
Functions
lily_return_booleanSet a Boolean return value.
lily_return_byteSet a Byte return value.
lily_return_doubleSet a Double return value.
lily_return_integerSet an Integer return value.
lily_return_noneSet a None return value.
lily_return_superUse this if lily_push_super was used.
lily_return_topSet the return value as the value currently at the top of the stack.
lily_return_unitSet a Unit return value.
lily_return_valueSet the value given as the return value.
Value extractionExtract a raw value from a full value.
Functions
lily_as_booleanExtract a Boolean.
lily_as_byteExtract a Byte.
lily_as_bytestringExtract a ByteString.
lily_as_containerExtract a container (user-defined class, non-empty variant, List, or Tuple).
lily_as_coroutineExtract a Coroutine.
lily_as_doubleExtract a Double.
lily_as_fileExtract a File.
lily_as_functionExtract a Function.
lily_as_genericExtract a generic pointer (to be cast to some other type)..
lily_as_hashExtract a Hash.
lily_as_integerExtract a Integer.
lily_as_stringExtract a String.
lily_as_string_rawExtract the raw buffer behind a String.
Calling a functionFunctions for calling back into the interpreter.
Functions
lily_call(Stack: -count) Perform a prepared call using values from the stack.
lily_call_prepare(Stack: +1) Reserve a result register and prepare ‘func’.
lily_call_resultReturn the register that ‘lily_call_prepare’ reserved.
Exception raiseFunctions for raising an exception.
Functions
lily_DivisionByZeroErrorRaise DivisionByZeroError with the given message and args.
lily_IndexErrorRaise IndexError with the given message and args.
lily_IOErrorRaise IOError with the given message and args.
lily_KeyErrorRaise KeyError with the given message and args.
lily_RuntimeErrorRaise RuntimeError with the given message and args.
lily_ValueErrorRaise ValueError with the given message and args.
Error callbacksForeign function cleanup.
Types
lily_error_callback_funcCallback for when lily_call raises an exception.
Functions
lily_error_callback_pushPush an error callback for the current foreign function.
lily_error_callback_popRemove an error callback (typically at foreign function exit).
Stack operationsOperations working on the top of the stack.
Functions
lily_stack_drop_topPop the top of the stack, deref-ing it if necessary.
lily_stack_get_topReturn the value at the top of the stack.
Message buffer operationsA wrapper over an automatically-growing buffer.
Types
lily_msgbufOpaque typedef for a msgbuf.
Functions
lily_new_msgbufCreate a new msgbuf with a starting size of ‘size’.
lily_free_msgbufFree a msgbuf struct and the underlying buffer.
lily_mb_addAdd ‘source’ to the msgbuf.
lily_mb_add_charAdd a single character ‘ch’ to the msgbuf.
lily_mb_add_fmtAdd to the msgbuf based on a format string.
lily_mb_add_fmt_valily_mb_add_fmt, but using a va_list.
lily_mb_add_sliceAdd ‘source’ to the msgbuf, from ‘start’ to ‘end’.
lily_mb_add_valueInterpolate a value into the msgbuf.
lily_mb_flushDrop all contents in the msgbuf.
lily_mb_rawReturn the underlying buffer of a msgbuf.
lily_mb_posReturn the length of the msgbuf.
lily_mb_html_escapeAdd html-escaped version of ‘input’ to the msgbuf.
lily_mb_sprintfEquivalent to flush, add_fmt, returning the underlying buffer.
lily_msgbuf_getReturn the common msgbuf of the interpreter.
Foreign bitsItems of interest for putting a foreign class into Lily.
Macros
LILY_FOREIGN_HEADERPut this macro at the top of any struct that is later introduced as a foreign class to the interpreter.
Types
lily_destroy_funcHook called when a value is to be destroyed.
MiscellaneousMiscellaneous operations that don’t fit elsewhere.
Functions
lily_find_functionSearch for a function called ‘name’.
lily_register_moduleMake a module called ‘name’ available to the interpreter.
lily_is_valid_utf8Check if ‘source’ is valid utf-8.
lily_value_tagPlace a gc tag onto ‘value’.
lily_cid_atFunction for autogenerated ID_* macros to get a class id.

Basic typedefs

Summary
Types
lily_bytestring_valHolds a ByteString value.
lily_container_valHolds a variant, user-defined class, List, or Tuple.
lily_coroutine_valHolds a Coroutine value.
lily_file_valHolds a File value.
lily_foreign_valHolds a foreign class.
lily_function_valHolds a Function (could be native or foreign).
lily_generic_valHolds some kind of pointer value (usually, to be cast to a foreign class).
lily_hash_valHolds a Hash value.
lily_string_valHolds a String value.
lily_valueA complete value with class and flag information.

Types

lily_bytestring_val

Holds a ByteString value.

lily_container_val

Holds a variant, user-defined class, List, or Tuple.

lily_coroutine_val

Holds a Coroutine value.

lily_file_val

Holds a File value.

lily_foreign_val

Holds a foreign class.

lily_function_val

Holds a Function (could be native or foreign).

lily_generic_val

Holds some kind of pointer value (usually, to be cast to a foreign class).

lily_hash_val

Holds a Hash value.

lily_string_val

Holds a String value.

lily_value

A complete value with class and flag information.

Configuration

The configuration struct and related functions.

lily_config

typedef struct lily_config_

All interpreter config info goes here.

Every interpreter requires a configuration struct to initialize it.  The config struct is a struct with members publically exposed.  This allows embedders to grab fields they want instead of going through the hoops of simple get/set functions for an opaque struct.

Interpreters do not free the config when they are done, nor do they free any fields in the config.  It is the caller’s responsibility to clean up the config when the interpreter is done.

Because of that, callers are permitted to use the same configuration to initialize multiple interpreters.

Callers must not modify configuration members once an interpreter has been created that uses them.

Fields

argc(Default: 0) Number of values in argv.
argv(Default: NULL) The argument list (later used by Lily’s sys.argv).
copy_str_input(Default: 0) The interpreter provides functions for parsing, rendering, and loading that use a ‘const char *’ as their input source.  These functions assume the caller will not modify the underlying string while the interpreter is using it.  If this is set to 1, then the interpreter will copy string data passed, free-ing it when parsing/rendering/loading is complete.
data(Default: stdin) This will later be sent as the data part of the import_func hook.
gc_multiplier(Default: 4) If a gc sweep fails, how much should the count of allowed values be multiplied by?
gc_start(Default: 100) How many values should be allowed to exist at once before a gc pass.
import_func(Default: lily_default_import_func) What function should be called to handle imports?
render_func(Default: fputs) What function should be called if there is template content to be rendered?
sipkey(Default: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] The sipkey is an array of 16 char values that helps to prevent collisions in Lily’s Hash class.
Summary
Functions
lily_config_initInitialize a config to default values.
lily_config_getFetch an interpreter’s config struct.

Functions

lily_config_init

void lily_config_init(lily_config *config)

Initialize a config to default values.

This function assumes that the caller has a config struct on the stack.  The caller can pass the address of that struct to this function, and the default values will be set.

lily_config_get

lily_config *lily_config_get(lily_state *s)

Fetch an interpreter’s config struct.

State Management

Summary
Functions
lily_new_stateCreate a new interpreter.
lily_free_stateDestroy an interpreter and any values it holds.

Functions

lily_new_state

lily_state *lily_new_state(lily_config *config)

Create a new interpreter.

lily_free_state

void lily_free_state(lily_state *s)

Destroy an interpreter and any values it holds.

Parsing/Rendering

Parse or render some input.

These functions must **not** be called while the interpreter is either executing or within an import hook.

The lily_load_* functions prepare content for the interpreter.  The other functions detailed in this sections consume the content.

Attempting to parse or render an interpreter without content ready will do nothing.  Similarly, attempting to load when content has already been loaded will do nothing.

If any functions detailed here fail, the embedder can use the `lily_error_*` set of functions to determine what went wrong (except for the two cases that are ignored above).

If necessary, the interpreter’s rewind is invoked when there is a successful `lily_load_*` call after the failed parse or render.

Summary
Functions
lily_load_filePrepare a file for the interpreter.
lily_load_stringPrepare a string for the interpreter.
lily_parse_contentParse content prepared for the interpreter.
lily_render_contentParse content prepared for the interpreter.
lily_parse_exprParse an expression prepared for the interpreter.

Functions

lily_load_file

int lily_load_file(lily_state *s,
const char *path)

Prepare a file for the interpreter.

The path used for loading is exactly the one that is provided by this function.  This function will raise an error if the path does not end in ‘.lily’.

Parameters

sThe interpreter.
pathA path to a file to be loaded.  Must end in ‘.lily’.

Returns 1 on success, 0 on failure.

lily_load_string

int lily_load_string(lily_state *s,
const char *context,
const char *str)

Prepare a string for the interpreter.

By default, the interpreter assumes that the ‘content’ will not be modified.  Callers who cannot provide such a guarantee should set the config option ‘copy_str_input’ to 1 before using this function.

The context passed does not require ‘.lily’ as a suffix.  The context provided is exactly the one that is used for the filename.

For pseudo-files like reading from stdin, the embedder may want to use a bracketed name (ex: `[cli]` or `[repl]`).

Parameters

sThe interpreter.
contextThis is the filename to use in case there is an error.
dataThe input for the interpreter.

Returns 1 on success, 0 on failure.

lily_parse_content

int lily_parse_content(lily_state *s)

Parse content prepared for the interpreter.

This parses the content provided in code-only mode.  The content is consumed regardless of this function’s result.

If the parse is successful, the code is executed as well.

Returns 1 on success, 0 on failure.

lily_render_content

int lily_render_content(lily_state *s)

Parse content prepared for the interpreter.

This parses the content provided in template mode.  The content is consumed regardless of this function’s result.

Prior to parsing, the content is checked to make sure it begins with the `<?lily` header at the very top of the file.  If it does not, no parsing is performed.

Returns 1 on success, 0 on failure.

lily_parse_expr

int lily_parse_expr(lily_state *s,
const char **output)

Parse an expression prepared for the interpreter.

This parses the content provided as an expression in code mode.  The content is consumed regardless of this function’s result.

If the expression is successfully processed, then ‘output’ is set to a buffer holding the type and the value of the type.

The buffer that ‘output’ holds on success points to an internal msgbuf.  It is valid until the next parse or render function is called.

Parameters

sThe interpreter.
outputIf ‘data’ is a valid expression, then the result is set to the address of ‘output’.

Returns 1 on success, 0 on failure.

Error Capture

Capture error information after a failed parse/render.

These functions capture the error that is raised when a parse or render function fails.  Error information from a failed parse or render exists until the next of either is called.

Capture functions must not be called multiple times.

Summary
Functions
lily_error_messageFetch the message and traceback of the last failed parse/render.
lily_error_message_no_traceFetch only the message of the last failed parse/render.

Functions

lily_error_message

const char *lily_error_message(lily_state *s)

Fetch the message and traceback of the last failed parse/render.

The output of this function is exactly what the ‘lily’ executable returns when there is an error (the kind of error, error message, then traceback).

The result of this is a pointer to a msgbuf inside of the interpeter.  The pointer is valid until the next parse/render step.

lily_error_message_no_trace

const char *lily_error_message_no_trace(lily_state *s)

Fetch only the message of the last failed parse/render.

This returns the kind of error raised and the error message.  Traceback is omitted.  This function is used by the repl.

The result of this is a pointer to a msgbuf inside of the interpeter.  The pointer is valid until the next parse/render step.

Configuring render

Render hook and related functions.

Summary
Types
lily_render_funcInvoked when template mode needs to render content.

Types

lily_render_func

Invoked when template mode needs to render content.

Parameters

contentThe text to be rendered.
dataThis is the ‘data’ member of the interpreter’s config.

Configuring import

The import hook and functions it uses.

Note: The loading functions mentioned here will return 0 on s

Summary
Types
lily_import_funcInvoked to find a module after registered modules have been tried.
lily_call_entry_funcAn dynaload entry in the call_table corresponding to the info_table.
Functions
lily_default_import_funcThis is the default import hook.
lily_import_fileImport a file for the interpreter.
lily_import_libraryLoad a library from a given path.
lily_import_library_dataLoad a preloaded library.
lily_import_stringLoad a string (context path, then content) as a library.
lily_import_use_local_dirUse a local directory for upcoming imports.
lily_import_use_package_dirUse a package directory for upcoming imports.
lily_import_current_root_dirReturn the directory of the package that the source import belongs to.

Types

lily_import_func

Invoked to find a module after registered modules have been tried.

This hook is provided the interpreter state and a target.  The target is what was sent to the ‘import’ keyword.  If the current platform doesn’t use forward slashes, then the slashes are replaced with what the platform uses.  On Windows for example, they’re replaced with backslashes.  No suffix is given.

Before any loading, the hook must use one of the lily_import_use_* functions.  Those functions tell the interpreter of the subsequent file or string or other content is at the root of a package or not.

The `lily_import_*` set of functions that this uses share some common behavior.  They will return 1 if another import has succeeded or an already-imported module satisfying the target given has been found.  If a `lily_import_*` function fails, it records the path that was attempted.

If the hook cannot load a module for the interpreter, it should return normally.  The interpreter will check if a module was loaded and write an error message detailing the paths that were tried.

Parameters

sThe interpreter state.
targetThe name passed to the import keyword.

lily_call_entry_func

An dynaload entry in the call_table corresponding to the info_table.

This is a typedef that represents an entry in the call_table half of dynaload.  One of these entries could be a method implementation or a var loader.  Both halves are automatically generated, and most users won’t need to interact with them except to register embedded Lily code.

Functions

lily_default_import_func

void lily_default_import_func(lily_state *s,
const char *target)

This is the default import hook.

The default import hook is used by the ‘lily’ embedder.  This is provided for the sake of completeness.

lily_import_file

int lily_import_file(lily_state *s,
const char *target)

Import a file for the interpreter.

In most cases, a caller will want to use this with the target that was provided by the hook.  The ‘.lily’ suffix is automatically added.

Parameters

sThe interpreter state.
targetThe target to attempt loading.

Returns 1 on success, 0 on failure.

lily_import_library

int lily_import_library(lily_state *s,
const char *target)

Load a library from a given path.

In most cases, a caller will want to use this with the target that was provided by the hook.  The appropriate library suffix is automatically added.

Parameters

sThe interpreter state.
targetThe target to attempt loading.

Returns 1 on success, 0 on failure.

lily_import_library_data

int lily_import_library_data(lily_state *s,
const char *target,
const char **info_table,
lily_call_entry_func *call_table)

Load a preloaded library.

This function does not add a suffix to the target given.

Parameters

sThe interpreter state.
targetThe path to register for the library.
info_tableAn info table for the library.
call_tableThe call table companion to the info table.

Returns 1 on success, 0 on failure.

lily_import_string

int lily_import_string(lily_state *s,
const char *target,
const char *content)

Load a string (context path, then content) as a library.

By default, the interpreter assumes that the ‘content’ will not be modified.  Callers who cannot provide such a guarantee should set the config option ‘copy_str_input’ to 1 before using this function.

This function does not add a suffix to the path given.

Returns 1 on success, 0 on failure.

lily_import_use_local_dir

void lily_import_use_local_dir(lily_state *s,
const char *dir)

Use a local directory for upcoming imports.

This instructs the interpreter that subsequent `lily_import_*` calls should be done within the current package.  Callers that want the default loading scheme that the ‘lily’ executable uses should pass this an empty string.

If this function is passed forward slashes, they are replaced with the platform-appropriate slash if necessary (backslash on Windows for example).

If, for example, an embedder wanted to allow for a ‘test’ directory to have access to a ‘src’ directory, it would execute a file in the parent directory of both.  It could then use `lily_import_use_local_dir(s, “src”)`, run imports, then use `lily_import_use_local_dir(s, “test”)`.

This lasts until the other function is called.

lily_import_use_package_dir

Use a package directory for upcoming imports.

This instructs the interpreter that subsequent `lily_import_*` calls should be done inside a package.  For a given target ‘x’, this will run imports within ‘packages/x/src/x.suffix’.  Callers that want the default loading scheme that the ‘lily’ executable uses should pass this an empty string.

If this function is passed forward slashes, they are replaced with the platform-appropriate slash if necessary (backslash on Windows for example).

If, for example, an embedder wanted to allow for a ‘test’ directory to have access to a ‘src’ directory, it would execute a file in the parent directory of both.  It could then use `lily_import_use_local_dir(s, “src”)`, run imports, then use `lily_import_use_local_dir(s, “test”)`.

This lasts until the other function is called.

lily_import_current_root_dir

const char *lily_import_current_root_dir(lily_state *s)

Return the directory of the package that the source import belongs to.

The first module imported is considered to be the root of a package.  For all others, packages are found within ‘packages/name/src/name.suffix’.

The result of this function does not include the initial directory passed to the first source (ex: ‘test/abc.lily’ is the same as ‘abc.lily’).

One use case of this is to allow files in a ‘test’ directory to import those in a ‘src’ directory.

The result of this function uses the slashes of the source platform, but will not contain a trailing slash.  If called from the first package, the result is an empty string.

Class id macros

Class ids for predefined classes.

Lily contains several predefined classes.  Their ids are made available in case they are useful to embedders.  Variant ids, for example, can be used with ‘lily_arg_isa’ to determine what variant an enum holds.

Embedders that add a foreign class to the interpreter will be fetching it with ‘lily_cid_at’.

Embedders must not rely on class ids having certain values, as they may (but should not) change between releases.

Summary
Macros
LILY_ID_UNSETFalse identity for testing if a value is unset.
LILY_ID_INTEGERIdentity of the Integer class.
LILY_ID_DOUBLEIdentity of the Double class.
LILY_ID_STRINGIdentity of the String class.
LILY_ID_BYTEIdentity of the Byte class.
LILY_ID_BYTESTRINGIdentity of the ByteString class.
LILY_ID_BOOLEANIdentity of the Boolean class.
LILY_ID_FUNCTIONIdentity of the Function class.
LILY_ID_LISTIdentity of the List class.
LILY_ID_HASHIdentity of the Hash class.
LILY_ID_TUPLEIdentity of the Tuple class.
LILY_ID_FILEIdentity of the File class.
LILY_ID_OPTIONIdentity of the Option enum.
LILY_ID_SOMEIdentity of the Some variant.
LILY_ID_NONEIdentity of the None variant.
LILY_ID_RESULTIdentity of the Result enum.
LILY_ID_FAILUREIdentity of the Failure variant of Result.
LILY_ID_SUCCESSIdentity of the Success variant of Result.
LILY_ID_EXCEPTIONIdentity of the Exception class.
LILY_ID_IOERRORIdentity of the IOError class.
LILY_ID_KEYERRORIdentity of the KeyError class.
LILY_ID_RUNTIMEERRORIdentity of the RuntimeError class.
LILY_ID_VALUEERRORIdentity of the ValueError class.
LILY_ID_INDEXERRORIdentity of the IndexError class.
LILY_ID_DBZERRORIdentity of the DivisionByZero class.
LILY_ID_UNITIdentity of the Unit class.
LILY_ID_COROUTINEIdentity of the Coroutine class.

Macros

LILY_ID_UNSET

False identity for testing if a value is unset.

This id is for use by functions that have optional keyword arguments.  Suppose a function takes three keyword arguments, but is only given the first and the third.  In such a case, the interpreter sends an ‘unset’ value to stand in for the second argument to allow using the same calling opcode.

LILY_ID_INTEGER

Identity of the Integer class.

LILY_ID_DOUBLE

Identity of the Double class.

LILY_ID_STRING

Identity of the String class.

LILY_ID_BYTE

Identity of the Byte class.

LILY_ID_BYTESTRING

Identity of the ByteString class.

LILY_ID_BOOLEAN

Identity of the Boolean class.

LILY_ID_FUNCTION

Identity of the Function class.

LILY_ID_LIST

Identity of the List class.

LILY_ID_HASH

Identity of the Hash class.

LILY_ID_TUPLE

Identity of the Tuple class.

LILY_ID_FILE

Identity of the File class.

LILY_ID_OPTION

Identity of the Option enum.

LILY_ID_SOME

Identity of the Some variant.

LILY_ID_NONE

Identity of the None variant.

LILY_ID_RESULT

Identity of the Result enum.

LILY_ID_FAILURE

Identity of the Failure variant of Result.

LILY_ID_SUCCESS

Identity of the Success variant of Result.

LILY_ID_EXCEPTION

Identity of the Exception class.

LILY_ID_IOERROR

Identity of the IOError class.

LILY_ID_KEYERROR

Identity of the KeyError class.

LILY_ID_RUNTIMEERROR

Identity of the RuntimeError class.

LILY_ID_VALUEERROR

Identity of the ValueError class.

LILY_ID_INDEXERROR

Identity of the IndexError class.

LILY_ID_DBZERROR

Identity of the DivisionByZero class.

LILY_ID_UNIT

Identity of the Unit class.

LILY_ID_COROUTINE

Identity of the Coroutine class.

Raw value operations

Functions that interact with raw values.

Summary
Functions
lily_bytestring_rawGet the raw buffer behind a ByteString.
lily_bytestring_lengthGet the size (in bytes) of a ByteString.
lily_con_getFetch an element from a container.
lily_con_setSet an element into a container.
lily_con_set_from_stack(Stack: -1) Set an element into a container from the stack.
lily_con_sizeReturn the number of occupied values in a container.
lily_file_for_readReturn the underlying FILE * of a File (if in read mode), or raise IOError.
lily_file_for_writeReturn the underlying FILE * of a File (if in write mode), or raise IOError.
lily_function_is_foreignReturn 1 if the Function has a foreign implementation, 0 otherwise.
lily_function_is_nativeReturn 1 if the Function has a native implementation, 0 otherwise.
lily_hash_getLook for a given key within a Hash.
lily_hash_setSet ‘key’ to ‘value’ within a given hash.
lily_hash_set_from_stack(Stack: -2) lily_hash_set, but key and value come from the stack.
lily_hash_take(Stack: +1?)
lily_list_insertInsert a value, pushing others to the right.
lily_list_reserveReserve N elements in a List.
lily_list_take(Stack: +1) Take an element out of a List, pushing it onto the stack.
lily_list_pushPush a value onto the end of a List.
lily_string_rawReturns the raw buffer behind a String.
lily_string_lengthReturns the size (in bytes) of a String buffer.

Functions

lily_bytestring_raw

char *lily_bytestring_raw(lily_bytestring_val *byte_val)

Get the raw buffer behind a ByteString.

lily_bytestring_length

int lily_bytestring_length(lily_bytestring_val *byte_val)

Get the size (in bytes) of a ByteString.

lily_con_get

lily_value *lily_con_get(lily_container_val *con,
int index)

Fetch an element from a container.

This returns a pointer to an element at ‘index’ within ‘con’.  The value is **not** given a refcount increase (that happens when the value is put somewhere).  The caller can therefore use the result of this function as part of an expression without worrying about a leak.

No safety checking is performed on the index given.

Parameters

conThe container (user-defined class, non-empty variant, List, or Tuple).
indexTarget index.  Cannot be negative.  0 is the first element.

lily_con_set

void lily_con_set(lily_container_val *con,
int index,
lily_value *value)

Set an element into a container.

This assigns a new value to ‘con’ at the position ‘index’.  The source value will receive a ref increase, whereas the old value will have a ref drop (and possibly be destroyed).

No safety checking is performed on the index given.

Parameters

conThe container (user-defined class, non-empty variant, List, or Tuple).
indexTarget index.  Cannot be negative.  0 is the first element.

lily_con_set_from_stack

void lily_con_set_from_stack(lily_state *s,
lily_container_val *con,
int index)

(Stack: -1) Set an element into a container from the stack.

This pops 1 value from the stack, to be used as the value.  Following that, this performs the same work as ‘lily_con_set’ using that value.

No safety checking is performed on the index given.

Parameters

conThe container (user-defined class, non-empty variant, List, or Tuple).
indexTarget index.  Cannot be negative.  0 is the first element.

lily_con_size

uint32_t lily_con_size(lily_container_val *con)

Return the number of occupied values in a container.

For List values, this does **not** include how many values were reserved.

lily_file_for_read

FILE *lily_file_for_read(lily_state *s,
lily_file_val *file)

Return the underlying FILE * of a File (if in read mode), or raise IOError.

lily_file_for_write

FILE *lily_file_for_write(lily_state *s,
lily_file_val *file)

Return the underlying FILE * of a File (if in write mode), or raise IOError.

lily_function_is_foreign

int lily_function_is_foreign(lily_function_val *func)

Return 1 if the Function has a foreign implementation, 0 otherwise.

lily_function_is_native

int lily_function_is_native(lily_function_val *func)

Return 1 if the Function has a native implementation, 0 otherwise.

lily_hash_get

lily_value *lily_hash_get(lily_state *s,
lily_hash_val *hash,
lily_value *key)

Look for a given key within a Hash.

This assumes that ‘key’ is valid for the hash given.  The caller must not send the wrong kind of a key for a hash (ex: a String key for a Integer hash).

The result of this function is either a pointer to the value found or NULL.

Parameters

sThe interpreter.  This must be the same interpreter that the hash was created for, because this function uses the interpreter’s sipkey.
hashThe target hash value.
keyA full value holding a key to search for.

lily_hash_set

void lily_hash_set(lily_state *s,
lily_hash_val *hash,
lily_value *key,
lily_value *record)

Set ‘key’ to ‘value’ within a given hash.

This assumes that both the key and record are valid for this kind of hash.  Do not attempt to store the wrong kind of key or record in a hash.

If the key provided does not already exist in the hash, then both the key and the value are copied into the hash.

Otherwise, the value for the existing key is overwritten.  The value provided will receive a ref increase, whereas the old value gets a ref drop (and may be destroyed.

Parameters

sThe interpreter.  This must be the same interpreter that the hash was created for, because this function uses the interpreter’s sipkey.
hashThe target hash value.
keyA full value holding a key to search for.
recordA full value to store in the hash.

lily_hash_set_from_stack

void lily_hash_set_from_stack(lily_state *s,
lily_hash_val *hash)

(Stack: -2) lily_hash_set, but key and value come from the stack.

This pops 2 values from the top of the stack.  The first value (the original top of the stack) is the record to use.  The second value (the one next to the top) is the key.

This function then performs the same work as lily_hash_set.

lily_hash_take

int lily_hash_take(lily_state *s,
lily_hash_val *hash,
lily_value *key)

(Stack: +1?)  Maybe take a value from a hash.

This performs the same work as lily_hash_get.

If the result is non-NULL, it is pushed onto the stack.  Otherwise, no action is performed to the stack.

Returns 1 if the stack had a value pushed, 0 otherwise.

lily_list_insert

void lily_list_insert(lily_container_val *con,
int index,
lily_value *value)

Insert a value, pushing others to the right.

This takes a container because List is implemented as a container.  However, the caller must **not** send non-List values to this function.

The index provided must be between existing elements in the List (reserved spaces do not count).  This function may, however, use an element that has been reserved.

Parameters

conA List value.
indexIndex position.  Cannot be negative.  0 is the first element.
valueA full value to push.

lily_list_reserve

void lily_list_reserve(lily_container_val *con,
int size)

Reserve N elements in a List.

This takes a container because List is implemented as a container.  However, the caller must **not** send non-List values to this function.

List values are not required to have reserved element in order for other List-based functions to work.  This function is for callers who know they will need a very large List and do not want repeated growing.

Parameters

conA List value.
sizeThe total number of elements to have reserved.  If this is less than the number of elements currently reserved, no action is taken.  Must not be negative.

lily_list_take

void lily_list_take(lily_state *s,
lily_container_val *con,
int index)

(Stack: +1) Take an element out of a List, pushing it onto the stack.

This takes a container because List is implemented as a container.  However, the caller must **not** send non-List values to this function.

This performs the same work as lily_list_get.  Instead of simply returning the value, it is instead taken from the List and pushed onto the stack.

Parameters

sThe interpreter.
conA List value.
indexTarget index.  Cannot be negative.  0 is the first element.

lily_list_push

void lily_list_push(lily_container_val *con,
lily_value *value)

Push a value onto the end of a List.

This takes a container because List is implemented as a container.  However, the caller must **not** send non-List values to this function.

This pushes the value provided onto the end of the List given.

lily_string_raw

char *lily_string_raw(lily_string_val *string_val)

Returns the raw buffer behind a String.

lily_string_length

int lily_string_length(lily_string_val *string_val)

Returns the size (in bytes) of a String buffer.

Argument handling

Fetch and/or test arguments passed to a foreign function.

The lily_arg_* functions grab values from the bottom of the interpreter’s stack.  The first argument is at index 0.

These functions are named lily_arg_* because their most common use is fetching arguments of a function.  However, they are not limited to that.  If, for example, a function takes 2 arguments and a Boolean is pushed, then lily_arg_boolean being passed an index of 2 (the third argument) will yield the value pushed.

How various function features are implemented

Variable argumentsExtra arguments are placed into a List which is empty if no extra arguments were passed.
Optional argumentsFunctions are provided an argument count, and are responsible for implementing the default values they claim to have.
Keyword argumentsArguments are rearranged into positional order before the function sees them.  If keyword arguments are optional, then the ‘holes’ are filled by sending an unset value.  Use LILY_ID_UNSET with lily_arg_isa to test for holes.

These functions do **not** support negative indexes.

Summary
Functions
lily_arg_booleanFetch a Boolean from the stack.
lily_arg_byteFetch a Byte from the stack.
lily_arg_bytestringFetch a ByteString from the stack.
lily_arg_containerFetch a user-defined class, (non-empty) variant, List, or Tuple.
lily_arg_coroutineFetch a Coroutine from the stack.
lily_arg_doubleFetch a Double from the stack.
lily_arg_fileFetch a File from the stack.
lily_arg_functionFetch a Function from the stack.
lily_arg_genericFetch a pointer-based (foreign) value from the stack.
lily_arg_hashFetch a Hash from the stack.
lily_arg_integerFetch a Integer from the stack.
lily_arg_stringFetch a String from the stack.
lily_arg_string_rawFetch the underlying buffer of a String from the stack.
lily_arg_valueFetch a complete value with flags and class information.
lily_arg_countHow many arguments the function being called was given.
lily_arg_isaCheck if an argument has an exact class id.
Macros
lily_arg_is_failureCalls lily_arg_isa with LILY_ID_FAILURE.
lily_arg_is_noneCalls lily_arg_isa with LILY_ID_NONE.
lily_arg_is_someCalls lily_arg_isa with LILY_ID_SOME.
lily_arg_is_successCalls lily_arg_isa with LILY_ID_SUCCESS.

Functions

lily_arg_boolean

int lily_arg_boolean (lily_state *s,
int index)

Fetch a Boolean from the stack.

lily_arg_byte

uint8_t lily_arg_byte (lily_state *s,
int index)

Fetch a Byte from the stack.

lily_arg_bytestring

lily_bytestring_val *lily_arg_bytestring(lily_state *s,
int index)

Fetch a ByteString from the stack.

lily_arg_container

lily_container_val * lily_arg_container (lily_state *s,
int index)

Fetch a user-defined class, (non-empty) variant, List, or Tuple.

If the argument can hold an empty variant (such as Option), make sure to test that first.  Otherwise, the container returned will be invalid, and using it will almost certainly cause a crash.

lily_arg_coroutine

lily_coroutine_val * lily_arg_coroutine (lily_state *s,
int index)

Fetch a Coroutine from the stack.

lily_arg_double

double lily_arg_double (lily_state *s,
int index)

Fetch a Double from the stack.

lily_arg_file

lily_file_val * lily_arg_file (lily_state *s,
int index)

Fetch a File from the stack.

lily_arg_function

lily_function_val * lily_arg_function (lily_state *s,
int index)

Fetch a Function from the stack.

lily_arg_generic

lily_generic_val * lily_arg_generic (lily_state *s,
int index)

Fetch a pointer-based (foreign) value from the stack.

Bindings generated for use by foreign classes will cast the result of this to the appropriate foreign class.

lily_arg_hash

lily_hash_val * lily_arg_hash (lily_state *s,
int index)

Fetch a Hash from the stack.

lily_arg_integer

int64_t lily_arg_integer (lily_state *s,
int index)

Fetch a Integer from the stack.

lily_arg_string

lily_string_val * lily_arg_string (lily_state *s,
int index)

Fetch a String from the stack.

lily_arg_string_raw

char * lily_arg_string_raw(lily_state *s,
int index)

Fetch the underlying buffer of a String from the stack.

lily_arg_value

lily_value * lily_arg_value (lily_state *s,
int index)

Fetch a complete value with flags and class information.

lily_arg_count

int lily_arg_count(lily_state *s)

How many arguments the function being called was given.

Note: Variable argument functions place their extra arguments into a List.

lily_arg_isa

int lily_arg_isa(lily_state *s,
int index,
uint16_t class_id)

Check if an argument has an exact class id.

This is a strict equality comparison to the value at the index provided.  Attempting to test that a value of class ValueError isa Exception will therefore fail.

One use of this function is to identify what variant that an enum is before using the enum.

Returns 1 if true, 0 otherwise.

Macros

lily_arg_is_failure

Calls lily_arg_isa with LILY_ID_FAILURE.

lily_arg_is_none

Calls lily_arg_isa with LILY_ID_NONE.

lily_arg_is_some

Calls lily_arg_isa with LILY_ID_SOME.

lily_arg_is_success

Calls lily_arg_isa with LILY_ID_SUCCESS.

Stack pushing

Pushing values onto the stack.

Foreign functions and dynaload loaders are permitted to push extra values onto the interpreter’s stack.

Simple primitives return void, since there is nothing more to do after pushing the value onto the stack.

Containers, on the other hand, return themselves.  It is the caller’s responsibility to fill containers befolre using them.

When implementing a dynaload loader, the variable loading functions should finish with exactly 1 extra value on the stack.  That extra value becomes the value for the var.

Summary
Functions
lily_push_boolean(Stack: +1) Push a Boolean value onto the stack.
lily_push_byte(Stack: +1) Push a Byte value onto the stack.
lily_push_bytestring(Stack: +1) Push a ByteString value onto the stack.
lily_push_double(Stack: +1) Push a Double value onto the stack.
lily_push_empty_variant(Stack: +1) Push an empty variant (such as None) onto the stack.
lily_push_file(Stack: +1) Push a file onto the stack (interpreter takes it over).
lily_push_foreign(Stack: +1) Push a foreign class value onto the stack.
lily_push_hash(Stack: +1) Push a new Hash with ‘size’ slots reserved onto the stack.
lily_push_instance(Stack: +1) Push a user-defined class instance with ‘size’ values onto the stack.
lily_push_integer(Stack: +1) Push a new Integer onto the stack.
lily_push_list(Stack: +1) Push a List with ‘size’ values onto the stack.
lily_push_string(Stack: +1) Push a String wrapping over ‘source’ onto the stack.
lily_push_string_sized(Stack: +1) Push a String of ‘size’ bytes from ‘source’ onto the stack.
lily_push_super(Stack: +1) Push a superclass onto the stack.
lily_push_tuple(Stack: +1) Push a Tuple with ‘size’ values onto the stack.
lily_push_unit(Stack: +1) Push the unit value (of class Unit) onto the stack.
lily_push_value(Stack: +1) Push a full value onto the stack.
lily_push_variant(Stack: +1) Push a variant of ‘class_id’ and ‘size’ values onto the stack.
Macros
lily_push_failureShorthand for lily_push_variant with LILY_ID_FAILURE.
lily_push_noneShorthand for lily_push_empty_variant with LILY_ID_NONE.
lily_push_someShorthand for lily_push_some with LILY_ID_SOME.
lily_push_successShorthand for lily_push_success with LILY_ID_SUCCESS.

Functions

lily_push_boolean

void lily_push_boolean (lily_state *s,
int value)

(Stack: +1) Push a Boolean value onto the stack.

lily_push_byte

void lily_push_byte (lily_state *s,
uint8_t value)

(Stack: +1) Push a Byte value onto the stack.

lily_push_bytestring

void lily_push_bytestring (lily_state *s,
const char *source,
int size)

(Stack: +1) Push a ByteString value onto the stack.

lily_push_double

void lily_push_double (lily_state *s,
double value)

(Stack: +1) Push a Double value onto the stack.

lily_push_empty_variant

void lily_push_empty_variant(lily_state *s,
uint16_t class_id)

(Stack: +1) Push an empty variant (such as None) onto the stack.

lily_push_file

void lily_push_file (lily_state *s,
FILE *f,
const char *mode)

(Stack: +1) Push a file onto the stack (interpreter takes it over).

This uses the mode provided to determine what mode that the file was opened with.

Once the File goes out of scope, the interpreter’s destroy function for File will automatically close the file.

lily_push_foreign

lily_foreign_val * lily_push_foreign (lily_state *s,
uint16_t class_id,
lily_destroy_func destroy_fn,
size_t size)

(Stack: +1) Push a foreign class value onto the stack.

This function is called by dynaload bindings to create foreign class instances.  It should not be called directly.

lily_push_hash

lily_hash_val * lily_push_hash (lily_state *s,
int size)

(Stack: +1) Push a new Hash with ‘size’ slots reserved onto the stack.

lily_push_instance

lily_container_val *lily_push_instance (lily_state *s,
uint16_t class_id,
uint32_t size)

(Stack: +1) Push a user-defined class instance with ‘size’ values onto the stack.

This allocates ‘size’ values in the new instance.  Slots from 0 up to size1 must be filled before the instance is used.

lily_push_integer

void lily_push_integer (lily_state *s,
int64_t value)

(Stack: +1) Push a new Integer onto the stack.

lily_push_list

lily_container_val *lily_push_list (lily_state *s,
uint32_t size)

(Stack: +1) Push a List with ‘size’ values onto the stack.

This allocates ‘size’ values in the new List.  Slots from 0 up to size1 must be filled before the List is used.

lily_push_string

void lily_push_string (lily_state *s,
const char *source)

(Stack: +1) Push a String wrapping over ‘source’ onto the stack.

This creates a String value with a deep copy of ‘source’.

Caller is responsible for making sure that the new String value is valid.  The interpreter is built with the expectation that all String values are utf-8.  If the caller is unsure, the function ‘lily_is_valid_utf8’ can be used.

lily_push_string_sized

void lily_push_string_sized (lily_state *s,
const char *source,
int size)

(Stack: +1) Push a String of ‘size’ bytes from ‘source’ onto the stack.

This performs the same work as lily_push_string, except that ‘size’ bytes are copied from ‘source’ (instead of all of it).

The source should not include a zero terminator.  This function will add one at the very end.  Callers should instead make sure that there are no zero terminators in ‘source’ (at least for as much as ‘size’).

lily_push_super

lily_container_val *lily_push_super (lily_state *s,
uint16_t class_id,
uint32_t size)

(Stack: +1) Push a superclass onto the stack.

This is solely for use by foreign functions acting as a constructor.  Those functions are also required to use this function, as otherwise superclass values will not be completely initialized.

This function checks if there is a superclass currently in progress.  If so, then that existing value is pushed onto the stack.  Otherwise, it creates a new value with ‘size’ slots reserved.

In either case, the caller should then set the slots that are declared in the class it is creating.  An example would be inheriting Exception.  The Exception constructor should only initialize slots 0 and 1 (the message and traceback, respectively).  It should not worry about initialization of other slots.

This does not handle foreign classes inheriting other foreign classes, because the language does not support that (intentionally).

lily_push_tuple

lily_container_val *lily_push_tuple (lily_state *s,
uint32_t size)

(Stack: +1) Push a Tuple with ‘size’ values onto the stack.

This allocates ‘size’ values in the new Tuple.  Slots from 0 up to size1 must be filled before the Tuple is used.

lily_push_unit

void lily_push_unit (lily_state *s)

(Stack: +1) Push the unit value (of class Unit) onto the stack.

lily_push_value

void lily_push_value (lily_state *s,
lily_value *value)

(Stack: +1) Push a full value onto the stack.

lily_push_variant

lily_container_val *lily_push_variant (lily_state *s,
uint16_t class_id,
uint32_t size)

(Stack: +1) Push a variant of ‘class_id’ and ‘size’ values onto the stack.

This allocates ‘size’ values in the new variant.  Slots from 0 up to size1 must be filled before the variant is used.

Macros

lily_push_failure

Shorthand for lily_push_variant with LILY_ID_FAILURE.

lily_push_none

Shorthand for lily_push_empty_variant with LILY_ID_NONE.

lily_push_some

Shorthand for lily_push_some with LILY_ID_SOME.

lily_push_success

Shorthand for lily_push_success with LILY_ID_SUCCESS.

Returning a value

All foreign functions must finish by returning a value.

The most common return is ‘lily_return_top’, wherein a caller returns the value at the top of the stack.

Specific returns for pointer-based values are intentionally omitted.  Callers should instead use lily_return_top or lily_return_value, both of which retain the flags behind a value.

Summary
Functions
lily_return_booleanSet a Boolean return value.
lily_return_byteSet a Byte return value.
lily_return_doubleSet a Double return value.
lily_return_integerSet an Integer return value.
lily_return_noneSet a None return value.
lily_return_superUse this if lily_push_super was used.
lily_return_topSet the return value as the value currently at the top of the stack.
lily_return_unitSet a Unit return value.
lily_return_valueSet the value given as the return value.

Functions

lily_return_boolean

void lily_return_boolean(lily_state *s,
int value)

Set a Boolean return value.

lily_return_byte

void lily_return_byte (lily_state *s,
uint8_t value)

Set a Byte return value.

lily_return_double

void lily_return_double (lily_state *s,
double value)

Set a Double return value.

lily_return_integer

void lily_return_integer(lily_state *s,
int64_t value)

Set an Integer return value.

lily_return_none

void lily_return_none (lily_state *s)

Set a None return value.

lily_return_super

void lily_return_super (lily_state *s)

Use this if lily_push_super was used.

lily_return_top

void lily_return_top (lily_state *s)

Set the return value as the value currently at the top of the stack.

lily_return_unit

void lily_return_unit (lily_state *s)

Set a Unit return value.

lily_return_value

void lily_return_value (lily_state *s,
lily_value *value)

Set the value given as the return value.

Value extraction

Extract a raw value from a full value.

Assumes that the caller knows the correct underlying value.

Summary
Functions
lily_as_booleanExtract a Boolean.
lily_as_byteExtract a Byte.
lily_as_bytestringExtract a ByteString.
lily_as_containerExtract a container (user-defined class, non-empty variant, List, or Tuple).
lily_as_coroutineExtract a Coroutine.
lily_as_doubleExtract a Double.
lily_as_fileExtract a File.
lily_as_functionExtract a Function.
lily_as_genericExtract a generic pointer (to be cast to some other type)..
lily_as_hashExtract a Hash.
lily_as_integerExtract a Integer.
lily_as_stringExtract a String.
lily_as_string_rawExtract the raw buffer behind a String.

Functions

lily_as_boolean

int lily_as_boolean (lily_value *value)

Extract a Boolean.

lily_as_byte

uint8_t lily_as_byte (lily_value *value)

Extract a Byte.

lily_as_bytestring

lily_bytestring_val *lily_as_bytestring(lily_value *value)

Extract a ByteString.

lily_as_container

lily_container_val * lily_as_container (lily_value *value)

Extract a container (user-defined class, non-empty variant, List, or Tuple).

lily_as_coroutine

lily_coroutine_val * lily_as_coroutine (lily_value *value)

Extract a Coroutine.

lily_as_double

double lily_as_double (lily_value *value)

Extract a Double.

lily_as_file

lily_file_val * lily_as_file (lily_value *value)

Extract a File.

lily_as_function

lily_function_val * lily_as_function (lily_value *value)

Extract a Function.

lily_as_generic

lily_generic_val * lily_as_generic (lily_value *value)

Extract a generic pointer (to be cast to some other type)..

lily_as_hash

lily_hash_val * lily_as_hash (lily_value *value)

Extract a Hash.

lily_as_integer

int64_t lily_as_integer (lily_value *value)

Extract a Integer.

lily_as_string

lily_string_val * lily_as_string (lily_value *value)

Extract a String.

lily_as_string_raw

char * lily_as_string_raw(lily_value *value)

Extract the raw buffer behind a String.

Calling a function

Functions for calling back into the interpreter.

These functions should only be called when the interpreter is inside a foreign function, or outside of a parse/render call.  Do not invoke these functions from a dynaload loader or a hook.

Summary
Functions
lily_call(Stack: -count) Perform a prepared call using values from the stack.
lily_call_prepare(Stack: +1) Reserve a result register and prepare ‘func’.
lily_call_resultReturn the register that ‘lily_call_prepare’ reserved.

Functions

lily_call

void lily_call(lily_state *s,
int count)

(Stack: -count) Perform a prepared call using values from the stack.

This function performs a single call into the interpreter.  The call in question does not trap for exceptions, so exceptions raised by this call will pass through the caller.

This takes ‘count’ values off of the top of the stack.  The section on argument handling details how various features (varargs, optargs, and keyargs) are implemented.  Refer to that for how to call those kinds of functions.

Function calls always have a result.  The result is stored in the register that was returned by the last call to ‘lily_call_prepare’.  If a caller wants to save the result of a function call, it can use lily_push_value to push the result onto the stack.

lily_call_prepare

void lily_call_prepare(lily_state *s,
lily_function_val *func)

(Stack: +1) Reserve a result register and prepare ‘func’.

This function **must** be called **before** pushing arguments to a function.  The function given is prepared so that subsequent calls to ‘lily_call’ will invoke it.  Many functions in Lily’s standard library (maps, selects, rejects) like to call the same function multiple times.  Having prep outside of call makes it so that the interpreter does not do repeated repeated prep work for each calls.  A single prep works for any number of subsequent ‘lily_call’ invocations.

The other job of this function is to set a result storage.  The result storage lives below a function’s arguments and is updated each time the function is called.  Callers that want to save the value can slide it over where they want it or push a copy onto the stack.

If the caller wants to switch the target function often, the caller should make sure to pop the results that are stored.  Otherwise, the interpreter’s stack can accumulate result values.

lily_call_result

lily_value *lily_call_result(lily_state *s)

Return the register that ‘lily_call_prepare’ reserved.

The value itself (not the contents) is valid until the next ‘lily_call_prepare’, or when the called foreign function goes out of scope.

Exception raise

Functions for raising an exception.

Each of these functions raises a specific exception.  The format string goes by the same rules that ‘lily_msgbuf_add_fmt’ goes by, because it (and the arguments) are sent to that function.

These functions must only be called when inside a foreign function.

Summary
Functions
lily_DivisionByZeroErrorRaise DivisionByZeroError with the given message and args.
lily_IndexErrorRaise IndexError with the given message and args.
lily_IOErrorRaise IOError with the given message and args.
lily_KeyErrorRaise KeyError with the given message and args.
lily_RuntimeErrorRaise RuntimeError with the given message and args.
lily_ValueErrorRaise ValueError with the given message and args.

Functions

lily_DivisionByZeroError

void lily_DivisionByZeroError(lily_state *s,
const char *format,
 ...)

Raise DivisionByZeroError with the given message and args.

lily_IndexError

void lily_IndexError(lily_state *s,
const char *format,
 ...)

Raise IndexError with the given message and args.

lily_IOError

void lily_IOError(lily_state *s,
const char *format,
 ...)

Raise IOError with the given message and args.

lily_KeyError

void lily_KeyError(lily_state *s,
const char *format,
 ...)

Raise KeyError with the given message and args.

lily_RuntimeError

void lily_RuntimeError(lily_state *s,
const char *format,
 ...)

Raise RuntimeError with the given message and args.

lily_ValueError

void lily_ValueError(lily_state *s,
const char *format,
 ...)

Raise ValueError with the given message and args.

Error callbacks

Foreign function cleanup.

Summary
Types
lily_error_callback_funcCallback for when lily_call raises an exception.
Functions
lily_error_callback_pushPush an error callback for the current foreign function.
lily_error_callback_popRemove an error callback (typically at foreign function exit).

Types

lily_error_callback_func

Callback for when lily_call raises an exception.

Error callbacks are invoked when lily_call has raised an exception that will go outside the invoking foreign function.  The callback is given a state that has the same stack bottom as when the foreign function registering it had when first called.

One use of error functions in the builtin api is to drop the iteration count of hashes.  This makes them eligible for alteration again, as hashes that are being iterated over cannot be altered.

Functions

lily_error_callback_push

void lily_error_callback_push(lily_state *s,
lily_error_callback_func callback_fn)

Push an error callback for the current foreign function.

lily_error_callback_pop

void lily_error_callback_pop(lily_state *s)

Remove an error callback (typically at foreign function exit).

A foreign function must call this for every error callback it registered if no error was raised.

Stack operations

Operations working on the top of the stack.

Summary
Functions
lily_stack_drop_topPop the top of the stack, deref-ing it if necessary.
lily_stack_get_topReturn the value at the top of the stack.

Functions

lily_stack_drop_top

void lily_stack_drop_top(lily_state *s)

Pop the top of the stack, deref-ing it if necessary.

lily_stack_get_top

lily_value *lily_stack_get_top(lily_state *s)

Return the value at the top of the stack.

Message buffer operations

A wrapper over an automatically-growing buffer.

Summary
Types
lily_msgbufOpaque typedef for a msgbuf.
Functions
lily_new_msgbufCreate a new msgbuf with a starting size of ‘size’.
lily_free_msgbufFree a msgbuf struct and the underlying buffer.
lily_mb_addAdd ‘source’ to the msgbuf.
lily_mb_add_charAdd a single character ‘ch’ to the msgbuf.
lily_mb_add_fmtAdd to the msgbuf based on a format string.
lily_mb_add_fmt_valily_mb_add_fmt, but using a va_list.
lily_mb_add_sliceAdd ‘source’ to the msgbuf, from ‘start’ to ‘end’.
lily_mb_add_valueInterpolate a value into the msgbuf.
lily_mb_flushDrop all contents in the msgbuf.
lily_mb_rawReturn the underlying buffer of a msgbuf.
lily_mb_posReturn the length of the msgbuf.
lily_mb_html_escapeAdd html-escaped version of ‘input’ to the msgbuf.
lily_mb_sprintfEquivalent to flush, add_fmt, returning the underlying buffer.
lily_msgbuf_getReturn the common msgbuf of the interpreter.

Types

lily_msgbuf

Opaque typedef for a msgbuf.

A message buffer (msgbuf for short) is a buffer with methods to add text that also grow it if necessary.  The msgbuf also zero-terminates the internal buffer after every method adding data.

The interpreter provides a general-purpose buffer (‘lily_msgbuf_get’) that operations can use if they know they’ll be working with a small string.

It is the responsibility of the caller to flush a msgbuf **before** it is used, not after.  By making it the responsibility at the start of a function, a caller that doesn’t flush a msgbuf before use becomes obvious.  Note that ‘lily_msgbuf_get’ automatically does that flushing.

Functions that need to store a potentially large amount of text should create their own temporary msgbuf.  Do note that the msgbuf never receives an interpreter object, and therefore the interpreter will not clean up temporary msgbuf’s for a caller.

Functions

lily_new_msgbuf

lily_msgbuf *lily_new_msgbuf(uint32_t size)

Create a new msgbuf with a starting size of ‘size’.

lily_free_msgbuf

void lily_free_msgbuf(lily_msgbuf *msgbuf)

Free a msgbuf struct and the underlying buffer.

Unlike destroying a value, this process is very straightforward.

lily_mb_add

void lily_mb_add(lily_msgbuf *msgbuf,
const char *source)

Add ‘source’ to the msgbuf.

lily_mb_add_char

void lily_mb_add_char(lily_msgbuf *msgbuf,
char ch)

Add a single character ‘ch’ to the msgbuf.

lily_mb_add_fmt

void lily_mb_add_fmt(lily_msgbuf *msgbuf,
const char *format,
 ...)

Add to the msgbuf based on a format string.

The following format characters are supported

%dint
%cchar
%schar *
%pvoid *
%lldint64_t
%%A single % character.
^Tlily_type * (internal use only).

lily_mb_add_fmt_va

void lily_mb_add_fmt_va(lily_msgbuf *msgbuf,
const char *format,
 va_list)

lily_mb_add_fmt, but using a va_list.

lily_mb_add_slice

void lily_mb_add_slice(lily_msgbuf *msgbuf,
const char *source,
int start,
int end)

Add ‘source’ to the msgbuf, from ‘start’ to ‘end’.

lily_mb_add_value

void lily_mb_add_value(lily_msgbuf *msgbuf,
lily_state *s,
lily_value *value)

Interpolate a value into the msgbuf.

lily_mb_flush

lily_msgbuf *lily_mb_flush(lily_msgbuf *msgbuf)

Drop all contents in the msgbuf.

lily_mb_raw

const char *lily_mb_raw(lily_msgbuf *msgbuf)

Return the underlying buffer of a msgbuf.

The buffer can be invalidated by any method that adds to the buffer.

lily_mb_pos

int lily_mb_pos(lily_msgbuf *msgbuf)

Return the length of the msgbuf.

lily_mb_html_escape

const char *lily_mb_html_escape(lily_msgbuf *msgbuf,
const char *input)

Add html-escaped version of ‘input’ to the msgbuf.

lily_mb_sprintf

const char *lily_mb_sprintf(lily_msgbuf *msgbuf,
const char *format,
 ...)

Equivalent to flush, add_fmt, returning the underlying buffer.

lily_msgbuf_get

lily_msgbuf *lily_msgbuf_get(lily_state *)

Return the common msgbuf of the interpreter.

Foreign bits

Items of interest for putting a foreign class into Lily.

Summary
Macros
LILY_FOREIGN_HEADERPut this macro at the top of any struct that is later introduced as a foreign class to the interpreter.
Types
lily_destroy_funcHook called when a value is to be destroyed.

Macros

LILY_FOREIGN_HEADER

Put this macro at the top of any struct that is later introduced as a foreign class to the interpreter.

Types

lily_destroy_func

Hook called when a value is to be destroyed.

This callback receives a generic_val, which is to be cast to the instance to be destroyed.  The callback is responsible for destroying what exists inside of the value.

The value itself should not be destroyed, because the interpreter will do that once the callback has returned.

Miscellaneous

Miscellaneous operations that don’t fit elsewhere.

Summary
Functions
lily_find_functionSearch for a function called ‘name’.
lily_register_moduleMake a module called ‘name’ available to the interpreter.
lily_is_valid_utf8Check if ‘source’ is valid utf-8.
lily_value_tagPlace a gc tag onto ‘value’.
lily_cid_atFunction for autogenerated ID_* macros to get a class id.

Functions

lily_find_function

lily_function_val *lily_find_function(lily_state *s,
const char *name)

Search for a function called ‘name’.

The search executes as if ‘name’ was typed in the first file loaded.  This function is currently limited, as it only accepts just a name (no namespace lookup or class lookup).

Returns a function on success, NULL on failure.

lily_register_module

Make a module called ‘name’ available to the interpreter.

A registered module is available anywhere in the interpreter, but must still be explicitly loaded through the import keyword.

This function must be called after the interpreter object is created, but before any parsing begins.

lily_is_valid_utf8

int lily_is_valid_utf8(const char *source)

Check if ‘source’ is valid utf-8.

lily_value_tag

void lily_value_tag(lily_state *s,
lily_value *value)

Place a gc tag onto ‘value’.  May invoke a sweep.

lily_cid_at

uint16_t lily_cid_at(lily_state *s,
int index)

Function for autogenerated ID_* macros to get a class id.

typedef struct lily_config_
All interpreter config info goes here.
void lily_config_init(lily_config *config)
Initialize a config to default values.
lily_config *lily_config_get(lily_state *s)
Fetch an interpreter’s config struct.
lily_state *lily_new_state(lily_config *config)
Create a new interpreter.
void lily_free_state(lily_state *s)
Destroy an interpreter and any values it holds.
int lily_load_file(lily_state *s,
const char *path)
Prepare a file for the interpreter.
int lily_load_string(lily_state *s,
const char *context,
const char *str)
Prepare a string for the interpreter.
int lily_parse_content(lily_state *s)
Parse content prepared for the interpreter.
int lily_render_content(lily_state *s)
Parse content prepared for the interpreter.
int lily_parse_expr(lily_state *s,
const char **output)
Parse an expression prepared for the interpreter.
const char *lily_error_message(lily_state *s)
Fetch the message and traceback of the last failed parse/render.
const char *lily_error_message_no_trace(lily_state *s)
Fetch only the message of the last failed parse/render.
void lily_default_import_func(lily_state *s,
const char *target)
This is the default import hook.
int lily_import_file(lily_state *s,
const char *target)
Import a file for the interpreter.
int lily_import_library(lily_state *s,
const char *target)
Load a library from a given path.
int lily_import_library_data(lily_state *s,
const char *target,
const char **info_table,
lily_call_entry_func *call_table)
Load a preloaded library.
int lily_import_string(lily_state *s,
const char *target,
const char *content)
Load a string (context path, then content) as a library.
void lily_import_use_local_dir(lily_state *s,
const char *dir)
Use a local directory for upcoming imports.
const char *lily_import_current_root_dir(lily_state *s)
Return the directory of the package that the source import belongs to.
char *lily_bytestring_raw(lily_bytestring_val *byte_val)
Get the raw buffer behind a ByteString.
int lily_bytestring_length(lily_bytestring_val *byte_val)
Get the size (in bytes) of a ByteString.
lily_value *lily_con_get(lily_container_val *con,
int index)
Fetch an element from a container.
void lily_con_set(lily_container_val *con,
int index,
lily_value *value)
Set an element into a container.
void lily_con_set_from_stack(lily_state *s,
lily_container_val *con,
int index)
(Stack: -1) Set an element into a container from the stack.
uint32_t lily_con_size(lily_container_val *con)
Return the number of occupied values in a container.
FILE *lily_file_for_read(lily_state *s,
lily_file_val *file)
Return the underlying FILE * of a File (if in read mode), or raise IOError.
FILE *lily_file_for_write(lily_state *s,
lily_file_val *file)
Return the underlying FILE * of a File (if in write mode), or raise IOError.
int lily_function_is_foreign(lily_function_val *func)
Return 1 if the Function has a foreign implementation, 0 otherwise.
int lily_function_is_native(lily_function_val *func)
Return 1 if the Function has a native implementation, 0 otherwise.
lily_value *lily_hash_get(lily_state *s,
lily_hash_val *hash,
lily_value *key)
Look for a given key within a Hash.
void lily_hash_set(lily_state *s,
lily_hash_val *hash,
lily_value *key,
lily_value *record)
Set ‘key’ to ‘value’ within a given hash.
void lily_hash_set_from_stack(lily_state *s,
lily_hash_val *hash)
(Stack: -2) lily_hash_set, but key and value come from the stack.
int lily_hash_take(lily_state *s,
lily_hash_val *hash,
lily_value *key)
(Stack: +1?)
void lily_list_insert(lily_container_val *con,
int index,
lily_value *value)
Insert a value, pushing others to the right.
void lily_list_reserve(lily_container_val *con,
int size)
Reserve N elements in a List.
void lily_list_take(lily_state *s,
lily_container_val *con,
int index)
(Stack: +1) Take an element out of a List, pushing it onto the stack.
void lily_list_push(lily_container_val *con,
lily_value *value)
Push a value onto the end of a List.
char *lily_string_raw(lily_string_val *string_val)
Returns the raw buffer behind a String.
int lily_string_length(lily_string_val *string_val)
Returns the size (in bytes) of a String buffer.
int lily_arg_boolean (lily_state *s,
int index)
Fetch a Boolean from the stack.
uint8_t lily_arg_byte (lily_state *s,
int index)
Fetch a Byte from the stack.
lily_bytestring_val *lily_arg_bytestring(lily_state *s,
int index)
Fetch a ByteString from the stack.
lily_container_val * lily_arg_container (lily_state *s,
int index)
Fetch a user-defined class, (non-empty) variant, List, or Tuple.
lily_coroutine_val * lily_arg_coroutine (lily_state *s,
int index)
Fetch a Coroutine from the stack.
double lily_arg_double (lily_state *s,
int index)
Fetch a Double from the stack.
lily_file_val * lily_arg_file (lily_state *s,
int index)
Fetch a File from the stack.
lily_function_val * lily_arg_function (lily_state *s,
int index)
Fetch a Function from the stack.
lily_generic_val * lily_arg_generic (lily_state *s,
int index)
Fetch a pointer-based (foreign) value from the stack.
lily_hash_val * lily_arg_hash (lily_state *s,
int index)
Fetch a Hash from the stack.
int64_t lily_arg_integer (lily_state *s,
int index)
Fetch a Integer from the stack.
lily_string_val * lily_arg_string (lily_state *s,
int index)
Fetch a String from the stack.
char * lily_arg_string_raw(lily_state *s,
int index)
Fetch the underlying buffer of a String from the stack.
lily_value * lily_arg_value (lily_state *s,
int index)
Fetch a complete value with flags and class information.
int lily_arg_count(lily_state *s)
How many arguments the function being called was given.
int lily_arg_isa(lily_state *s,
int index,
uint16_t class_id)
Check if an argument has an exact class id.
void lily_push_boolean (lily_state *s,
int value)
(Stack: +1) Push a Boolean value onto the stack.
void lily_push_byte (lily_state *s,
uint8_t value)
(Stack: +1) Push a Byte value onto the stack.
void lily_push_bytestring (lily_state *s,
const char *source,
int size)
(Stack: +1) Push a ByteString value onto the stack.
void lily_push_double (lily_state *s,
double value)
(Stack: +1) Push a Double value onto the stack.
void lily_push_empty_variant(lily_state *s,
uint16_t class_id)
(Stack: +1) Push an empty variant (such as None) onto the stack.
void lily_push_file (lily_state *s,
FILE *f,
const char *mode)
(Stack: +1) Push a file onto the stack (interpreter takes it over).
lily_foreign_val * lily_push_foreign (lily_state *s,
uint16_t class_id,
lily_destroy_func destroy_fn,
size_t size)
(Stack: +1) Push a foreign class value onto the stack.
lily_hash_val * lily_push_hash (lily_state *s,
int size)
(Stack: +1) Push a new Hash with ‘size’ slots reserved onto the stack.
lily_container_val *lily_push_instance (lily_state *s,
uint16_t class_id,
uint32_t size)
(Stack: +1) Push a user-defined class instance with ‘size’ values onto the stack.
void lily_push_integer (lily_state *s,
int64_t value)
(Stack: +1) Push a new Integer onto the stack.
lily_container_val *lily_push_list (lily_state *s,
uint32_t size)
(Stack: +1) Push a List with ‘size’ values onto the stack.
void lily_push_string (lily_state *s,
const char *source)
(Stack: +1) Push a String wrapping over ‘source’ onto the stack.
void lily_push_string_sized (lily_state *s,
const char *source,
int size)
(Stack: +1) Push a String of ‘size’ bytes from ‘source’ onto the stack.
lily_container_val *lily_push_super (lily_state *s,
uint16_t class_id,
uint32_t size)
(Stack: +1) Push a superclass onto the stack.
lily_container_val *lily_push_tuple (lily_state *s,
uint32_t size)
(Stack: +1) Push a Tuple with ‘size’ values onto the stack.
void lily_push_unit (lily_state *s)
(Stack: +1) Push the unit value (of class Unit) onto the stack.
void lily_push_value (lily_state *s,
lily_value *value)
(Stack: +1) Push a full value onto the stack.
lily_container_val *lily_push_variant (lily_state *s,
uint16_t class_id,
uint32_t size)
(Stack: +1) Push a variant of ‘class_id’ and ‘size’ values onto the stack.
void lily_return_boolean(lily_state *s,
int value)
Set a Boolean return value.
void lily_return_byte (lily_state *s,
uint8_t value)
Set a Byte return value.
void lily_return_double (lily_state *s,
double value)
Set a Double return value.
void lily_return_integer(lily_state *s,
int64_t value)
Set an Integer return value.
void lily_return_none (lily_state *s)
Set a None return value.
void lily_return_super (lily_state *s)
Use this if lily_push_super was used.
void lily_return_top (lily_state *s)
Set the return value as the value currently at the top of the stack.
void lily_return_unit (lily_state *s)
Set a Unit return value.
void lily_return_value (lily_state *s,
lily_value *value)
Set the value given as the return value.
int lily_as_boolean (lily_value *value)
Extract a Boolean.
uint8_t lily_as_byte (lily_value *value)
Extract a Byte.
lily_bytestring_val *lily_as_bytestring(lily_value *value)
Extract a ByteString.
lily_container_val * lily_as_container (lily_value *value)
Extract a container (user-defined class, non-empty variant, List, or Tuple).
lily_coroutine_val * lily_as_coroutine (lily_value *value)
Extract a Coroutine.
double lily_as_double (lily_value *value)
Extract a Double.
lily_file_val * lily_as_file (lily_value *value)
Extract a File.
lily_function_val * lily_as_function (lily_value *value)
Extract a Function.
lily_generic_val * lily_as_generic (lily_value *value)
Extract a generic pointer (to be cast to some other type)..
lily_hash_val * lily_as_hash (lily_value *value)
Extract a Hash.
int64_t lily_as_integer (lily_value *value)
Extract a Integer.
lily_string_val * lily_as_string (lily_value *value)
Extract a String.
char * lily_as_string_raw(lily_value *value)
Extract the raw buffer behind a String.
void lily_call(lily_state *s,
int count)
(Stack: -count) Perform a prepared call using values from the stack.
void lily_call_prepare(lily_state *s,
lily_function_val *func)
(Stack: +1) Reserve a result register and prepare ‘func’.
lily_value *lily_call_result(lily_state *s)
Return the register that ‘lily_call_prepare’ reserved.
void lily_DivisionByZeroError(lily_state *s,
const char *format,
 ...)
Raise DivisionByZeroError with the given message and args.
void lily_IndexError(lily_state *s,
const char *format,
 ...)
Raise IndexError with the given message and args.
void lily_IOError(lily_state *s,
const char *format,
 ...)
Raise IOError with the given message and args.
void lily_KeyError(lily_state *s,
const char *format,
 ...)
Raise KeyError with the given message and args.
void lily_RuntimeError(lily_state *s,
const char *format,
 ...)
Raise RuntimeError with the given message and args.
void lily_ValueError(lily_state *s,
const char *format,
 ...)
Raise ValueError with the given message and args.
void lily_error_callback_push(lily_state *s,
lily_error_callback_func callback_fn)
Push an error callback for the current foreign function.
void lily_error_callback_pop(lily_state *s)
Remove an error callback (typically at foreign function exit).
void lily_stack_drop_top(lily_state *s)
Pop the top of the stack, deref-ing it if necessary.
lily_value *lily_stack_get_top(lily_state *s)
Return the value at the top of the stack.
lily_msgbuf *lily_new_msgbuf(uint32_t size)
Create a new msgbuf with a starting size of ‘size’.
void lily_free_msgbuf(lily_msgbuf *msgbuf)
Free a msgbuf struct and the underlying buffer.
void lily_mb_add(lily_msgbuf *msgbuf,
const char *source)
Add ‘source’ to the msgbuf.
void lily_mb_add_char(lily_msgbuf *msgbuf,
char ch)
Add a single character ‘ch’ to the msgbuf.
void lily_mb_add_fmt(lily_msgbuf *msgbuf,
const char *format,
 ...)
Add to the msgbuf based on a format string.
void lily_mb_add_fmt_va(lily_msgbuf *msgbuf,
const char *format,
 va_list)
lily_mb_add_fmt, but using a va_list.
void lily_mb_add_slice(lily_msgbuf *msgbuf,
const char *source,
int start,
int end)
Add ‘source’ to the msgbuf, from ‘start’ to ‘end’.
void lily_mb_add_value(lily_msgbuf *msgbuf,
lily_state *s,
lily_value *value)
Interpolate a value into the msgbuf.
lily_msgbuf *lily_mb_flush(lily_msgbuf *msgbuf)
Drop all contents in the msgbuf.
const char *lily_mb_raw(lily_msgbuf *msgbuf)
Return the underlying buffer of a msgbuf.
int lily_mb_pos(lily_msgbuf *msgbuf)
Return the length of the msgbuf.
const char *lily_mb_html_escape(lily_msgbuf *msgbuf,
const char *input)
Add html-escaped version of ‘input’ to the msgbuf.
const char *lily_mb_sprintf(lily_msgbuf *msgbuf,
const char *format,
 ...)
Equivalent to flush, add_fmt, returning the underlying buffer.
lily_msgbuf *lily_msgbuf_get(lily_state *)
Return the common msgbuf of the interpreter.
lily_function_val *lily_find_function(lily_state *s,
const char *name)
Search for a function called ‘name’.
int lily_is_valid_utf8(const char *source)
Check if ‘source’ is valid utf-8.
void lily_value_tag(lily_state *s,
lily_value *value)
Place a gc tag onto ‘value’.
uint16_t lily_cid_at(lily_state *s,
int index)
Function for autogenerated ID_* macros to get a class id.
Close