(API for version 1.3 is here)
As demonstrated in main.cpp, the following API functions are for building an executable program:
void* api_parse_file(const char* fname, char *error)
-- Parses script in the file and returns a module or NULL in case of error.
The second variable must point to memory (>= 256 bytes) for error message.
void* api_parse_string(void *string, char *error)
-- Parses script in the string and returns a module or NULL in case of error.
int api_exec_module(void *module, char *error)
-- Executes the module and return a negative integer if failed.
The second variable must point to memory (>= 256 bytes) for error message.
void api_delete_module(void *module)
-- Delete the module and release resources allocated by the module.
void api_set_module_object(void *module, const char *name, void *ptr, int type)
-- Sets a user object to the module.
void* api_get_module_object(void *module, const char *name)
-- Gets a module object by name.
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.
A module manages its own memoy and imported modules and may be executed many times. But in a thread-safe application, each thread should parse script files independently.
You may build dynamic link libraries (DLL) of primitive functions by including api.h (and scan.h if you want to redefine operators for you objects) in your C or C++ source code and linking the library to 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 with nargs-number of arguments (args). A primitive function may be registered to Z-Script by calling 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 with the name of func+ID, e.g. func4835. 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(caller)
-- creates a null object.
void* api_create_integer(caller, int value)
-- creates a integer type object.
void* api_create_real(caller, double value)
-- creates a real type object.
void* api_create_string(caller, const char* str)
-- creates a string type object.
void* api_create_array(caller, size)
-- creates a array type object with the given hash table size.
void* api_create_user(caller, void* ptr, void* opfunc, void* destroy, int type)
-- creates a user type object.
The opfunc pointer in api_create_user() may be NULL or the address of 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 function 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 just 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 a user object, 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. Further more, when * is used as an array index argument, it is treated as a null input, e.g, a[*,1] is equavalent to a[null,1]. Refer to the matrix library for implementation details.