klisp

an open source interpreter for the Kernel Programming Language.
git clone http://git.hanabi.in/repos/klisp.git
Log | Files | Refs | README

commit 5dbb785c88a1d106ffa8e5649a41fec153535cb4
parent 7dae242b9a8adb572aa435f779a4eb7ea6d1cae4
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Mon, 12 Dec 2011 04:45:33 -0300

Bugfix in require (empty check after klispH_get). Added applicatives find-required-file, registered-requirement?, register-requirement!, unregister-requirement! to allow imitation or require functionality.

Diffstat:
Msrc/kgports.c | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 82 insertions(+), 2 deletions(-)

diff --git a/src/kgports.c b/src/kgports.c @@ -862,7 +862,6 @@ static TValue find_file (klisp_State *K, TValue name, TValue pname) { ** - When/if the file is found, evaluation happens in an initially ** standard environment */ -/* TODO check if file was required */ void require(klisp_State *K) { TValue *xparams = K->next_xparams; @@ -886,7 +885,7 @@ void require(klisp_State *K) const TValue *node = klispH_getstr(tv2table(K->require_table), tv2str(saved_name)); - if (node != &kfree) { + if (!ttisfree(*node)) { /* was required already, nothing to be done */ kapply_cc(K, KINERT); } @@ -962,6 +961,75 @@ void require(klisp_State *K) } } +/* ?.? registered-requirement? */ +void registered_requirementP(klisp_State *K) +{ + bind_1tp(K, K->next_value, "string", ttisstring, name); + if (kstring_emptyp(name)) { + klispE_throw_simple(K, "Empty name"); + return; + } + /* search for the named file in the table of already + required files. + N.B. this will be fooled if the same file is accessed + through different names */ + TValue saved_name = kstring_immutablep(name)? name : + kstring_new_bs_imm(K, kstring_buf(name), kstring_size(name)); + + const TValue *node = klispH_getstr(tv2table(K->require_table), + tv2str(saved_name)); + kapply_cc(K, ttisfree(*node)? KFALSE : KTRUE); +} + +void register_requirementB(klisp_State *K) +{ + bind_1tp(K, K->next_value, "string", ttisstring, name); + if (kstring_emptyp(name)) { + klispE_throw_simple(K, "Empty name"); + return; + } + TValue saved_name = kstring_immutablep(name)? name : + kstring_new_bs_imm(K, kstring_buf(name), kstring_size(name)); + + /* don't throw error if already registered */ + *(klispH_setstr(K, tv2table(K->require_table), + tv2str(saved_name))) = KTRUE; + kapply_cc(K, KINERT); +} + +void unregister_requirementB(klisp_State *K) +{ + bind_1tp(K, K->next_value, "string", ttisstring, name); + if (kstring_emptyp(name)) { + klispE_throw_simple(K, "Empty name"); + return; + } + TValue saved_name = kstring_immutablep(name)? name : + kstring_new_bs_imm(K, kstring_buf(name), kstring_size(name)); + + /* don't throw error if not registered */ + *(klispH_setstr(K, tv2table(K->require_table), + tv2str(saved_name))) = KFREE; + kapply_cc(K, KINERT); +} + +/* will throw an error if not found */ +void find_required_filename(klisp_State *K) +{ + bind_1tp(K, K->next_value, "string", ttisstring, name); + if (kstring_emptyp(name)) { + klispE_throw_simple(K, "Empty name"); + return; + } + TValue filename = find_file(K, name, K->require_path); + + if (kstring_emptyp(filename)) { + klispE_throw_simple_with_irritants(K, "Not found", 1, name); + return; + } + kapply_cc(K, filename); +} + /* 15.2.3 get-module */ void get_module(klisp_State *K) { @@ -1262,6 +1330,18 @@ void kinit_ports_ground_env(klisp_State *K) add_applicative(K, ground_env, "load", load, 0); /* 15.2.? require */ add_applicative(K, ground_env, "require", require, 0); + /* 15.2.? registered-requirement? */ + add_applicative(K, ground_env, "registered-requirement?", + registered_requirementP, 0); + /* 15.2.? register-requirement! */ + add_applicative(K, ground_env, "register-requirement!", + register_requirementB, 0); + /* 15.2.? unregister-requirement! */ + add_applicative(K, ground_env, "unregister-requirement!", + unregister_requirementB, 0); + /* 15.2.? find-required-filename */ + add_applicative(K, ground_env, "find-required-filename", + find_required_filename, 0); /* 15.2.3 get-module */ add_applicative(K, ground_env, "get-module", get_module, 0); /* 15.2.? display */