commit 3063304c62cabf23655a1d25ff35ccd4956cf365
parent 0771a7ccf83312b313a2adb729b680442960eb26
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Fri, 25 Nov 2011 17:07:38 -0300
Added bytevector, list->bytevector, and bytevector->list to the ground environment. Refactored kgbytevectors.h and kgstrings.h.
Diffstat:
6 files changed, 116 insertions(+), 140 deletions(-)
diff --git a/TODO b/TODO
@@ -34,6 +34,8 @@
 ** vector-map (r7rs)
 ** bytevector-map (r7rs)
 ** string-map (r7rs)
+** vector->bytevector
+** bytevector->vector
 ** vector->string (r7rs)
 ** string->vector (r7rs)
 ** vector-copy! (r7rs)
diff --git a/src/kgbytevectors.c b/src/kgbytevectors.c
@@ -29,6 +29,87 @@
 /* ?.? immutable-bytevector?, mutable-bytevector? */
 /* use ftypep */
 
+/* Helper for bytevector and list->bytevector */
+/* GC: Assumes ls is rooted */
+TValue list_to_bytevector_h(klisp_State *K, char *name, TValue ls)
+{
+    int32_t dummy;
+    /* don't allow cycles */
+    int32_t pairs = check_typed_list(K, name, "u8", ku8p, false,
+				     ls, &dummy);
+
+    TValue new_bb;
+    /* the if isn't strictly necessary but it's clearer this way */
+    if (pairs == 0) {
+	return K->empty_bytevector; 
+    } else {
+	new_bb = kbytevector_new_s(K, pairs);
+	uint8_t *buf = kbytevector_buf(new_bb);
+	TValue tail = ls;
+	while(pairs--) {
+	    *buf++ = ivalue(kcar(tail));
+	    tail = kcdr(tail);
+	}
+	return new_bb;
+    }
+}
+
+/* ?.? bytevector */
+void bytevector(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);
+    
+    TValue new_bb = list_to_bytevector_h(K, "bytevector", ptree);
+    kapply_cc(K, new_bb);
+}
+
+/* ?.? bytevector->list */
+void bytevector_to_list(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, "bytevector", ttisbytevector, bb);
+    int32_t pairs = kbytevector_size(bb);
+    uint8_t *buf = kbytevector_buf(bb);
+
+    TValue tail = kget_dummy1(K);
+
+    while(pairs--) {
+	TValue new_pair = kcons(K, i2tv(*buf), KNIL);
+	buf++;
+	kset_cdr(tail, new_pair);
+	tail = new_pair;
+    }
+    kapply_cc(K, kcutoff_dummy1(K));
+}
+
+/* ?.? list->bytevector */
+void list_to_bytevector(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);
+    
+    /* check later in list_to_bytevector_h */
+    bind_1p(K, ptree, ls);
+
+    TValue new_bb = list_to_bytevector_h(K, "list->bytevector", ls);
+    kapply_cc(K, new_bb);
+}
+
 /* ?.? make-bytevector */
 void make_bytevector(klisp_State *K)
 {
@@ -374,6 +455,12 @@ void kinit_bytevectors_ground_env(klisp_State *K)
 		    p2tv(kimmutable_bytevectorp));
     add_applicative(K, ground_env, "mutable-bytevector?", ftypep, 2, symbol, 
 		    p2tv(kmutable_bytevectorp));
+    /* ??.1.? bytevector */
+    add_applicative(K, ground_env, "bytevector", bytevector, 0);
+    /* ??.1.? list->bytevector */
+    add_applicative(K, ground_env, "list->bytevector", list_to_bytevector, 0);
+    /* ??.1.? bytevector->list */
+    add_applicative(K, ground_env, "bytevector->list", bytevector_to_list, 0);
     /* ??.1.2? make-bytevector */
     add_applicative(K, ground_env, "make-bytevector", make_bytevector, 0);
     /* ??.1.3? bytevector-length */
