klisp

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

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:
MTODO | 2++
Msrc/kgbytevectors.c | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/kgbytevectors.h | 39---------------------------------------
Msrc/kgstrings.c | 2+-
Msrc/kgstrings.h | 77-----------------------------------------------------------------------------
Msrc/tests/bytevectors.k | 49++++++++++++++++++++++++++-----------------------
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