~brenns10/funlisp

0aae20ef7dc8f84b6d1b62176701f4b97bcc4100 — Stephen Brennan 1 year, 8 months ago 93e63f6
Make module api public
4 files changed, 93 insertions(+), 15 deletions(-)

M doc/api.rst
M inc/funlisp.h
M src/funlisp_internal.h
M src/module.c
M doc/api.rst => doc/api.rst +6 -0
@@ 39,6 39,12 @@ Builtin Functions
.. doxygengroup:: builtins
   :content-only:

Modules
-------

.. doxygengroup:: modules
   :content-only:

Embedding Tools
---------------


M inc/funlisp.h => inc/funlisp.h +70 -0
@@ 724,6 724,76 @@ int lisp_get_args(lisp_runtime *rt, lisp_list *list, char *format, ...);

/**
 * @}
 * @defgroup modules Modules
 * @{
 */

/**
 * @brief Create a new, empty module object.
 *
 * The module object represents a separate namespace which can contain symbols
 * mapped to builtins, lambdas, constants, and more. It is a great place to
 * store related functionality. The module can represent all of the symbols
 * defined in a single lisp file. It can also represent a collection of
 * resources created by C code.
 *
 * C code which wishes to create a module should start here, access the scope
 * from the resulting module using lisp_module_get_scope(), and populate the
 * scope with any builtins or other data necessary. Finally, modules should be
 * registered with the runtime using lisp_register_module().
 *
 * @param rt runtime
 * @param name the name of the module, used for imports
 * @param file filename for the module object. This file is not actually loaded,
 * simply stored as part of the module metadata. If you would like to load a
 * file as a module, see lisp_import_file().
 * @return a new, empty module object
 */
lisp_module *lisp_new_module(lisp_runtime *rt, lisp_string *name, lisp_string *file);

/**
 * @brief Given a module returned by lisp_new_module(), access its scope
 * @param module A module to get the scope of
 * @return the scope of that module
 */
lisp_scope *lisp_module_get_scope(lisp_module *module);

/**
 * @brief Given a module object, register it with the runtime
 *
 * The module is mapped using the name given at creation time. For example, if a
 * module was given the name ``foo``, then it can be imported with the statement
 * ``(import foo)``.
 *
 * @param rt runtime
 * @param module module to register
 */
void lisp_register_module(lisp_runtime *rt, lisp_module *module);

/**
 * @brief Load a file of lisp code and return it as a module object.
 * @param name Name for the resulting module
 * @param file Filename to read and load as a module
 * @return the resulting module
 */
lisp_module *lisp_import_file(lisp_runtime *rt, lisp_string *name, lisp_string *file);

/**
 * @brief Given a module name, import and return it if possible, or raise error
 *
 * This process works as follows. First, check whether an existing module has
 * already been registered by that name. If so, return it. Second, attempt to
 * read ``./NAME.lisp`` as a lisp file, and return that as a module. Raise error
 * on failure.
 *
 * @param rt runtime
 * @param name name of module to import
 * @return the resulting module
 */
lisp_module *lisp_do_import(lisp_runtime *rt, lisp_symbol *name);

/**
 * @}
 * @defgroup embed Embedding API
 * @{
 */

M src/funlisp_internal.h => src/funlisp_internal.h +0 -5
@@ 196,12 196,7 @@ void lisp_textcache_remove(struct hashtable *cache, struct lisp_text *t);

int lisp_truthy(lisp_value *v);

/* Module stuff, will become public eventually, but for now is private */
lisp_module *create_os_module(lisp_runtime *rt);
void lisp_register_module(lisp_runtime *rt, lisp_module *m);
lisp_module *lisp_lookup_module(lisp_runtime *rt, lisp_symbol *name);

lisp_module *lisp_import_file(lisp_runtime *rt, lisp_string *name, lisp_string *file);
lisp_module *lisp_do_import(lisp_runtime *rt, lisp_symbol *name);
int get_errno(void);
#endif

M src/module.c => src/module.c +17 -10
@@ 26,19 26,12 @@ static lisp_value *lisp_os_getenv(lisp_runtime *rt, lisp_scope *scope,
		return lisp_nil_new(rt);
}

static void build_example_module(lisp_runtime *rt, lisp_module *m)
{
	lisp_scope_add_builtin(rt, m->contents, "getenv", lisp_os_getenv, NULL, 1);
}

lisp_module *create_os_module(lisp_runtime *rt)
{
	lisp_module *m = (lisp_module *) lisp_new(rt, type_module);
	m->name = lisp_string_new(rt, "os", 0);
	m->file = lisp_string_new(rt, __FILE__, 0);
	m->contents = lisp_new_empty_scope(rt);

	build_example_module(rt, m);
	lisp_module *m = lisp_new_module(rt, lisp_string_new(rt, "os", 0),
		lisp_string_new(rt, __FILE__, 0));
	lisp_scope_add_builtin(rt, m->contents, "getenv", lisp_os_getenv, NULL, 1);
	return m;
}



@@ 59,6 52,20 @@ lisp_module *lisp_lookup_module(lisp_runtime *rt, lisp_symbol *name)
	return m;
}

lisp_module *lisp_new_module(lisp_runtime *rt, lisp_string *name, lisp_string *file)
{
	lisp_module *m = (lisp_module *)lisp_new(rt, type_module);
	m->name = name;
	m->file = file;
	m->contents = lisp_new_empty_scope(rt);
	return m;
}

lisp_scope *lisp_module_get_scope(lisp_module *module)
{
	return module->contents;
}

lisp_module *lisp_import_file(lisp_runtime *rt, lisp_string *name, lisp_string *file)
{
	FILE *f;