diff --git a/src/kgbytevectors.h b/src/kgbytevectors.h
@@ -7,46 +7,7 @@
 #ifndef kgbytevectors_h
 #define kgbytevectors_h
 
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-#include "kobject.h"
-#include "klisp.h"
 #include "kstate.h"
-#include "kghelpers.h"
-
-/* ??.1.1? bytevector? */
-/* uses typep */
-
-/* ??.1.2? make-bytevector */
-void make_bytevector(klisp_State *K);
-
-/* ??.1.3? bytevector-length */
-void bytevector_length(klisp_State *K);
-
-/* ??.1.4? bytevector-u8-ref */
-void bytevector_u8_ref(klisp_State *K);
-
-/* ??.1.5? bytevector-u8-set! */
-void bytevector_u8_setB(klisp_State *K);
-
-/* ??.2.?? bytevector-copy */
-void bytevector_copy(klisp_State *K);
-
-/* ??.2.?? bytevector-copy! */
-void bytevector_copyB(klisp_State *K);
-
-/* ??.2.?? bytevector-copy-partial */
-void bytevector_copy_partial(klisp_State *K);
-
-/* ??.2.?? bytevector-copy-partial! */
-void bytevector_copy_partialB(klisp_State *K);
-
-/* ??.2.?? bytevector->immutable-bytevector */
-void bytevector_to_immutable_bytevector(klisp_State *K);
 
 /* init ground */
 void kinit_bytevectors_ground_env(klisp_State *K);
diff --git a/src/kgstrings.c b/src/kgstrings.c
@@ -139,7 +139,7 @@ void string_setB(klisp_State *K)
 
 /* Helper for string and list->string */
 /* GC: Assumes ls is rooted */
