klisp

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

commit e5fb6339f72557e07b5e5be366014e6391938901
parent 955613e496747b76e2fa582d03cc7d724dd851b3
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Sun, 27 Nov 2011 18:38:02 -0300

Added string->vector and vector->string to the ground environment. Refactored kvector.h.

Diffstat:
MTODO | 4++--
Msrc/Makefile | 2+-
Msrc/kgequalp.c | 8++++----
Msrc/kgstrings.c | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/kgvectors.c | 24++++++++++++------------
Msrc/kvector.c | 2++
Msrc/kvector.h | 6+++---
Msrc/tests/strings.k | 28++++++++++++++++++++++++++++
8 files changed, 115 insertions(+), 22 deletions(-)

diff --git a/TODO b/TODO @@ -36,8 +36,8 @@ ** string-map (r7rs) ** vector->bytevector ** bytevector->vector -** vector->string (r7rs) -** string->vector (r7rs) +** string->bytevector +** bytevector->string ** vector-copy! (r7rs) ** vector-copy-partial (r7rs) ** vector-copy-partial! (r7rs) diff --git a/src/Makefile b/src/Makefile @@ -233,7 +233,7 @@ kground.o: kground.c kstate.h klimits.h klisp.h kobject.h klispconf.h \ kgerrors.h kgffi.h ktable.h keval.h krepl.h kgstrings.o: kgstrings.c kstate.h klimits.h klisp.h kobject.h klispconf.h \ ktoken.h kmem.h kapplicative.h koperative.h kcontinuation.h kerror.h \ - kpair.h kgc.h ksymbol.h kstring.h kghelpers.h kenvironment.h \ + kpair.h kgc.h ksymbol.h kstring.h kghelpers.h kenvironment.h kvector.h \ kgstrings.h kgnumbers.h kgsymbols.o: kgsymbols.c kstate.h klimits.h klisp.h kobject.h klispconf.h \ ktoken.h kmem.h kcontinuation.h kpair.h kgc.h kstring.h ksymbol.h \ diff --git a/src/kgequalp.c b/src/kgequalp.c @@ -204,14 +204,14 @@ bool equal2p(klisp_State *K, TValue obj1, TValue obj2) } break; case K_TVECTOR: - if (kvector_length(obj1) == kvector_length(obj2)) { + if (kvector_size(obj1) == kvector_size(obj2)) { /* if they were already compaired, consider equal for now otherwise they are equal if all their elements are equal pairwise */ if (!equal_find2_mergep(K, obj1, obj2)) { - uint32_t i = kvector_length(obj1); - TValue *array1 = kvector_array(obj1); - TValue *array2 = kvector_array(obj1); + uint32_t i = kvector_size(obj1); + TValue *array1 = kvector_buf(obj1); + TValue *array2 = kvector_buf(obj1); while(i-- > 0) { ks_spush(K, array1[i]); ks_spush(K, array2[i]); diff --git a/src/kgstrings.c b/src/kgstrings.c @@ -21,6 +21,7 @@ #include "ksymbol.h" #include "kchar.h" #include "kstring.h" +#include "kvector.h" #include "kghelpers.h" #include "kgstrings.h" @@ -458,6 +459,65 @@ void list_to_string(klisp_State *K) kapply_cc(K, new_str); } +/* 13.? string->vector, vector->string */ +void string_to_vector(klisp_State *K) +{ + TValue *xparams = K->next_xparams; + TValue ptree = K->next_value; + TValue denv = K->next_env; + klisp_assert(ttisenvironment(K->next_env)); + UNUSED(xparams); + UNUSED(denv); + + bind_1tp(K, ptree, "string", ttisstring, str); + TValue res; + + if (kstring_emptyp(str)) { + res = K->empty_vector; + } else { + uint32_t size = kstring_size(str); + + /* MAYBE add vector constructor without fill */ + /* no need to root this */ + res = kvector_new_sf(K, size, KINERT); + char *src = kstring_buf(str); + TValue *dst = kvector_buf(res); + while(size--) { + char ch = *src++; /* not needed but just in case */ + *dst++ = ch2tv(ch); + } + } + kapply_cc(K, res); +} + +/* TEMP Only ASCII for now */ +void vector_to_string(klisp_State *K) +{ + TValue *xparams = K->next_xparams; + TValue ptree = K->next_value; + TValue denv = K->next_env; + klisp_assert(ttisenvironment(K->next_env)); + UNUSED(xparams); + UNUSED(denv); + + bind_1tp(K, ptree, "vector", ttisvector, vec); + uint32_t size = kvector_size(vec); + + TValue res = kstring_new_s(K, size); /* no need to root this */ + TValue *src = kvector_buf(vec); + char *dst = kstring_buf(res); + while(size--) { + TValue tv = *src++; + if (!ttischar(tv)) { + klispE_throw_simple_with_irritants(K, "Non char object found", + 1, tv); + return; + } + *dst++ = chvalue(tv); + } + kapply_cc(K, res); +} + /* 13.2.8? string-copy */ /* TEMP: at least for now this always returns mutable strings */ void string_copy(klisp_State *K) @@ -591,6 +651,9 @@ void kinit_strings_ground_env(klisp_State *K) /* 13.2.7? string->list, list->string */ add_applicative(K, ground_env, "string->list", string_to_list, 0); add_applicative(K, ground_env, "list->string", list_to_string, 0); + /* 13.?? string->vector, vector->string */ + add_applicative(K, ground_env, "string->vector", string_to_vector, 0); + add_applicative(K, ground_env, "vector->string", vector_to_string, 0); /* 13.2.8? string-copy */ add_applicative(K, ground_env, "string-copy", string_copy, 0); /* 13.2.9? string->immutable-string */ diff --git a/src/kgvectors.c b/src/kgvectors.c @@ -61,7 +61,7 @@ void vector_length(klisp_State *K) bind_1tp(K, ptree, "vector", ttisvector, vector); - TValue res = i2tv(kvector_length(vector)); + TValue res = i2tv(kvector_size(vector)); kapply_cc(K, res); } @@ -80,12 +80,12 @@ void vector_ref(klisp_State *K) return; } int32_t i = ivalue(tv_i); - if (i < 0 || i >= kvector_length(vector)) { + if (i < 0 || i >= kvector_size(vector)) { klispE_throw_simple_with_irritants(K, "vector index out of bounds", 1, tv_i); return; } - kapply_cc(K, kvector_array(vector)[i]); + kapply_cc(K, kvector_buf(vector)[i]); } /* (R7RS 3rd draft 6.3.6) vector-set! */ @@ -104,7 +104,7 @@ void vector_setB(klisp_State *K) } int32_t i = ivalue(tv_i); - if (i < 0 || i >= kvector_length(vector)) { + if (i < 0 || i >= kvector_size(vector)) { klispE_throw_simple_with_irritants(K, "vector index out of bounds", 1, tv_i); return; @@ -113,7 +113,7 @@ void vector_setB(klisp_State *K) return; } - kvector_array(vector)[i] = tv_new_value; + kvector_buf(vector)[i] = tv_new_value; kapply_cc(K, KINERT); } @@ -128,7 +128,7 @@ void vector_copy(klisp_State *K) TValue new_vector = kvector_emptyp(v)? v - : kvector_new_bs_g(K, true, kvector_array(v), kvector_length(v)); + : kvector_new_bs_g(K, true, kvector_buf(v), kvector_size(v)); kapply_cc(K, new_vector); } @@ -142,7 +142,7 @@ static TValue list_to_vector_h(klisp_State *K, const char *name, TValue ls) } else { TValue res = kvector_new_sf(K, pairs, KINERT); for (int i = 0; i < pairs; i++) { - kvector_array(res)[i] = kcar(ls); + kvector_buf(res)[i] = kcar(ls); ls = kcdr(ls); } return res; @@ -180,9 +180,9 @@ void vector_to_list(klisp_State *K) TValue tail = KNIL; krooted_vars_push(K, &tail); - size_t i = kvector_length(v); + size_t i = kvector_size(v); while (i-- > 0) - tail = kcons(K, kvector_array(v)[i], tail); + tail = kcons(K, kvector_buf(v)[i], tail); krooted_vars_pop(K); kapply_cc(K, tail); } @@ -204,8 +204,8 @@ void vector_fillB(klisp_State *K) return; } - uint32_t size = kvector_length(vector); - TValue *buf = kvector_array(vector); + uint32_t size = kvector_size(vector); + TValue *buf = kvector_buf(vector); while(size-- > 0) { *buf++ = fill; } @@ -222,7 +222,7 @@ void vector_to_immutable_vector(klisp_State *K) TValue res = kvector_immutablep(v)? v - : kvector_new_bs_g(K, false, kvector_array(v), kvector_length(v)); + : kvector_new_bs_g(K, false, kvector_buf(v), kvector_size(v)); kapply_cc(K, res); } diff --git a/src/kvector.c b/src/kvector.c @@ -14,6 +14,8 @@ /* helper function allocating vectors */ +/* XXX I'm not too convinced this is the best way to handle the empty + vector... Try to find a better way */ static Vector *kvector_alloc(klisp_State *K, bool m, uint32_t length) { Vector *new_vector; diff --git a/src/kvector.h b/src/kvector.h @@ -24,10 +24,10 @@ bool kmutable_vectorp(TValue obj); /* some macros to access the parts of vectors */ -#define kvector_array(tv_) (tv2vector(tv_)->array) -#define kvector_length(tv_) (tv2vector(tv_)->sizearray) +#define kvector_buf(tv_) (tv2vector(tv_)->array) +#define kvector_size(tv_) (tv2vector(tv_)->sizearray) -#define kvector_emptyp(tv_) (kvector_length(tv_) == 0) +#define kvector_emptyp(tv_) (kvector_size(tv_) == 0) #define kvector_mutablep(tv_) (kis_mutable(tv_)) #define kvector_immutablep(tv_) (kis_immutable(tv_)) diff --git a/src/tests/strings.k b/src/tests/strings.k @@ -226,6 +226,34 @@ ($check-error (list->string ($quote (#\a #0=(#\a . #0#))))) +;; XXX string->vector + +($check equal? (string->vector "") (vector)) +($check equal? (string->vector "abc") (vector #\a #\B #\c)) + +($check-not-predicate + ($let* + ( (str "abc") + (x (string->vector str)) + (y (string->vector str))) + (eq? x y))) + +($check-predicate (mutable-vector? (string->vector "abc"))) + +;; XXX vector->string + +($check equal? (vector->string (vector)) "") +($check equal? (vector->string (vector #\a #\b #\c)) "abc") + +($check-not-predicate + ($let* + ( (cs (vector #\a #\b #\c)) + (x (vector->string cs)) + (y (vector->string cs))) + (eq? x y))) + +($check-predicate (mutable-string? (vector->string (vector #\a #\b)))) + ;; 13.1.1 string->symbol ;; XXX symbol->string ;;