klisp

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

commit df913012db547b03bbbd23ba691dd2cec2ef613d
parent 24a46c098019bbf49a17a9718d6340855e5491a4
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Tue, 12 Apr 2011 23:05:55 -0300

Added support for bigints to string applicatives. Bugfix: allow (substring str (string-lenght str) (string-length str)) to be called and return "". (Was disallowed, but scheme r6rs allows it).

Diffstat:
Msrc/Makefile | 2+-
Msrc/kgstrings.c | 49+++++++++++++++++++++++++++++++++++--------------
2 files changed, 36 insertions(+), 15 deletions(-)

diff --git a/src/Makefile b/src/Makefile @@ -138,5 +138,5 @@ kgnumbers.o: kgnumbers.c kgnumbers.h kghelpers.h kstate.h klisp.h \ ksymbol.h kinteger.h kgstrings.o: kgstrings.c kgstrings.h kghelpers.h kstate.h klisp.h \ kobject.h kerror.h kapplicative.h koperative.h kcontinuation.h \ - ksymbol.h + ksymbol.h kgnumbers.h imath.o: kobject.h kstate.h kmem.h kerror.h \ No newline at end of file diff --git a/src/kgstrings.c b/src/kgstrings.c @@ -24,6 +24,7 @@ #include "kghelpers.h" #include "kgchars.h" /* for kcharp */ #include "kgstrings.h" +#include "kgnumbers.h" /* for kintegerp & knegativep */ /* 13.1.1? string? */ /* uses typep */ @@ -33,16 +34,19 @@ void make_string(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) { UNUSED(xparams); UNUSED(denv); - bind_al1tp(K, "make-string", ptree, "finite number", ttisfixint, tv_s, + bind_al1tp(K, "make-string", ptree, "integer", kintegerp, tv_s, maybe_char); char fill = ' '; if (get_opt_tpar(K, "make-string", K_TCHAR, &maybe_char)) fill = chvalue(maybe_char); - if (ivalue(tv_s) < 0) { + if (knegativep(tv_s)) { klispE_throw(K, "make-string: negative size"); return; + } else if (!ttisfixint(tv_s)) { + klispE_throw(K, "make-string: size is too big"); + return; } TValue new_str = kstring_new_sc(K, ivalue(tv_s), fill); @@ -67,8 +71,13 @@ void string_ref(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) UNUSED(xparams); UNUSED(denv); bind_2tp(K, "string-ref", ptree, "string", ttisstring, str, - "finite integer", ttisfixint, tv_i); + "integer", kintegerp, tv_i); + if (!ttisfixint(tv_i)) { + /* TODO show index */ + klispE_throw(K, "string-ref: index out of bounds"); + return; + } int32_t i = ivalue(tv_i); if (i < 0 || i >= kstring_size(str)) { @@ -87,7 +96,13 @@ void string_setS(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) UNUSED(xparams); UNUSED(denv); bind_3tp(K, "string-set!", ptree, "string", ttisstring, str, - "finite integer", ttisfixint, tv_i, "char", ttischar, tv_ch); + "integer", kintegerp, tv_i, "char", ttischar, tv_ch); + + if (!ttisfixint(tv_i)) { + /* TODO show index */ + klispE_throw(K, "string-set!: index out of bounds"); + return; + } int32_t i = ivalue(tv_i); @@ -230,23 +245,29 @@ void substring(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) UNUSED(xparams); UNUSED(denv); bind_3tp(K, "substring", ptree, "string", ttisstring, str, - "finite integer", ttisfixint, tv_start, - "finite integer", ttisfixint, tv_end); + "integer", kintegerp, tv_start, + "integer", kintegerp, tv_end); - int32_t start = ivalue(tv_start); - int32_t end = ivalue(tv_end); - - if (start < 0 || start >= kstring_size(str)) { + if (!ttisfixint(tv_start) || ivalue(tv_start) < 0 || + ivalue(tv_start) > kstring_size(str)) { /* TODO show index */ klispE_throw(K, "substring: start index out of bounds"); return; - } else if (end < 0 || end > kstring_size(str)) { /* end can be = size */ - /* TODO show index */ + } + + int32_t start = ivalue(tv_start); + + if (!ttisfixint(tv_end) || ivalue(tv_end) < 0 || + ivalue(tv_end) > kstring_size(str)) { klispE_throw(K, "substring: end index out of bounds"); return; - } else if (start > end) { + } + + int32_t end = ivalue(tv_end); + + if (start > end) { /* TODO show indexes */ - klispE_throw(K, "substring: end index is greater than start index"); + klispE_throw(K, "substring: end index is smaller than start index"); return; }