-inline TValue list_to_string_h(klisp_State *K, char *name, TValue ls)
+TValue list_to_string_h(klisp_State *K, char *name, TValue ls)
 {
     int32_t dummy;
     /* don't allow cycles */
diff --git a/src/kgstrings.h b/src/kgstrings.h
@@ -7,84 +7,7 @@
 #ifndef kgstrings_h
 #define kgstrings_h
 
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-#include "kobject.h"
-#include "klisp.h"
 #include "kstate.h"
-#include "kghelpers.h"
-
-/* 13.1.1? string? */
-/* uses typep */
-
-/* 13.1.? immutable-string?, mutable-string? */
-/* use ftypep */
-
-/* 13.1.2? make-string */
-void make_string(klisp_State *K);
-
-/* 13.1.3? string-length */
-void string_length(klisp_State *K);
-
-/* 13.1.4? string-ref */
-void string_ref (klisp_State *K);
-
-/* 13.1.5? string-set! */
-void string_setS (klisp_State *K);
-
-/* 13.2.1? string */
-void string(klisp_State *K);
-
-/* 13.2.2? string=?, string-ci=? */
-/* use ftyped_bpredp */
-
-/* 13.2.3? string<?, string<=?, string>?, string>=? */
-/* use ftyped_bpredp */
-
-/* 13.2.4? string-ci<?, string-ci<=?, string-ci>?, string-ci>=? */
-/* use ftyped_bpredp */
-
-/* Helpers for binary predicates */
-/* XXX: this should probably be in file kstring.h */
-bool kstring_eqp(TValue str1, TValue str2);
-bool kstring_ci_eqp(TValue str1, TValue str2);
-
-bool kstring_ltp(TValue str1, TValue str2);
-bool kstring_lep(TValue str1, TValue str2);
-bool kstring_gtp(TValue str1, TValue str2);
-bool kstring_gep(TValue str1, TValue str2);
-
-bool kstring_ci_ltp(TValue str1, TValue str2);
-bool kstring_ci_lep(TValue str1, TValue str2);
-bool kstring_ci_gtp(TValue str1, TValue str2);
-bool kstring_ci_gep(TValue str1, TValue str2);
-
-
-/* 13.2.5? substring */
-void substring(klisp_State *K);
-
-/* 13.2.6? string-append */
-void string_append(klisp_State *K);
-
-/* 13.2.7? string->list, list->string */
-void list_to_string(klisp_State *K);
-void string_to_list(klisp_State *K);
-
-/* 13.2.8? string-copy */
-void string_copy(klisp_State *K);
-
-/* 13.2.9? string->immutable-string */
-void string_to_immutable_string(klisp_State *K);
-
-/* 13.2.10? string-fill! */
-void string_fillB(klisp_State *K);
-
-/* Helpers */
-bool kstringp(TValue obj);
 
 /* init ground */
 void kinit_strings_ground_env(klisp_State *K);
diff --git a/src/tests/bytevectors.k b/src/tests/bytevectors.k
@@ -5,9 +5,6 @@
 
 ;; helper functions
 ;;
-;; (list->bytevector INTEGERS) converts list of integers to bytevector
-;; The elements of INTEGERS must be in the range 0...255.
-;;
 ;; (u8 X_0 X_1 ... X_{N-1}) returns a bytevector B of length N,
 ;;   such that B[k] = X_k
 ;;
@@ -19,23 +16,8 @@
 ;;   such that the bytes B[4k] ... B[4k+3], combined into 32-bit
 ;;   unsigned integer, represent the number X_k
 ;;
-($define! list->bytevector
-  ($lambda (bytes)
-    ($let*
-      ( (n (length bytes))
-        (v (make-bytevector n)) )
-      ($letrec
-        ((loop ($lambda (i xs)
-          ($if (<? i n)
-            ($sequence
-              (bytevector-u8-set! v i (car xs))
-              (loop (+ i 1) (cdr xs)))
-            #inert))))
-        (loop 0 bytes)
-        v))))
-
-($define! u8
-  ($lambda bytes (list->bytevector bytes)))
+
+($define! u8 bytevector)
 
 ;; TODO: endianess
 ($define! u16
@@ -73,6 +55,27 @@
 ($check-predicate (mutable-bytevector?))
 ($check-predicate (mutable-bytevector? (make-bytevector 1)))
 
+;; XXX bytevector
+($check-predicate (bytevector? (bytevector 1 2 3)))
+($check-predicate (mutable-bytevector? (bytevector 1 2 3)))
+($check equal? (bytevector 1 2 3) (list->bytevector (list 1 2 3)))
+
+;; XXX list->bytevector
+($check equal? (make-bytevector 0) (list->bytevector ()))
+($check equal? (make-bytevector 3 1) (list->bytevector (list 1 1 1)))
+($check equal? (list->bytevector (list 1 2 3 4)) (u8 1 2 3 4))
+($check-predicate (mutable-bytevector? (list->bytevector (list 1 2 3))))
+($check-predicate (mutable-bytevector? (list->bytevector 
+					(copy-es-immutable (list 1 2 3)))))
+
+;; XXX bytevector->list
+($check-predicate (null? (bytevector->list (u8))))
+($check equal? (bytevector->list (u8 1 2 3 4)) (list 1 2 3 4))
+($check-predicate (mutable-pair? (bytevector->list (u8 1 2))))
+($check-predicate (mutable-pair? (bytevector->list 
+				  (bytevector->immutable-bytevector 
+				   (u8 1 2)))))
+
 ;; (R7RS 3rd draft, section 6.3.7) make-bytevector bytevector-length
 
 ($check equal? (bytevector-length (make-bytevector 0)) 0)
@@ -163,11 +166,11 @@
   ($check-error (bytevector-copy-partial! (u8 1 2) 0 2 w 0)))
 
 ;; XXX bytevector-u8-fill!
-($check-predicate (inert? (bytevector-u8-fill! (bytevector 1 2) 0)))
-($check equal? ($let ((b (bytevector 1 2 3)))
+($check-predicate (inert? (bytevector-u8-fill! (u8 1 2) 0)))
+($check equal? ($let ((b (u8 1 2 3)))
 		 (bytevector-u8-fill! b 0)
 		 b)
-	(bytevector 0 0 0))
+	(u8 0 0 0))
 
 ;; XXX bytevector->immutable-bytevector