klisp

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

commit f604ac1430b756e6489e03d04d967aff7e110017
parent 07844d71887f047c789d68e131e4c8bff8561f64
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Mon,  5 Dec 2011 21:36:50 -0300

Added file tracking to require to avoid reloading the same file twice (at least with the same name)

Diffstat:
Msrc/Makefile | 2+-
Msrc/kgports.c | 26++++++++++++++++++++++++++
2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/src/Makefile b/src/Makefile @@ -214,7 +214,7 @@ kgpairs_lists.o: kgpairs_lists.c kstate.h klimits.h klisp.h kobject.h \ kgports.o: kgports.c kstate.h klimits.h klisp.h kobject.h klispconf.h \ ktoken.h kmem.h kport.h kstring.h kbytevector.h kenvironment.h \ kapplicative.h koperative.h kcontinuation.h kpair.h kgc.h kerror.h \ - ksymbol.h kread.h kwrite.h kghelpers.h ktable.h kgports.h + ksymbol.h kread.h kwrite.h kghelpers.h ktable.h kgports.h ktable.h kgpromises.o: kgpromises.c kstate.h klimits.h klisp.h kobject.h \ klispconf.h ktoken.h kmem.h kpromise.h kpair.h kgc.h kapplicative.h \ koperative.h kcontinuation.h kerror.h kghelpers.h kenvironment.h \ diff --git a/src/kgports.c b/src/kgports.c @@ -14,6 +14,7 @@ #include "kobject.h" #include "kport.h" #include "kstring.h" +#include "ktable.h" #include "kbytevector.h" #include "kenvironment.h" #include "kapplicative.h" @@ -876,6 +877,21 @@ void require(klisp_State *K) 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)); + if (node != &kfree) { + /* was required already, nothing to be done */ + kapply_cc(K, KINERT); + } + + krooted_tvs_push(K, saved_name); TValue filename = K->empty_string; krooted_vars_push(K, &filename); filename = find_file(K, name, K->require_path); @@ -885,6 +901,16 @@ void require(klisp_State *K) return; } + /* the file was found, save it in the table */ + /* MAYBE the name should be saved in the table only if no error + occured... but that could lead to loops if the file is + required recursively. A third option would be to record the + sate of the require in the table, so we could have: error, required, + requiring, etc */ + *(klispH_setstr(K, tv2table(K->require_table), tv2str(saved_name))) = + KTRUE; + krooted_tvs_pop(K); /* saved_name no longer necessary */ + /* the reads must be guarded to close the file if there is some error this continuation also will return inert after the evaluation of the last expression is done */