klisp

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

commit 2f1bd9c3bbd1a8bb7eacd718b6572ba73d827e3e
parent 42e8a2aef70f3cec076dfb429951711f98a2ec0f
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Wed, 13 Jul 2011 14:39:51 -0300

Added blob-copy and blob->immutable-blob.

Diffstat:
Msrc/kblob.h | 3+++
Msrc/kgblobs.c | 62+++++++++++++++++++++++++++++++++++++++++++++++++++++---------
Msrc/kgblobs.h | 16++++++++++++----
Msrc/kgeqp.h | 2++
4 files changed, 70 insertions(+), 13 deletions(-)

diff --git a/src/kblob.h b/src/kblob.h @@ -10,6 +10,9 @@ #include "kobject.h" #include "kstate.h" +/* TODO change blob constructors to string like constructors */ +/* TODO change names to lua-like (e.g. klispB_new, etc) */ + /* Constructors for blobs */ TValue kblob_new_g(klisp_State *K, bool m, uint32_t size); TValue kblob_new_imm(klisp_State *K, uint32_t size); diff --git a/src/kgblobs.c b/src/kgblobs.c @@ -54,7 +54,7 @@ void make_blob(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) /* TValue new_blob = kblob_new_sf(K, ivalue(tv_s), fill); */ TValue new_blob = kblob_new(K, ivalue(tv_s)); if (fill != 0) { - int s = ivalue(tv_s); + int32_t s = ivalue(tv_s); uint8_t *ptr = kblob_buf(new_blob); while(s--) *ptr++ = fill; @@ -75,8 +75,8 @@ void blob_length(klisp_State *K, TValue *xparams, TValue ptree, kapply_cc(K, res); } -/* 13.1.4? blob-ref */ -void blob_ref(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) +/* 13.1.4? blob-u8-ref */ +void blob_u8_ref(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) { UNUSED(xparams); UNUSED(denv); @@ -100,8 +100,8 @@ void blob_ref(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) kapply_cc(K, res); } -/* 13.1.5? blob-set! */ -void blob_setS(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) +/* 13.1.5? blob-u8-set! */ +void blob_u8_setS(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) { UNUSED(xparams); UNUSED(denv); @@ -132,6 +132,45 @@ void blob_setS(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) kapply_cc(K, KINERT); } +/* TODO change blob constructors to string like constructors */ + +/* 13.2.8? blob-copy */ +/* TEMP: at least for now this always returns mutable blobs */ +void blob_copy(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) +{ + UNUSED(xparams); + UNUSED(denv); + bind_1tp(K, ptree, "blob", ttisblob, blob); + + TValue new_blob; + /* the if isn't strictly necessary but it's clearer this way */ + if (tv_equal(blob, K->empty_blob)) { + new_blob = blob; + } else { + new_blob = kblob_new(K, kblob_size(blob)); + memcpy(kblob_buf(new_blob), kblob_buf(blob), kblob_size(blob)); + } + kapply_cc(K, new_blob); +} + +/* 13.2.9? blob->immutable-blob */ +void blob_to_immutable_blob(klisp_State *K, TValue *xparams, + TValue ptree, TValue denv) +{ + UNUSED(xparams); + UNUSED(denv); + bind_1tp(K, ptree, "blob", ttisblob, blob); + + TValue res_blob; + if (kblob_immutablep(blob)) {/* this includes the empty blob */ + res_blob = blob; + } else { + res_blob = kblob_new_imm(K, kblob_size(blob)); + memcpy(kblob_buf(res_blob), kblob_buf(blob), kblob_size(blob)); + } + kapply_cc(K, res_blob); +} + /* init ground */ void kinit_blobs_ground_env(klisp_State *K) { @@ -152,10 +191,15 @@ void kinit_blobs_ground_env(klisp_State *K) /* ??.1.3? blob-length */ add_applicative(K, ground_env, "blob-length", blob_length, 0); - /* ??.1.4? blob-ref */ - add_applicative(K, ground_env, "blob-ref", blob_ref, 0); - /* ??.1.5? blob-set! */ - add_applicative(K, ground_env, "blob-set!", blob_setS, 0); + /* ??.1.4? blob-u8-ref */ + add_applicative(K, ground_env, "blob-u8-ref", blob_u8_ref, 0); + /* ??.1.5? blob-u8-set! */ + add_applicative(K, ground_env, "blob-u8-set!", blob_u8_setS, 0); + + /* ??.1.?? blob-copy */ + add_applicative(K, ground_env, "blob-copy", blob_copy, 0); + /* ??.1.?? blob->immutable-blob */ + add_applicative(K, ground_env, "blob->immutable-blob", blob_to_immutable_blob, 0); /* TODO put the blob equivalents here */ #if 0 diff --git a/src/kgblobs.h b/src/kgblobs.h @@ -28,11 +28,19 @@ void make_blob(klisp_State *K, TValue *xparams, TValue ptree, TValue denv); void blob_length(klisp_State *K, TValue *xparams, TValue ptree, TValue denv); -/* ??.1.4? blob-ref */ -void blob_ref(klisp_State *K, TValue *xparams, TValue ptree, TValue denv); +/* ??.1.4? blob-u8-ref */ +void blob_u8_ref(klisp_State *K, TValue *xparams, TValue ptree, TValue denv); -/* ??.1.5? blob-set! */ -void blob_setS(klisp_State *K, TValue *xparams, TValue ptree, TValue denv); +/* ??.1.5? blob-u8-set! */ +void blob_u8_setS(klisp_State *K, TValue *xparams, TValue ptree, TValue denv); + +/* ??.2.?? blob-copy */ +void blob_copy(klisp_State *K, TValue *xparams, + TValue ptree, TValue denv); + +/* ??.2.?? blob->immutable-blob */ +void blob_to_immutable_blob(klisp_State *K, TValue *xparams, + TValue ptree, TValue denv); /* init ground */ void kinit_blobs_ground_env(klisp_State *K); diff --git a/src/kgeqp.h b/src/kgeqp.h @@ -28,6 +28,8 @@ void eqp(klisp_State *K, TValue *xparams, TValue ptree, TValue denv); /* Helper (also used in equal?) */ inline bool eq2p(klisp_State *K, TValue obj1, TValue obj2) { + /* TODO/FIXME: immutable blobs aren't interned and so will compare + as un-eq? even if the contents are the same */ bool res = (tv_equal(obj1, obj2)); if (!res && (ttype(obj1) == ttype(obj2))) { switch (ttype(obj1)) {