From c6b0c2319c20a20077f3ce41cf66427a74c04819 Mon Sep 17 00:00:00 2001 From: Alex Shinn Date: Wed, 16 Dec 2009 17:43:56 +0900 Subject: [PATCH] adding srfi-27 --- Makefile | 6 +- include/chibi/sexp.h | 4 + lib/srfi/27.module | 11 +++ lib/srfi/27/constructors.scm | 7 ++ lib/srfi/27/rand.c | 153 +++++++++++++++++++++++++++++++++++ sexp.c | 6 +- 6 files changed, 181 insertions(+), 6 deletions(-) create mode 100644 lib/srfi/27.module create mode 100644 lib/srfi/27/constructors.scm create mode 100644 lib/srfi/27/rand.c diff --git a/Makefile b/Makefile index 925b1eb7..0a892b6f 100644 --- a/Makefile +++ b/Makefile @@ -53,8 +53,10 @@ endif all: chibi-scheme$(EXE) libs -COMPILED_LIBS := lib/srfi/33/bit$(SO) lib/srfi/69/hash$(SO) lib/srfi/98/env$(SO) \ - lib/chibi/ast$(SO) lib/chibi/net$(SO) lib/chibi/posix$(SO) # lib/chibi/heap-stats$(SO) +COMPILED_LIBS := lib/srfi/27/rand$(SO) lib/srfi/33/bit$(SO) \ + lib/srfi/69/hash$(SO) lib/srfi/98/env$(SO) \ + lib/chibi/ast$(SO) lib/chibi/net$(SO) \ + lib/chibi/posix$(SO) # lib/chibi/heap-stats$(SO) libs: $(COMPILED_LIBS) diff --git a/include/chibi/sexp.h b/include/chibi/sexp.h index 1b487a54..b4527037 100644 --- a/include/chibi/sexp.h +++ b/include/chibi/sexp.h @@ -352,6 +352,10 @@ void *sexp_realloc(sexp ctx, sexp x, size_t size); #define sexp_offsetof(type, f) (offsetof(struct sexp_struct, value.type.f)) +#define sexp_offsetof_slot0 (offsetof(struct sexp_struct, value)) + +#define sexp_sizeof_header (sexp_sizeof(flonum) - sizeof(double)) + #define sexp_alloc_type(ctx, type, tag) sexp_alloc_tagged(ctx, sexp_sizeof(type), tag) #if USE_BIGNUMS diff --git a/lib/srfi/27.module b/lib/srfi/27.module new file mode 100644 index 00000000..198d444e --- /dev/null +++ b/lib/srfi/27.module @@ -0,0 +1,11 @@ + +(define-module (srfi 27) + (export random-integer random-real default-random-source + make-random-source random-source? + random-source-state-ref random-source-state-set! + random-source-randomize! random-source-pseudo-randomize! + random-source-make-integers random-source-make-reals) + (import (scheme)) + (include-shared "27/rand") + (include "27/constructors.scm")) + diff --git a/lib/srfi/27/constructors.scm b/lib/srfi/27/constructors.scm new file mode 100644 index 00000000..473ad2a2 --- /dev/null +++ b/lib/srfi/27/constructors.scm @@ -0,0 +1,7 @@ + +(define (random-source-make-integers rs) + (lambda (n) (%random-integer rs n))) + +(define (random-source-make-reals rs . o) + (lambda () (%random-real rs))) + diff --git a/lib/srfi/27/rand.c b/lib/srfi/27/rand.c new file mode 100644 index 00000000..4ae30f50 --- /dev/null +++ b/lib/srfi/27/rand.c @@ -0,0 +1,153 @@ + +#include +#include + +#define SEXP_RANDOM_STATE_SIZE 128 + +#define ZERO sexp_make_fixnum(0) +#define ONE sexp_make_fixnum(1) +#define STATE_SIZE sexp_make_fixnum(SEXP_RANDOM_STATE_SIZE) + +#define sexp_random_source_p(x) sexp_check_tag(x, rs_type_id) + +#define sexp_random_state(x) (sexp_slot_ref((x), 0)) +#define sexp_random_data(x) ((struct random_data*)(&sexp_slot_ref((x), 1))) + +#define sexp_random_init(x, seed) \ + initstate_r(seed, \ + sexp_string_data(sexp_random_state(x)), \ + SEXP_RANDOM_STATE_SIZE, \ + sexp_random_data(x)) + +#define sexp_sizeof_random (sexp_sizeof_header + sizeof(struct random_data) + sizeof(sexp)) + +static sexp_uint_t rs_type_id; +static sexp default_random_source; + +static sexp sexp_rs_random_integer (sexp ctx, sexp rs, sexp bound) { + sexp res; + int32_t n, hi, mod, len, i, *data; + if (! sexp_random_source_p(rs)) + res = sexp_type_exception(ctx, "not a random-source", rs); + if (sexp_fixnump(bound)) { + random_r(sexp_random_data(rs), &n); + res = sexp_make_fixnum(n % sexp_unbox_fixnum(bound)); +#if USE_BIGNUMS + } else if (sexp_bignump(bound)) { + hi = sexp_bignum_hi(bound); + len = hi * sizeof(sexp_uint_t) / sizeof(int32_t); + res = sexp_make_bignum(ctx, hi); + data = (int32_t*) sexp_bignum_data(res); + for (i=0; i