As demonstrated in main.cpp, the following API functions are for building an executable program:
void* api_load_module(const char* fname, char *error)
-- Creates a module, loads script from the file, and then execute;
copies error message, if any, to error and returns the module object.
void api_cleanup()
-- cleanup z-script virtual machine.
void api_add_arg_ikey(int key, const char* value)
void api_add_arg_skey(const char* key, const char* value)
-- adds the key-value to be extracted by the build-in getarg(key) function.
void api_add_path(const char *path)
-- adds path for searching modules.
In certain situation, you may want to insert objects to the module and exeucte the module again; then use these tow functions:
int api_set_module_object(void* module, const char* name, void *object)
-- Sets the object to the named variable in the module and returns negative
value in case of error. You should use api_create_* functions to create the object.
int api_exec_module(void* module, char *error)
-- Executes the module again and return nagative value in case of error.
Or you may want execute a string as if it is the content of a module:
char* api_exec_string(const char* str, char *error)
You may build dynamic link libraries (DLL) of primitive functions by including api.h (and scan.h if you need to define operators for you objects) in your C or C++ source code and linking with zs.lib. A primitive function must have the prototype of
void *func(void *caller, int nargs, **args);
Where the caller is the expression in a scripting program that calls the function. The number of arguments and the arguments are passed to the function as nargs and args.
A primitive function may be registered to Z-Script by using the function
void api_add_primitive(const char* name, int type, void* func)
You should assign a distinguished type ID to your object. Z-Script uses the ID to prevent name clash of functions. That is that the registered name of a primitive function will be formed with the type ID attached to the given name. And when the primitive is called as
obj:func(...);
Z-Script will look for the function named func with the type ID attached when obj is a user object. The search starts first in the hash table for for primitive functions and then in the hash table for script functions. A primitive function may return null or an object create by one of the API functions:
void* api_create_null()
-- creates a null object.
void* api_create_integer(int value)
-- creates a integer type object.
void* api_create_real(double value)
-- creates a real type object.
void* api_create_string(const char* str)
-- creates a string type object.
void* api_create_array(size)
-- creates a array type object.
void* api_create_user(void* ptr, void* opfunc, void* destroy, int type)
-- creates a user type object.
The opfunc pointer in api_create_user() may be null or pointing to a primitive function that will be called when a user object is an operand of a operator. The first argument passed to opfunc will be the user object, the second will be the operator id (ref. scan.h), and the third will be null for unary operators or another object for binary operators. The destroy pointer may point to a function of the prototype
void destroy(void *ptr)
that will be called when Z-Script is about to delete the user object.
In a primitive function, you may use these functions to query the object type of an argument:
bool api_is_null(void *object)
-- returns true is the object is null; returns false otherwise.
bool api_is_integer(void* object)
-- returns true is the object is integer; returns false otherwise.
bool api_is_real(void* object)
-- returns true is the object is real (double); returns false otherwise.
bool api_is_number(void *object)
-- returns true is the object is integer or real; returns false otherwise.
bool api_is_string(void *object)
-- returns true is the object is string; returns false otherwise.
bool api_is_array(void *object)
-- returns true is the object is array; returns false otherwise.
bool api_is_user(void *object)
-- returns true is the object is user type; returns false otherwise.
int api_get_type(void *object)
-- returns the object type ID.
If you are expecting a certain type of object, you may use the following functions to extract object values. They will throw an error when the object type is not what your are asking for.
int api_get_integer(void *caller, void* object)
-- asserts that the object is integer and returns its value.
double api_get_real(void *caller, void* object)
-- asserts that the object is real and returns its value.
double api_get_number(void *caller, void* object)
-- asserts that the object is integer or real and returns its value.
const char* api_get_string(void* caller, void* object)
-- asserts that the object is string and returns the pointer to the string.
void* api_get_ptr(void *caller, void *user)
-- asserts that the object is user type and return the pointer
that is passed to api_create_user function.
int api_get_array_size(void *object)
-- returns the size of the array object.
void* api_get_array_object(void *caller, void* array, const char* key)
void* api_get_array_object2(void *caller, void* array, int key)
-- asserts that the array type is correct
and return the object corresponding to the key.
void* api_peek_array_object(void* array, const char* key)
void* api_peek_array_object2(void* array, int key)
-- tries to get the object corresponding to the key from the array
and returns null if failed.
void api_set_array_object(void *caller, void* array, const char* key, void* value)
void api_set_array_object2(void *caller, void* array, int key, void* value)
-- asserts that the array type is correct, removes the key/value first,
and then sets the key/value in the array.
Calling script function from your primitive functions may be achieved through these functions:
void* api_get_func(void *caller, const char* name)
-- returns the pointer to the named script function;
throw error is the function is not declared in script.
void* api_call_func(void *func, int nargs, void** args)
-- call script function with arguments
And finally, you should let the caller to handle critical error using this function:
void api_runtime_error(const void *caller, const char* msg)
If__get and __set primitives are defined for user objects, the __get function will be called in an array access expression (e.g., a = u[1]) and the __set function will be called in an expression of array assignment (e.g., u[1] = a) when u is a user object. This powerful feature lets users to handle their own arrays in whatever way they like. The first argument passed to __get and __set is u, the second argument is the first index, and so on. For the __set function, the last argument is the object to be assigned to the u. Refer to the matrix library for implementation details.