Merge pull request #446 from okuoku/win32-cmake

Win32: Wrap-up
This commit is contained in:
Alex Shinn 2017-12-14 20:05:21 +09:00 committed by GitHub
commit 27d8174518
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 392 additions and 41 deletions

View file

@ -50,6 +50,7 @@ Thanks to the following people for patches and bug reports:
* Stephen Lewis * Stephen Lewis
* Taylor Venable * Taylor Venable
* Travis Cross * Travis Cross
* Yuki Okumura
If you would prefer not to be listed, or are one of the users listed If you would prefer not to be listed, or are one of the users listed
without a full name, please contact me. If you've made a contribution without a full name, please contact me. If you've made a contribution

View file

@ -249,3 +249,44 @@ foreach(e ${chibi-scheme-tests})
COMMAND chibi-scheme tests/${e}.scm COMMAND chibi-scheme tests/${e}.scm
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
endforeach() endforeach()
message(STATUS "Detecting library tests")
file(GLOB_RECURSE srfi_tests RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/srfi/*/test.sld)
file(GLOB_RECURSE chibi_scheme_tests RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/chibi/*-test.sld)
set(testexcludes
# Excluded tests
chibi/filesystem-test
chibi/memoize-test
chibi/term/ansi-test
chibi/weak-test
# Not ported to Win32
srfi/18/test # Threading
chibi/doc-test # Depends (chibi time)
chibi/system-test
chibi/tar-test # Depends (chibi system)
)
set(testlibs)
foreach(e ${srfi_tests} ${chibi_scheme_tests})
get_filename_component(pth ${e} PATH)
get_filename_component(nam ${e} NAME_WE)
list(APPEND testlibs ${pth}/${nam})
endforeach()
list(REMOVE_ITEM testlibs ${testexcludes})
foreach(e ${testlibs})
string(REGEX REPLACE "/" "_" testname ${e})
string(REGEX REPLACE "/" " " form ${e})
add_test(NAME "lib_${testname}"
COMMAND chibi-scheme -e "(import (${form}))"
-e "(run-tests)"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
message(STATUS "Test ${testname}")
endforeach()

View file

@ -24,11 +24,23 @@ TEMPFILE := $(shell mktemp -t chibi.XXXXXX)
######################################################################## ########################################################################
# Choose compiled library on MSYS
ifeq ($(OS), Windows_NT)
ifeq ($(PLATFORM),msys)
EXCLUDE_WIN32_LIBS=1
else
EXCLUDE_POSIX_LIBS=1
endif
endif
########################################################################
CHIBI_COMPILED_LIBS = lib/chibi/filesystem$(SO) lib/chibi/weak$(SO) \ CHIBI_COMPILED_LIBS = lib/chibi/filesystem$(SO) lib/chibi/weak$(SO) \
lib/chibi/heap-stats$(SO) lib/chibi/disasm$(SO) lib/chibi/ast$(SO) \ lib/chibi/heap-stats$(SO) lib/chibi/disasm$(SO) lib/chibi/ast$(SO) \
lib/chibi/emscripten$(SO) lib/chibi/emscripten$(SO)
CHIBI_POSIX_COMPILED_LIBS = lib/chibi/process$(SO) lib/chibi/time$(SO) \ CHIBI_POSIX_COMPILED_LIBS = lib/chibi/process$(SO) lib/chibi/time$(SO) \
lib/chibi/system$(SO) lib/chibi/stty$(SO) lib/chibi/net$(SO) lib/chibi/system$(SO) lib/chibi/stty$(SO) lib/chibi/net$(SO)
CHIBI_WIN32_COMPILED_LIBS = lib/chibi/win32/process-win32$(SO)
CHIBI_CRYPTO_COMPILED_LIBS = lib/chibi/crypto/crypto$(SO) CHIBI_CRYPTO_COMPILED_LIBS = lib/chibi/crypto/crypto$(SO)
CHIBI_IO_COMPILED_LIBS = lib/chibi/io/io$(SO) CHIBI_IO_COMPILED_LIBS = lib/chibi/io/io$(SO)
CHIBI_OPT_COMPILED_LIBS = lib/chibi/optimize/rest$(SO) \ CHIBI_OPT_COMPILED_LIBS = lib/chibi/optimize/rest$(SO) \
@ -37,6 +49,8 @@ EXTRA_COMPILED_LIBS ?=
ifndef EXCLUDE_POSIX_LIBS ifndef EXCLUDE_POSIX_LIBS
CHIBI_COMPILED_LIBS += $(CHIBI_POSIX_COMPILED_LIBS) CHIBI_COMPILED_LIBS += $(CHIBI_POSIX_COMPILED_LIBS)
else
CHIBI_COMPILED_LIBS += $(CHIBI_WIN32_COMPILED_LIBS)
endif endif
COMPILED_LIBS = $(CHIBI_COMPILED_LIBS) $(CHIBI_IO_COMPILED_LIBS) \ COMPILED_LIBS = $(CHIBI_COMPILED_LIBS) $(CHIBI_IO_COMPILED_LIBS) \

81
README-win32.md Normal file
View file

@ -0,0 +1,81 @@
Chibi-scheme for Windows
========================
Chibi-scheme provides limited support for native desktop Windows. To use
fully-featured Chibi-scheme on Windows, consider using POSIX layer such as
Windows Subsytem for Linux(WSL), Cygwin or MSYS.
Currently, only R7RS Small libraries are available for the platform.
Supported Environments
----------------------
Chibi-scheme can be compiled with following platforms:
* Microsoft Visual Studio 2017 (32bit only)
* MinGW32
* MinGW64
* MSYS
Known Issues
------------
Following libraries are not ported yet:
* `(chibi net)`
* `(chibi process)` : `exit` is available through `(scheme process-context)`
* `(chibi stty)`
* `(chibi system)`
* `(chibi time)`
Following library is not completely ported:
* `(chibi filesystem)`
Other issues:
* SRFI-27: Due to C Runtime limitation, the library is not thread-safe
* `make install` is not supported on Windows platforms
* On MSVC, flonum precision is degraded when compared with other compilers
* Cross compilation is not supported
Build with MinGW(Makefile)
--------------------------
The top-level `Makefile` can be used with MinGW.
1. Open MinGW64 or MinGW32 command prompt
2. `make`
3. `make test`
Currently, `make doc` is not supported on these platforms.
Build with MSYS(Makefile)
-------------------------
By default, the Makefile will compile against native Windows API. To use
MSYS's own POSIX emulation layer, specify `PLATFORM=msys`.
1. Open MSYS command prompt
2. `make PLATFORM=msys`
3. `make PLATFORM=msys test`
Build with Visual Studio(CMake)
-------------------------------
Minimal `CMakeLists.txt` is provided as an example to build Chibi-scheme on
Windows platforms. This is only intended to be used with Windows platforms;
currently it does not provide features provided with standard `Makefile` nor
it does not support UNIX/APPLE platforms either.
1. (Make sure CMake was selected with Visual Studio installer)
2. Open this directory with "Open with Visual Studio"
3. Choose "x86-Release" or "x86-Debug" configuration
4. "CMake" => "Build all"
5. "CMake" => "Run Tests" => "chibi-scheme"

View file

@ -22,6 +22,8 @@ a smaller language on startup.
Chibi-Scheme is known to work on **32** and **64-bit** Linux, Chibi-Scheme is known to work on **32** and **64-bit** Linux,
FreeBSD and OS X, Plan 9, Windows (using Cygwin), iOS, Android, FreeBSD and OS X, Plan 9, Windows (using Cygwin), iOS, Android,
ARM and [Emscripten](https://kripken.github.io/emscripten-site). ARM and [Emscripten](https://kripken.github.io/emscripten-site).
Basic support for native Windows desktop also exists. See
README-win32.md for details and build instructions.
To build on most platforms just run `make && make test`. This will To build on most platforms just run `make && make test`. This will
provide a shared library *libchibi-scheme*, as well as a sample provide a shared library *libchibi-scheme*, as well as a sample

View file

@ -32,7 +32,7 @@ before_build:
- if %BUILDTYPE%.==x86MinGW. set CC=c:/msys64/mingw32/bin/gcc - if %BUILDTYPE%.==x86MinGW. set CC=c:/msys64/mingw32/bin/gcc
- if %BUILDTYPE%.==x64MSYS. set CC=gcc - if %BUILDTYPE%.==x64MSYS. set CC=gcc
- if %TOOLCHAIN%.==MSVC. set CC=cl.exe - if %TOOLCHAIN%.==MSVC. set CC=cl.exe
- if %TOOLCHAIN%%BUILDSYSTEM%.==MinGWMSYS2. set EXARG=EXCLUDE_POSIX_LIBS=1 - if %TOOLCHAIN%%BUILDSYSTEM%.==MinGWMSYS2. set EXARG=
- if %TOOLCHAIN%%BUILDSYSTEM%.==MSYSMSYS2. set EXARG=PLATFORM=msys - if %TOOLCHAIN%%BUILDSYSTEM%.==MSYSMSYS2. set EXARG=PLATFORM=msys
- if %BUILDSYSTEM%.==CMAKE. cmake -G Ninja . - if %BUILDSYSTEM%.==CMAKE. cmake -G Ninja .

10
include/chibi/sexp.h Executable file → Normal file
View file

@ -20,11 +20,11 @@ extern "C" {
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#include <errno.h> #include <errno.h>
#define sexp_isalpha(x) ((isalpha)((int)(x))) #define sexp_isalpha(x) (isalpha(x))
#define sexp_isxdigit(x) ((isxdigit)((int)(x))) #define sexp_isxdigit(x) (isxdigit(x))
#define sexp_isdigit(x) ((isdigit)((int)(x))) #define sexp_isdigit(x) (isdigit(x))
#define sexp_tolower(x) ((tolower)((int)(x))) #define sexp_tolower(x) (tolower(x))
#define sexp_toupper(x) ((toupper)((int)(x))) #define sexp_toupper(x) (toupper(x))
#define SEXP_USE_POLL_PORT 0 #define SEXP_USE_POLL_PORT 0
#define sexp_poll_input(ctx, port) usleep(SEXP_POLL_SLEEP_TIME) #define sexp_poll_input(ctx, port) usleep(SEXP_POLL_SLEEP_TIME)
#define sexp_poll_output(ctx, port) usleep(SEXP_POLL_SLEEP_TIME) #define sexp_poll_output(ctx, port) usleep(SEXP_POLL_SLEEP_TIME)

View file

@ -10,6 +10,10 @@
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
#if defined(__MINGW32__) || defined(__MINGW64__)
/* Workaround MinGW header implementation */
errno_t getenv_s(size_t*, char*, size_t, const char*);
#endif
int setenv(const char *name, const char *value, int overwrite) int setenv(const char *name, const char *value, int overwrite)
{ {
int errcode = 0; int errcode = 0;

View file

@ -11,7 +11,11 @@
#define SEXP_DISASM_PAD_WIDTH 4 #define SEXP_DISASM_PAD_WIDTH 4
#if SEXP_64_BIT #if SEXP_64_BIT
#ifdef _WIN32
#define SEXP_PRId "%I64d"
#else
#define SEXP_PRId "%ld" #define SEXP_PRId "%ld"
#endif
#else #else
#define SEXP_PRId "%d" #define SEXP_PRId "%d"
#endif #endif

View file

@ -14,6 +14,7 @@
(cond-expand (cond-expand
(windows (windows
(c-include-verbatim "filesystem_win32_shim.c")
(define-c-struct stat (define-c-struct stat
predicate: stat? predicate: stat?
(dev_t st_dev stat-dev) (dev_t st_dev stat-dev)
@ -30,10 +31,6 @@
(time_t st_mtime stat-mtime) (time_t st_mtime stat-mtime)
(time_t st_ctime stat-ctime))) (time_t st_ctime stat-ctime)))
(else (else
(define-c-type DIR
finalizer: closedir)
(define-c-struct dirent
(string d_name dirent-name))
(define-c-struct stat (define-c-struct stat
predicate: stat? predicate: stat?
(dev_t st_dev stat-dev) (dev_t st_dev stat-dev)
@ -51,18 +48,19 @@
(time_t st_ctime stat-ctime)) (time_t st_ctime stat-ctime))
)) ))
(define-c-type DIR
finalizer: closedir)
(define-c-struct dirent
(string d_name dirent-name))
(cond-expand
((not windows)
(define-c boolean S_ISREG (mode_t)) (define-c boolean S_ISREG (mode_t))
(define-c boolean S_ISDIR (mode_t)) (define-c boolean S_ISDIR (mode_t))
(define-c boolean S_ISCHR (mode_t)) (define-c boolean S_ISCHR (mode_t))
(define-c boolean S_ISBLK (mode_t)) (define-c boolean S_ISBLK (mode_t))
(define-c boolean S_ISFIFO (mode_t)) (define-c boolean S_ISFIFO (mode_t))
(define-c boolean S_ISLNK (mode_t)) (define-c boolean S_ISLNK (mode_t))
(define-c boolean S_ISSOCK (mode_t)))) (define-c boolean S_ISSOCK (mode_t))
(cond-expand (cond-expand
((not windows) ((not windows)
@ -152,7 +150,7 @@
((not windows) ((not windows)
(define-c errno (create-directory "mkdir") (string (default #o775 int)))) (define-c errno (create-directory "mkdir") (string (default #o775 int))))
(else (else
(define-c errno (create-directory "mkdir") (string)))) (define-c errno (create-directory "mkdir_shim") (string (default #o775 int)))))
;;> Deletes the directory named \var{string} from the filesystem. ;;> Deletes the directory named \var{string} from the filesystem.
;;> Does not attempt to delete recursively. ;;> Does not attempt to delete recursively.
@ -160,10 +158,8 @@
(define-c errno (delete-directory "rmdir") (string)) (define-c errno (delete-directory "rmdir") (string))
(cond-expand
((not windows)
(define-c (free DIR) opendir (string)) (define-c (free DIR) opendir (string))
(define-c dirent readdir ((link (pointer DIR)))))) (define-c dirent readdir ((link (pointer DIR))))
;;> Duplicates the given file descriptor, returning he new value, ;;> Duplicates the given file descriptor, returning he new value,
;; or -1 on failure. ;; or -1 on failure.
@ -248,11 +244,9 @@
(port-or-fileno off_t)))) (port-or-fileno off_t))))
;; Used for file-is-readable?, file-is-writable?, file-is-executable?. ;; Used for file-is-readable?, file-is-writable?, file-is-executable?.
(cond-expand
((not windows)
(define-c-const int (access/read "R_OK")) (define-c-const int (access/read "R_OK"))
(define-c-const int (access/write "W_OK")) (define-c-const int (access/write "W_OK"))
(define-c-const int (access/execute "X_OK")))) (define-c-const int (access/execute "X_OK"))
(define-c int (file-access "access") (string int)) (define-c int (file-access "access") (string int))
;;> Applies the specified locking operation using flock(2) to the port ;;> Applies the specified locking operation using flock(2) to the port

View file

@ -0,0 +1,104 @@
/* Win32 shim for (chibi filesystem) */
#include <windows.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <direct.h>
static int mkdir_shim(const char* path, int ignored) {
return mkdir(path);
}
#if !defined(__MINGW32__) && !defined(__MINGW64__)
/* Flags for _access() API */
#define R_OK 4
#define W_OK 2
#define X_OK 1 /* Follow MinGW */
#define SHIM_WIN32_STAT_IS(m, flg) ((m & _S_IFMT) == flg)
#define S_ISREG(m) SHIM_WIN32_STAT_IS(m, _S_IFREG)
#define S_ISDIR(m) SHIM_WIN32_STAT_IS(m, _S_IFDIR)
#define S_ISCHR(m) SHIM_WIN32_STAT_IS(m, _S_IFCHR)
#define S_ISFIFO(m) SHIM_WIN32_STAT_IS(m, _S_IFIFO)
#define S_ISBLK(m) 0
#endif
#define S_ISLNK(m) 0
#define S_ISSOCK(m) S_ISFIFO(m)
struct dirent {
char d_name[MAX_PATH];
};
struct DIR_s {
int want_next;
HANDLE hFind;
struct dirent result;
};
typedef struct DIR_s DIR;
static DIR* opendir(const char* path) {
HANDLE hFind;
WIN32_FIND_DATAA ffd;
DIR* dp;
char* query;
query = malloc(MAX_PATH + 1);
if(!query){
errno = ENOMEM;
return NULL;
}
query[0] = 0;
strncat(query, path, MAX_PATH);
strncat(query, "\\*", MAX_PATH);
query[MAX_PATH] = 0;
hFind = FindFirstFileA(query, &ffd);
if(hFind == INVALID_HANDLE_VALUE){
switch(GetLastError()){
case ERROR_FILE_NOT_FOUND:
errno = ENOENT;
break;
default:
errno = EACCES;
break;
}
return NULL;
}
free(query);
dp = malloc(sizeof(DIR));
if(!dp){
errno = ENOMEM;
return NULL;
}
dp->hFind = hFind;
strncpy(dp->result.d_name, ffd.cFileName, MAX_PATH);
dp->want_next = 0;
return dp;
}
static struct dirent *readdir(DIR *dp) {
BOOL b;
WIN32_FIND_DATAA ffd;
if(dp->want_next){
/* Query the next file */
b = FindNextFile(dp->hFind, &ffd);
if(! b){
return NULL;
}
strncpy(dp->result.d_name, ffd.cFileName, MAX_PATH);
}
dp->want_next = 1;
return &dp->result;
}
static int closedir(DIR *dp) {
BOOL b;
b = FindClose(dp->hFind);
if(! b){
errno = EBADF;
return -1;
}
free(dp);
return 0;
}

View file

@ -6,6 +6,10 @@
#include <sys/sendfile.h> #include <sys/sendfile.h>
#endif #endif
#ifdef _WIN32
#include <io.h>
#endif
#define SEXP_LAST_CONTEXT_CHECK_LIMIT 256 #define SEXP_LAST_CONTEXT_CHECK_LIMIT 256
#define sexp_cookie_ctx(vec) sexp_vector_ref((sexp)vec, SEXP_ZERO) #define sexp_cookie_ctx(vec) sexp_vector_ref((sexp)vec, SEXP_ZERO)

View file

@ -0,0 +1,7 @@
(define (exit . code?)
(%exit (if (pair? code?)
(let ((c (car code?)))
(cond ((integer? c) c)
((eq? #t c) 0)
(else 1)))
0)))

View file

@ -0,0 +1,5 @@
(define-library (chibi win32 process-win32)
(import (scheme base))
(export %exit)
(include-shared "process-win32")
(include "process-win32.scm"))

View file

@ -0,0 +1,5 @@
;;> An interface to Win32 MSVCRT provided process functions and Win32 APIs
(c-system-include "stdlib.h")
(define-c void (%exit exit) (int))

View file

@ -1,6 +1,8 @@
(define-library (scheme process-context) (define-library (scheme process-context)
(import (chibi) (srfi 98) (only (chibi process) exit)) (import (chibi) (srfi 98))
(cond-expand (windows (import (only (chibi win32 process-win32) exit)))
(else (import (only (chibi process) exit))))
(export get-environment-variable get-environment-variables (export get-environment-variable get-environment-variables
command-line exit emergency-exit) command-line exit emergency-exit)
;; TODO: Make exit unwind and finalize properly. ;; TODO: Make exit unwind and finalize properly.

84
lib/srfi/144/lgamma_r.c Normal file
View file

@ -0,0 +1,84 @@
/*
* Ruby's missing/lgamma_r.c took from
* https://github.com/ruby/ruby/commit/39330d6b79c95f67006453156d8405242da04d7b
*/
/* lgamma_r.c - public domain implementation of function lgamma_r(3m)
lgamma_r() is based on gamma(). modified by Tanaka Akira.
reference - Haruhiko Okumura: C-gengo niyoru saishin algorithm jiten
(New Algorithm handbook in C language) (Gijyutsu hyouron
sha, Tokyo, 1991) [in Japanese]
http://oku.edu.mie-u.ac.jp/~okumura/algo/
*/
/***********************************************************
gamma.c -- Gamma function
***********************************************************/
#include <math.h>
#include <errno.h>
#define PI 3.14159265358979324 /* $\pi$ */
#define LOG_2PI 1.83787706640934548 /* $\log 2\pi$ */
#define LOG_PI 1.14472988584940017 /* $\log_e \pi$ */
#define N 8
#define B0 1 /* Bernoulli numbers */
#define B1 (-1.0 / 2.0)
#define B2 ( 1.0 / 6.0)
#define B4 (-1.0 / 30.0)
#define B6 ( 1.0 / 42.0)
#define B8 (-1.0 / 30.0)
#define B10 ( 5.0 / 66.0)
#define B12 (-691.0 / 2730.0)
#define B14 ( 7.0 / 6.0)
#define B16 (-3617.0 / 510.0)
static double
loggamma(double x) /* the natural logarithm of the Gamma function. */
{
double v, w;
if (x == 1.0 || x == 2.0) return 0.0;
v = 1;
while (x < N) { v *= x; x++; }
w = 1 / (x * x);
return ((((((((B16 / (16 * 15)) * w + (B14 / (14 * 13))) * w
+ (B12 / (12 * 11))) * w + (B10 / (10 * 9))) * w
+ (B8 / ( 8 * 7))) * w + (B6 / ( 6 * 5))) * w
+ (B4 / ( 4 * 3))) * w + (B2 / ( 2 * 1))) / x
+ 0.5 * LOG_2PI - log(v) - x + (x - 0.5) * log(x);
}
#ifdef __MINGW_ATTRIB_PURE
/* get rid of bugs in math.h of mingw */
#define modf(_X, _Y) __extension__ ({\
double intpart_modf_bug = intpart_modf_bug;\
double result_modf_bug = modf((_X), &intpart_modf_bug);\
*(_Y) = intpart_modf_bug;\
result_modf_bug;\
})
#endif
/* the natural logarithm of the absolute value of the Gamma function */
double
lgamma_r(double x, int *signp)
{
if (x <= 0) {
double i, f, s;
f = modf(-x, &i);
if (f == 0.0) { /* pole error */
*signp = signbit(x) ? -1 : 1;
errno = ERANGE;
return HUGE_VAL;
}
*signp = (fmod(i, 2.0) != 0.0) ? 1 : -1;
s = sin(PI * f);
if (s < 0) s = -s;
return LOG_PI - log(s) - loggamma(1 - x);
}
*signp = 1;
return loggamma(x);
}

View file

@ -148,11 +148,8 @@
(define-c double (flgamma "tgamma") (double)) (define-c double (flgamma "tgamma") (double))
(cond-expand (cond-expand
(windows (windows
;; FIXME: Implement this. (c-include-verbatim "lgamma_r.c")))
(c-declare "double lgamma_r(double x, int* sign) { *sign = 9999; __debugbreak(); }") (define-c double lgamma_r (double (result int)))
(define-c double lgamma_r (double (result int))))
(else
(define-c double lgamma_r (double (result int)))))
(define-c double (flfirst-bessel "jn") (int double)) (define-c double (flfirst-bessel "jn") (int double))
(define-c double (flsecond-bessel "yn") (int double)) (define-c double (flsecond-bessel "yn") (int double))

View file

@ -398,13 +398,13 @@ sexp sexp_bit_set_p (sexp ctx, sexp self, sexp_sint_t n, sexp i, sexp x) {
return sexp_xtype_exception(ctx, self, "index must be non-negative", i); return sexp_xtype_exception(ctx, self, "index must be non-negative", i);
if (sexp_fixnump(x)) { if (sexp_fixnump(x)) {
return sexp_make_boolean((pos < sizeof(sexp_uint_t)*CHAR_BIT) return sexp_make_boolean((pos < sizeof(sexp_uint_t)*CHAR_BIT)
&& (sexp_unbox_fixnum(x) & (1UL<<pos))); && (sexp_unbox_fixnum(x) & ((sexp_uint_t)1<<pos)));
#if SEXP_USE_BIGNUMS #if SEXP_USE_BIGNUMS
} else if (sexp_bignump(x)) { } else if (sexp_bignump(x)) {
pos /= (sizeof(sexp_uint_t)*CHAR_BIT); pos /= (sizeof(sexp_uint_t)*CHAR_BIT);
rem = (sexp_unbox_fixnum(i) - pos*sizeof(sexp_uint_t)*CHAR_BIT); rem = (sexp_unbox_fixnum(i) - pos*sizeof(sexp_uint_t)*CHAR_BIT);
return sexp_make_boolean((pos < (sexp_sint_t)sexp_bignum_length(x)) return sexp_make_boolean((pos < (sexp_sint_t)sexp_bignum_length(x))
&& (sexp_bignum_data(x)[pos] & (1UL<<rem))); && (sexp_bignum_data(x)[pos] & ((sexp_uint_t)1<<rem)));
#endif #endif
} else { } else {
return sexp_type_exception(ctx, self, SEXP_FIXNUM, x); return sexp_type_exception(ctx, self, SEXP_FIXNUM, x);

View file

@ -5,11 +5,9 @@
#ifdef __APPLE__ #ifdef __APPLE__
#include <crt_externs.h> #include <crt_externs.h>
#define environ (*_NSGetEnviron()) #define environ (*_NSGetEnviron())
#else #elif !defined(_WIN32) && !defined(PLAN9)
#ifndef PLAN9
extern char **environ; extern char **environ;
#endif #endif
#endif
#include <chibi/eval.h> #include <chibi/eval.h>

4
sexp.c
View file

@ -15,6 +15,10 @@ struct sexp_huff_entry {
#include "chibi/sexp-huff.h" #include "chibi/sexp-huff.h"
#endif #endif
#ifdef _WIN32
#include <io.h>
#endif
static int sexp_initialized_p = 0; static int sexp_initialized_p = 0;
static const char sexp_separators[] = { static const char sexp_separators[] = {