mirror of
https://github.com/justinethier/cyclone.git
synced 2025-05-20 14:19:17 +02:00
Compare commits
No commits in common. "master" and "v0.36.0" have entirely different histories.
29 changed files with 118 additions and 653 deletions
27
.github/workflows/c-runtime-unit-tests.yml
vendored
27
.github/workflows/c-runtime-unit-tests.yml
vendored
|
@ -1,27 +0,0 @@
|
||||||
name: C Runtime Unit Tests
|
|
||||||
|
|
||||||
#on: [create]
|
|
||||||
on: [push]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
arch: [64]
|
|
||||||
|
|
||||||
steps:
|
|
||||||
# Install dependencies
|
|
||||||
- name: Install libck
|
|
||||||
run: sudo apt-get install libck-dev
|
|
||||||
#- name: Install Cyclone
|
|
||||||
# run: |
|
|
||||||
# wget https://github.com/cyclone-scheme/binary-releases/raw/master/ubuntu-18.04-lts/cyclone-scheme_0.30.0_amd64.deb
|
|
||||||
# sudo apt install ./cyclone-scheme_0.30.0_amd64.deb
|
|
||||||
- uses: actions/checkout@v1
|
|
||||||
|
|
||||||
# Execute runtime library unit tests
|
|
||||||
- name: make test-lib
|
|
||||||
run: make libcyclone.a && make test-lib && ./test-lib
|
|
22
.github/workflows/ci.yml
vendored
22
.github/workflows/ci.yml
vendored
|
@ -1,22 +0,0 @@
|
||||||
name: Ubuntu Linux Build
|
|
||||||
|
|
||||||
on: [push]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
arch: [32, 64]
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v1
|
|
||||||
- name: Install deps
|
|
||||||
run: sudo apt-get install indent
|
|
||||||
- name: Install ck
|
|
||||||
run: sudo apt-get install libck-dev
|
|
||||||
- name: make runtime
|
|
||||||
run: make libcyclone.a
|
|
||||||
|
|
3
.github/workflows/formatting.yml
vendored
3
.github/workflows/formatting.yml
vendored
|
@ -16,6 +16,5 @@ jobs:
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
run: sudo apt-get install -y indent
|
run: sudo apt-get install -y indent
|
||||||
- name: formatting
|
- name: formatting
|
||||||
run: |
|
run: make test-format
|
||||||
make test-format
|
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ jobs:
|
||||||
|
|
||||||
- name: upload deb
|
- name: upload deb
|
||||||
if: matrix.arch == '64'
|
if: matrix.arch == '64'
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v1
|
||||||
with:
|
with:
|
||||||
name: cyclone-scheme docs
|
name: cyclone-scheme docs
|
||||||
path: html.tar.bz2
|
path: html.tar.bz2
|
16
CHANGELOG.md
16
CHANGELOG.md
|
@ -1,21 +1,5 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## 0.37.0 - TBD
|
|
||||||
|
|
||||||
Bug Fixes
|
|
||||||
|
|
||||||
- Yorick Hardy fixed the runtime to return the appropriate types of objects to exception handlers.
|
|
||||||
- Yorick Hardy modified the runtime to allow `thread-terminate!` to take a thread object as an argument, per SRFI 18.
|
|
||||||
- @nmeum fixed `open_memstream`/`fmemopen` feature detection with GCC >= 14.
|
|
||||||
- Fixed a bug in `apply` where an error may be raised when processing quoted sub-expressions. For example the following would throw an error: `(apply cons '(5 (1 2)))`. Thanks to @srgx for the bug report!
|
|
||||||
- Fixed a beta expansion optimization bug where code such as the following would cause the compiler to hang. Thanks to Yorick Hardy for the bug report:
|
|
||||||
|
|
||||||
(define (compile-forever x) x (compile-forever x))
|
|
||||||
|
|
||||||
- Added a fix from Yorick Hardy to define `*ai-v4mapped*` to zero on platforms where `AI_V4MAPPED` is undefined.
|
|
||||||
- Updated `sqrt` to properly handle complex results given non-complex input. EG: `(sqrt -1) ==> 1i`. And updated the parser to properly handle `+i` and `-i`. Thanks to Christopher Hebert for the bug reports!
|
|
||||||
- Updated `cond-expand` to raise an error if no clauses match, instead of returning `#t`.
|
|
||||||
|
|
||||||
## 0.36.0 - February 14, 2024
|
## 0.36.0 - February 14, 2024
|
||||||
|
|
||||||
Features
|
Features
|
||||||
|
|
19
Makefile
19
Makefile
|
@ -131,10 +131,7 @@ tags :
|
||||||
ctags -R *
|
ctags -R *
|
||||||
|
|
||||||
format : gc.c runtime.c ffi.c hashset.c mstreams.c ck-polyfill.c ck-polyfill.h $(HEADER_DIR)/*.h
|
format : gc.c runtime.c ffi.c hashset.c mstreams.c ck-polyfill.c ck-polyfill.h $(HEADER_DIR)/*.h
|
||||||
$(FORMAT_CMD) $(HEADER_DIR)/hashset.h
|
$(FORMAT_CMD) $(HEADER_DIR)/*.h
|
||||||
$(FORMAT_CMD) $(HEADER_DIR)/runtime.h
|
|
||||||
$(FORMAT_CMD) $(HEADER_DIR)/runtime-main.h
|
|
||||||
$(FORMAT_CMD) $(HEADER_DIR)/types.h
|
|
||||||
$(FORMAT_CMD) ck-polyfill.c
|
$(FORMAT_CMD) ck-polyfill.c
|
||||||
$(FORMAT_CMD) ck-polyfill.h
|
$(FORMAT_CMD) ck-polyfill.h
|
||||||
$(FORMAT_CMD) ffi.c
|
$(FORMAT_CMD) ffi.c
|
||||||
|
@ -144,17 +141,7 @@ format : gc.c runtime.c ffi.c hashset.c mstreams.c ck-polyfill.c ck-polyfill.h $
|
||||||
$(FORMAT_CMD) runtime.c
|
$(FORMAT_CMD) runtime.c
|
||||||
|
|
||||||
test-format :
|
test-format :
|
||||||
./scripts/check-c-formatting.sh $(HEADER_DIR)/hashset.h
|
|
||||||
./scripts/check-c-formatting.sh $(HEADER_DIR)/runtime.h
|
|
||||||
./scripts/check-c-formatting.sh $(HEADER_DIR)/runtime-main.h
|
|
||||||
./scripts/check-c-formatting.sh $(HEADER_DIR)/types.h
|
|
||||||
# ./scripts/check-c-formatting.sh ffi.c
|
|
||||||
# ./scripts/check-c-formatting.sh gc.c
|
|
||||||
./scripts/check-c-formatting.sh hashset.c
|
./scripts/check-c-formatting.sh hashset.c
|
||||||
# ./scripts/check-c-formatting.sh mstreams.c
|
|
||||||
# ./scripts/check-c-formatting.sh runtime.c
|
|
||||||
# ./scripts/check-c-formatting.sh ck-polyfill.c
|
|
||||||
# ./scripts/check-c-formatting.sh ck-polyfill.h
|
|
||||||
|
|
||||||
# This is a test directive used to test changes to a SLD file
|
# This is a test directive used to test changes to a SLD file
|
||||||
# EG: make sld SLDPATH=scheme/cyclone SLD=macros
|
# EG: make sld SLDPATH=scheme/cyclone SLD=macros
|
||||||
|
@ -355,7 +342,3 @@ install-bin : cyclone icyc
|
||||||
$(MKDIR) $(DESTDIR)$(BINDIR)
|
$(MKDIR) $(DESTDIR)$(BINDIR)
|
||||||
$(INSTALL) -m0755 cyclone $(DESTDIR)$(BINDIR)/
|
$(INSTALL) -m0755 cyclone $(DESTDIR)$(BINDIR)/
|
||||||
$(INSTALL) -m0755 icyc $(DESTDIR)$(BINDIR)/
|
$(INSTALL) -m0755 icyc $(DESTDIR)$(BINDIR)/
|
||||||
|
|
||||||
# TODO: is this linking in local lcyclone or the system one????
|
|
||||||
test-lib: test-lib.c
|
|
||||||
$(CCOMP) -g test-lib.c -o test-lib -L . $(LIBS)
|
|
||||||
|
|
|
@ -91,9 +91,8 @@ DESTDIR ?=
|
||||||
|
|
||||||
# Automatically detect platform-specific flags, instead of using autoconf
|
# Automatically detect platform-specific flags, instead of using autoconf
|
||||||
#CYC_PLATFORM_HAS_MEMSTREAM ?= 1
|
#CYC_PLATFORM_HAS_MEMSTREAM ?= 1
|
||||||
HASH := \# # Needed for compatibility with GNU Make < 4.3 <https://lists.gnu.org/archive/html/info-gnu/2020-01/msg00004.html>
|
CYC_PLATFORM_HAS_MEMSTREAM := $(shell echo "main(){char *buf; int len; open_memstream(&buf, &len);}" | $(CC) -xc - >/dev/null 2>/dev/null && echo 1 || echo 0)
|
||||||
CYC_PLATFORM_HAS_MEMSTREAM := $(shell printf "$(HASH)include <stdio.h>\n%s\n" "int main(void){char *buf; size_t len; open_memstream(&buf, &len); return 0;}" | $(CC) -xc - >/dev/null 2>/dev/null && echo 1 || echo 0)
|
CYC_PLATFORM_HAS_FMEMOPEN := $(shell echo "main(){char *buf; fmemopen(&buf, 0, \"r\");}" | $(CC) -xc - >/dev/null 2>/dev/null && echo 1 || echo 0)
|
||||||
CYC_PLATFORM_HAS_FMEMOPEN := $(shell printf "$(HASH)include <stdio.h>\n%s\n" "int main(void){char *buf; fmemopen(&buf, 0, \"r\"); return 0;}" | $(CC) -xc - >/dev/null 2>/dev/null && echo 1 || echo 0)
|
|
||||||
|
|
||||||
# code from chibi's makefile to detect platform
|
# code from chibi's makefile to detect platform
|
||||||
ifndef PLATFORM
|
ifndef PLATFORM
|
||||||
|
|
|
@ -15,8 +15,3 @@ Steps for making a release of Cyclone:
|
||||||
- Update release on Homebrew (automated)
|
- Update release on Homebrew (automated)
|
||||||
- Update release on Dockerhub (push to bitbucket)
|
- Update release on Dockerhub (push to bitbucket)
|
||||||
- Upload new binary from cyclone-bootstrap release build to the cyclone-scheme "packages" repo
|
- Upload new binary from cyclone-bootstrap release build to the cyclone-scheme "packages" repo
|
||||||
- Update WASM hosted Cyclone
|
|
||||||
- Trigger CI action on the WASM repo to recompile the WASM binary: https://github.com/cyclone-scheme/wasm-terminal
|
|
||||||
- Download the generated `.zip` artifact
|
|
||||||
- Extract `terminal.js` and `terminal.wasm` and copy to the `_site` directory in the repo to update the build
|
|
||||||
- Optionally update year in the `terminal.html` file
|
|
||||||
|
|
|
@ -92,9 +92,9 @@ The current thread exits the running state as if its quantum had expired.
|
||||||
|
|
||||||
# thread-terminate!
|
# thread-terminate!
|
||||||
|
|
||||||
(thread-terminate! thread)
|
(thread-terminate!)
|
||||||
|
|
||||||
Immediately abort the given thread.
|
Immediately abort the current thread.
|
||||||
|
|
||||||
# thread-join!
|
# thread-join!
|
||||||
|
|
||||||
|
|
105
gc.c
105
gc.c
|
@ -55,7 +55,6 @@ static unsigned char gc_color_purple = 1; // There are many "shades" of pu
|
||||||
|
|
||||||
static int gc_status_col = STATUS_SYNC1;
|
static int gc_status_col = STATUS_SYNC1;
|
||||||
static int gc_stage = STAGE_RESTING;
|
static int gc_stage = STAGE_RESTING;
|
||||||
static int gc_threads_merged = 0;
|
|
||||||
|
|
||||||
// Does not need sync, only used by collector thread
|
// Does not need sync, only used by collector thread
|
||||||
static void **mark_stack = NULL;
|
static void **mark_stack = NULL;
|
||||||
|
@ -1902,38 +1901,6 @@ void gc_mut_update(gc_thread_data * thd, object old_obj, object value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gc_sweep_primordial_thread_heap()
|
|
||||||
{
|
|
||||||
int heap_type, must_free;
|
|
||||||
gc_heap *h, *prev, *next, *sweep;
|
|
||||||
pthread_mutex_lock(&(primordial_thread->lock));
|
|
||||||
for (heap_type = 0; heap_type < NUM_HEAP_TYPES; heap_type++) {
|
|
||||||
prev = primordial_thread->heap->heap[heap_type];
|
|
||||||
h = prev->next;
|
|
||||||
while (h != NULL) {
|
|
||||||
next = h->next;
|
|
||||||
must_free = 0;
|
|
||||||
if (h->is_unswept) {
|
|
||||||
if (h->type <= LAST_FIXED_SIZE_HEAP_TYPE) {
|
|
||||||
sweep = gc_sweep_fixed_size(h, primordial_thread);
|
|
||||||
} else {
|
|
||||||
sweep = gc_sweep(h, primordial_thread);
|
|
||||||
}
|
|
||||||
must_free = (sweep == NULL);
|
|
||||||
} else {
|
|
||||||
must_free = gc_is_heap_empty(h);
|
|
||||||
}
|
|
||||||
if (must_free) {
|
|
||||||
gc_heap_free(h, prev);
|
|
||||||
} else {
|
|
||||||
prev = h;
|
|
||||||
}
|
|
||||||
h = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&(primordial_thread->lock));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Called by a mutator to cooperate with the collector thread
|
* @brief Called by a mutator to cooperate with the collector thread
|
||||||
* @param thd Mutator's thread data
|
* @param thd Mutator's thread data
|
||||||
|
@ -1944,23 +1911,11 @@ static void gc_sweep_primordial_thread_heap()
|
||||||
*/
|
*/
|
||||||
void gc_mut_cooperate(gc_thread_data * thd, int buf_len)
|
void gc_mut_cooperate(gc_thread_data * thd, int buf_len)
|
||||||
{
|
{
|
||||||
int i, status_c, status_m, stage, merged;
|
int i, status_c, status_m;
|
||||||
#if GC_DEBUG_VERBOSE
|
#if GC_DEBUG_VERBOSE
|
||||||
int debug_print = 0;
|
int debug_print = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Since terminated threads' heap pages are merged into
|
|
||||||
// the primordial thread's heap, it may be that a sweep
|
|
||||||
// for the primordeal thread is never triggered even though
|
|
||||||
// the heep keeps growing. Perform a sweep here if necessary.
|
|
||||||
stage = ck_pr_load_int(&gc_stage);
|
|
||||||
merged = ck_pr_load_int(&gc_threads_merged);
|
|
||||||
if ((thd == primordial_thread) && (merged == 1)
|
|
||||||
&& ((stage == STAGE_SWEEPING) || (stage == STAGE_RESTING))) {
|
|
||||||
gc_sweep_primordial_thread_heap();
|
|
||||||
ck_pr_cas_int(&gc_threads_merged, 1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle any pending marks from write barrier
|
// Handle any pending marks from write barrier
|
||||||
gc_sum_pending_writes(thd, 0);
|
gc_sum_pending_writes(thd, 0);
|
||||||
|
|
||||||
|
@ -2784,28 +2739,10 @@ void gc_thread_data_free(gc_thread_data * thd)
|
||||||
*
|
*
|
||||||
* This function assumes appropriate locks are already held.
|
* This function assumes appropriate locks are already held.
|
||||||
*/
|
*/
|
||||||
int gc_heap_merge(gc_heap * hdest, gc_heap * hsrc)
|
void gc_heap_merge(gc_heap * hdest, gc_heap * hsrc)
|
||||||
{
|
{
|
||||||
int freed = 0;
|
|
||||||
gc_heap *last = gc_heap_last(hdest);
|
gc_heap *last = gc_heap_last(hdest);
|
||||||
gc_heap *cur = hsrc, *prev = last, *next;
|
|
||||||
last->next = hsrc;
|
last->next = hsrc;
|
||||||
// free any empty heaps and convert remaining heaps
|
|
||||||
// to free list so that they can be swept
|
|
||||||
while (cur != NULL) {
|
|
||||||
cur->is_unswept = 1;
|
|
||||||
next = cur->next;
|
|
||||||
if (gc_is_heap_empty(cur)) {
|
|
||||||
freed += cur->size;
|
|
||||||
gc_heap_free(cur, prev);
|
|
||||||
} else {
|
|
||||||
gc_convert_heap_page_to_free_list(cur, primordial_thread);
|
|
||||||
ck_pr_cas_int(&gc_threads_merged, 0, 1);
|
|
||||||
prev = cur;
|
|
||||||
}
|
|
||||||
cur = next;
|
|
||||||
}
|
|
||||||
return freed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2818,47 +2755,15 @@ int gc_heap_merge(gc_heap * hdest, gc_heap * hsrc)
|
||||||
void gc_merge_all_heaps(gc_thread_data * dest, gc_thread_data * src)
|
void gc_merge_all_heaps(gc_thread_data * dest, gc_thread_data * src)
|
||||||
{
|
{
|
||||||
gc_heap *hdest, *hsrc;
|
gc_heap *hdest, *hsrc;
|
||||||
int freed, heap_type, i;
|
int heap_type;
|
||||||
pair_type *context = NULL;
|
|
||||||
vector_type *v = src->scm_thread_obj;
|
|
||||||
|
|
||||||
// The following objects are part of the thread context and should
|
|
||||||
// be stored on the primordial thread's heap. Make this explicit by
|
|
||||||
// including it in the thread object.
|
|
||||||
if (src->gc_num_args > 0) {
|
|
||||||
for (i = src->gc_num_args - 1; i >= 0; --i) {
|
|
||||||
context = gc_alloc_pair(dest, (src->gc_args)[i], context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (src->gc_cont != NULL && is_object_type(src->gc_cont)) {
|
|
||||||
context = gc_alloc_pair(dest, src->gc_cont, context);
|
|
||||||
}
|
|
||||||
if (src->exception_handler_stack != NULL) {
|
|
||||||
context = gc_alloc_pair(dest, src->exception_handler_stack, context);
|
|
||||||
}
|
|
||||||
if (src->param_objs != NULL) {
|
|
||||||
context = gc_alloc_pair(dest, src->param_objs, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context != NULL) {
|
|
||||||
gc_mark_black(context);
|
|
||||||
v->elements[8] = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (heap_type = 0; heap_type < NUM_HEAP_TYPES; heap_type++) {
|
for (heap_type = 0; heap_type < NUM_HEAP_TYPES; heap_type++) {
|
||||||
hdest = dest->heap->heap[heap_type];
|
hdest = dest->heap->heap[heap_type];
|
||||||
hsrc = src->heap->heap[heap_type];
|
hsrc = src->heap->heap[heap_type];
|
||||||
if (!hdest) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"WARNING !!!!! merging heap type %d does not happen: hdest = %p hsrc = %p size = %d\n",
|
|
||||||
heap_type, hdest, hsrc, hsrc->size);
|
|
||||||
fflush(stderr);
|
|
||||||
}
|
|
||||||
if (hdest && hsrc) {
|
if (hdest && hsrc) {
|
||||||
freed = gc_heap_merge(hdest, hsrc);
|
gc_heap_merge(hdest, hsrc);
|
||||||
ck_pr_add_ptr(&(dest->cached_heap_total_sizes[heap_type]),
|
ck_pr_add_ptr(&(dest->cached_heap_total_sizes[heap_type]),
|
||||||
ck_pr_load_ptr(&(src->cached_heap_total_sizes[heap_type])) -
|
ck_pr_load_ptr(&(src->cached_heap_total_sizes[heap_type])));
|
||||||
freed);
|
|
||||||
ck_pr_add_ptr(&(dest->cached_heap_free_sizes[heap_type]),
|
ck_pr_add_ptr(&(dest->cached_heap_free_sizes[heap_type]),
|
||||||
ck_pr_load_ptr(&(src->cached_heap_free_sizes[heap_type])));
|
ck_pr_load_ptr(&(src->cached_heap_free_sizes[heap_type])));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,87 +0,0 @@
|
||||||
;; cyclone.scm
|
|
||||||
(use-modules
|
|
||||||
(gnu packages)
|
|
||||||
(gnu packages multiprecision)
|
|
||||||
((guix licenses)
|
|
||||||
#:select (gpl2 gpl2+ lgpl2.0+ lgpl2.1 lgpl2.1+ lgpl3+ asl2.0
|
|
||||||
bsd-0 bsd-3 cc-by-sa4.0 non-copyleft expat
|
|
||||||
public-domain))
|
|
||||||
(guix gexp)
|
|
||||||
(guix packages)
|
|
||||||
(guix download)
|
|
||||||
(guix git-download)
|
|
||||||
(guix utils)
|
|
||||||
(guix build-system gnu)
|
|
||||||
(gnu packages c))
|
|
||||||
|
|
||||||
(define-public cyclone
|
|
||||||
(package
|
|
||||||
(name "cyclone")
|
|
||||||
(version "0.36.0")
|
|
||||||
(source (origin
|
|
||||||
(method git-fetch)
|
|
||||||
(uri (git-reference
|
|
||||||
(url "https://github.com/justinethier/cyclone-bootstrap")
|
|
||||||
(commit (string-append "v" version))))
|
|
||||||
(sha256
|
|
||||||
(base32
|
|
||||||
"0fv0mnrn5shbx77383f4mbkvc4i9yyj1bjm3dfyhipnaqapbhqpi"))
|
|
||||||
(file-name (git-file-name name version))))
|
|
||||||
(build-system gnu-build-system)
|
|
||||||
(arguments
|
|
||||||
(list
|
|
||||||
#:test-target "test"
|
|
||||||
#:make-flags #~(list (string-append
|
|
||||||
"CC=" #$(this-package-input "gcc-toolchain")
|
|
||||||
"/bin/gcc")
|
|
||||||
(string-append "PREFIX=" #$output)
|
|
||||||
(string-append "COMP_INCDIRS=-I$(PREFIX)/include -I"
|
|
||||||
#$(this-package-input "gcc-toolchain")
|
|
||||||
"/include")
|
|
||||||
(string-append
|
|
||||||
"COMP_LIBDIRS=-L$(PREFIX)/lib "
|
|
||||||
"-Wl,-rpath=" #$(this-package-input "ck") "/lib "
|
|
||||||
"-L" #$(this-package-input "ck") "/lib "
|
|
||||||
"-Wl,-rpath=" #$(this-package-input "libtommath")
|
|
||||||
"/lib "
|
|
||||||
"-L" #$(this-package-input "libtommath") "/lib "
|
|
||||||
"-Wl,-rpath="
|
|
||||||
#$(this-package-input "gcc-toolchain") "/lib "
|
|
||||||
"-L" #$(this-package-input "gcc-toolchain")
|
|
||||||
"/lib"))
|
|
||||||
#:phases #~(modify-phases %standard-phases
|
|
||||||
(delete 'configure) ; no configure script
|
|
||||||
(add-before 'build 'replace-cyclonebn
|
|
||||||
(lambda* (#:key outputs #:allow-other-keys)
|
|
||||||
(substitute* "Makefile"
|
|
||||||
(("-lcyclonebn")
|
|
||||||
"-ltommath")
|
|
||||||
(("^[$][(]CYC_BN_LIB[)] :")
|
|
||||||
"dont-build-cyclonebn :")
|
|
||||||
(("^ [$][(]INSTALL[)] .* [$][(]CYC_BN_LIB[)].*$")
|
|
||||||
"#dont-install-cyclonebn\n")
|
|
||||||
(("[$][(]CYC_BN_LIB[)]")
|
|
||||||
""))
|
|
||||||
(substitute* "Makefile.config"
|
|
||||||
(("-lcyclonebn")
|
|
||||||
"-ltommath"))))
|
|
||||||
(add-after 'install 'wrap
|
|
||||||
(lambda _
|
|
||||||
(wrap-program (string-append #$output "/bin/cyclone")
|
|
||||||
`("LIBRARY_PATH" ":" prefix
|
|
||||||
,(list (string-append
|
|
||||||
#$(this-package-input "gcc-toolchain")
|
|
||||||
"/lib")))))))))
|
|
||||||
(inputs (list ck libtommath (module-ref (resolve-interface
|
|
||||||
'(gnu packages commencement))
|
|
||||||
'gcc-toolchain)))
|
|
||||||
(home-page "https://justinethier.github.io/cyclone/")
|
|
||||||
(synopsis "R7RS Scheme to C compiler")
|
|
||||||
(description
|
|
||||||
"Cyclone Scheme is a R7RS Scheme-to-C compiler that uses a variant of
|
|
||||||
Cheney on the MTA to implement full tail recursion, continuations, and
|
|
||||||
generational garbage collection. It also includes the Winds package manager
|
|
||||||
for installing Cyclone libraries.")
|
|
||||||
(license expat)))
|
|
||||||
|
|
||||||
cyclone
|
|
|
@ -256,7 +256,7 @@ extern "C" {
|
||||||
/* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */
|
/* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */
|
||||||
typedef int private_mp_prime_callback(unsigned char *dst, int len, void *dat);
|
typedef int private_mp_prime_callback(unsigned char *dst, int len, void *dat);
|
||||||
typedef private_mp_prime_callback MP_DEPRECATED(mp_rand_source)
|
typedef private_mp_prime_callback MP_DEPRECATED(mp_rand_source)
|
||||||
ltm_prime_callback;
|
ltm_prime_callback;
|
||||||
|
|
||||||
/* error code to char* string */
|
/* error code to char* string */
|
||||||
const char *mp_error_to_string(mp_err code) MP_WUR;
|
const char *mp_error_to_string(mp_err code) MP_WUR;
|
||||||
|
@ -766,14 +766,15 @@ extern "C" {
|
||||||
|
|
||||||
MP_DEPRECATED(mp_ubin_size) int mp_unsigned_bin_size(const mp_int *
|
MP_DEPRECATED(mp_ubin_size) int mp_unsigned_bin_size(const mp_int *
|
||||||
a) MP_WUR;
|
a) MP_WUR;
|
||||||
MP_DEPRECATED(mp_from_ubin) mp_err mp_read_unsigned_bin(mp_int * a, const unsigned char
|
MP_DEPRECATED(mp_from_ubin) mp_err mp_read_unsigned_bin(mp_int * a,
|
||||||
|
const unsigned char
|
||||||
*b, int c) MP_WUR;
|
*b, int c) MP_WUR;
|
||||||
MP_DEPRECATED(mp_to_ubin) mp_err mp_to_unsigned_bin(const mp_int * a,
|
MP_DEPRECATED(mp_to_ubin) mp_err mp_to_unsigned_bin(const mp_int * a,
|
||||||
unsigned char *b) MP_WUR;
|
unsigned char *b) MP_WUR;
|
||||||
MP_DEPRECATED(mp_to_ubin) mp_err mp_to_unsigned_bin_n(const mp_int * a,
|
MP_DEPRECATED(mp_to_ubin) mp_err mp_to_unsigned_bin_n(const mp_int * a,
|
||||||
unsigned char *b,
|
unsigned char *b,
|
||||||
unsigned long *outlen)
|
unsigned long *outlen)
|
||||||
MP_WUR;
|
MP_WUR;
|
||||||
|
|
||||||
MP_DEPRECATED(mp_sbin_size) int mp_signed_bin_size(const mp_int * a) MP_WUR;
|
MP_DEPRECATED(mp_sbin_size) int mp_signed_bin_size(const mp_int * a) MP_WUR;
|
||||||
MP_DEPRECATED(mp_from_sbin) mp_err mp_read_signed_bin(mp_int * a,
|
MP_DEPRECATED(mp_from_sbin) mp_err mp_read_signed_bin(mp_int * a,
|
||||||
|
@ -784,7 +785,7 @@ extern "C" {
|
||||||
MP_DEPRECATED(mp_to_sbin) mp_err mp_to_signed_bin_n(const mp_int * a,
|
MP_DEPRECATED(mp_to_sbin) mp_err mp_to_signed_bin_n(const mp_int * a,
|
||||||
unsigned char *b,
|
unsigned char *b,
|
||||||
unsigned long *outlen)
|
unsigned long *outlen)
|
||||||
MP_WUR;
|
MP_WUR;
|
||||||
|
|
||||||
size_t mp_ubin_size(const mp_int * a) MP_WUR;
|
size_t mp_ubin_size(const mp_int * a) MP_WUR;
|
||||||
mp_err mp_from_ubin(mp_int * a, const unsigned char *buf, size_t size) MP_WUR;
|
mp_err mp_from_ubin(mp_int * a, const unsigned char *buf, size_t size) MP_WUR;
|
||||||
|
|
|
@ -385,7 +385,7 @@ int gc_is_mutator_new(gc_thread_data * thd);
|
||||||
void gc_sleep_ms(int ms);
|
void gc_sleep_ms(int ms);
|
||||||
gc_heap *gc_heap_create(int heap_type, size_t size, gc_thread_data * thd);
|
gc_heap *gc_heap_create(int heap_type, size_t size, gc_thread_data * thd);
|
||||||
gc_heap *gc_heap_free(gc_heap * page, gc_heap * prev_page);
|
gc_heap *gc_heap_free(gc_heap * page, gc_heap * prev_page);
|
||||||
int gc_heap_merge(gc_heap * hdest, gc_heap * hsrc);
|
void gc_heap_merge(gc_heap * hdest, gc_heap * hsrc);
|
||||||
void gc_merge_all_heaps(gc_thread_data * dest, gc_thread_data * src);
|
void gc_merge_all_heaps(gc_thread_data * dest, gc_thread_data * src);
|
||||||
void gc_print_stats(gc_heap * h);
|
void gc_print_stats(gc_heap * h);
|
||||||
gc_heap *gc_grow_heap(gc_heap * h, size_t size, gc_thread_data * thd);
|
gc_heap *gc_grow_heap(gc_heap * h, size_t size, gc_thread_data * thd);
|
||||||
|
@ -1261,9 +1261,6 @@ typedef pair_type *pair;
|
||||||
n->pair_car = a; \
|
n->pair_car = a; \
|
||||||
n->pair_cdr = d;
|
n->pair_cdr = d;
|
||||||
|
|
||||||
/** Create a new pair in the thread's heap */
|
|
||||||
void *gc_alloc_pair(gc_thread_data * data, object head, object tail);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set members of the given pair
|
* Set members of the given pair
|
||||||
* @param n - Pointer to a pair object
|
* @param n - Pointer to a pair object
|
||||||
|
|
141
runtime.c
141
runtime.c
|
@ -8,7 +8,6 @@
|
||||||
* This file contains the C runtime used by compiled programs.
|
* This file contains the C runtime used by compiled programs.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <ck_hs.h>
|
#include <ck_hs.h>
|
||||||
#include <ck_ht.h>
|
#include <ck_ht.h>
|
||||||
#include <ck_pr.h>
|
#include <ck_pr.h>
|
||||||
|
@ -30,8 +29,6 @@ static uint32_t Cyc_utf8_decode(uint32_t * state, uint32_t * codep,
|
||||||
static int Cyc_utf8_count_code_points_and_bytes(uint8_t * s,
|
static int Cyc_utf8_count_code_points_and_bytes(uint8_t * s,
|
||||||
char_type * codepoint,
|
char_type * codepoint,
|
||||||
int *cpts, int *bytes);
|
int *cpts, int *bytes);
|
||||||
void gc_start_major_collection(gc_thread_data * thd);
|
|
||||||
static void Cyc_cancel_thread(gc_thread_data * thd);
|
|
||||||
|
|
||||||
/* Error checking section - type mismatch, num args, etc */
|
/* Error checking section - type mismatch, num args, etc */
|
||||||
/* Type names to use for error messages */
|
/* Type names to use for error messages */
|
||||||
|
@ -214,8 +211,6 @@ const object Cyc_RECORD_MARKER = &__RECORD;
|
||||||
static ck_hs_t lib_table;
|
static ck_hs_t lib_table;
|
||||||
static ck_hs_t symbol_table;
|
static ck_hs_t symbol_table;
|
||||||
static int symbol_table_initial_size = 4096;
|
static int symbol_table_initial_size = 4096;
|
||||||
static int cyclone_thread_key_create = 1;
|
|
||||||
static pthread_key_t cyclone_thread_key;
|
|
||||||
static pthread_mutex_t symbol_table_lock;
|
static pthread_mutex_t symbol_table_lock;
|
||||||
|
|
||||||
char **env_variables = NULL;
|
char **env_variables = NULL;
|
||||||
|
@ -706,30 +701,24 @@ object Cyc_default_exception_handler(void *data, object _, int argc,
|
||||||
{
|
{
|
||||||
object err = args[0];
|
object err = args[0];
|
||||||
int is_msg = 1;
|
int is_msg = 1;
|
||||||
|
fprintf(stderr, "Error: ");
|
||||||
|
|
||||||
if ((err == NULL) || is_value_type(err) || type_of(err) != pair_tag || type_of(car(err)) != symbol_tag) {
|
if ((err == NULL) || is_value_type(err) || type_of(err) != pair_tag) {
|
||||||
fprintf(stderr, "Error: ");
|
|
||||||
Cyc_display(data, err, stderr);
|
Cyc_display(data, err, stderr);
|
||||||
} else {
|
} else {
|
||||||
if (strncmp(((symbol) car(err))->desc, "error", 5) == 0) {
|
// Error is list of form (type arg1 ... argn)
|
||||||
fprintf(stderr, "Error: ");
|
err = cdr(err); // skip type field
|
||||||
// Error is list of form (type arg1 ... argn)
|
for (; (err != NULL); err = cdr(err)) { // output with no enclosing parens
|
||||||
err = cdr(err); // skip type field
|
if (is_msg && is_object_type(car(err)) && type_of(car(err)) == string_tag) {
|
||||||
for (; (err != NULL); err = cdr(err)) { // output with no enclosing parens
|
is_msg = 0;
|
||||||
if (is_msg && is_object_type(car(err)) && type_of(car(err)) == string_tag) {
|
Cyc_display(data, car(err), stderr);
|
||||||
is_msg = 0;
|
if (cdr(err)) {
|
||||||
Cyc_display(data, car(err), stderr);
|
fprintf(stderr, ": ");
|
||||||
if (cdr(err)) {
|
|
||||||
fprintf(stderr, ": ");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Cyc_write(data, car(err), stderr);
|
|
||||||
fprintf(stderr, " ");
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Cyc_write(data, car(err), stderr);
|
||||||
|
fprintf(stderr, " ");
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
fprintf(stderr, "Error: ");
|
|
||||||
Cyc_display(data, cdr(err), stderr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5371,7 +5360,7 @@ void _Cyc_91end_91thread_67(void *data, object clo, int argc, object * args)
|
||||||
vector_type *v = d->scm_thread_obj;
|
vector_type *v = d->scm_thread_obj;
|
||||||
v->elements[7] = args[0]; // Store thread result
|
v->elements[7] = args[0]; // Store thread result
|
||||||
|
|
||||||
Cyc_end_thread(d);
|
Cyc_end_thread((gc_thread_data *) data);
|
||||||
object cont = args[0];
|
object cont = args[0];
|
||||||
return_closcall1(data, cont, boolean_f);
|
return_closcall1(data, cont, boolean_f);
|
||||||
}
|
}
|
||||||
|
@ -6423,16 +6412,15 @@ int gc_minor(void *data, object low_limit, object high_limit, closure cont,
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cont != NULL) {
|
gc_move2heap(cont);
|
||||||
gc_move2heap(cont);
|
((gc_thread_data *) data)->gc_cont = cont;
|
||||||
((gc_thread_data *) data)->gc_cont = cont;
|
((gc_thread_data *) data)->gc_num_args = num_args;
|
||||||
((gc_thread_data *) data)->gc_num_args = num_args;
|
|
||||||
|
|
||||||
for (i = 0; i < num_args; i++) {
|
for (i = 0; i < num_args; i++) {
|
||||||
gc_move2heap(args[i]);
|
gc_move2heap(args[i]);
|
||||||
((gc_thread_data *) data)->gc_args[i] = args[i];
|
((gc_thread_data *) data)->gc_args[i] = args[i];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transport exception stack
|
// Transport exception stack
|
||||||
gc_move2heap(((gc_thread_data *) data)->exception_handler_stack);
|
gc_move2heap(((gc_thread_data *) data)->exception_handler_stack);
|
||||||
gc_move2heap(((gc_thread_data *) data)->param_objs);
|
gc_move2heap(((gc_thread_data *) data)->param_objs);
|
||||||
|
@ -6569,13 +6557,8 @@ void GC(void *data, closure cont, object * args, int num_args)
|
||||||
#ifdef CYC_HIGH_RES_TIMERS
|
#ifdef CYC_HIGH_RES_TIMERS
|
||||||
hrt_log_delta("minor gc", tstamp);
|
hrt_log_delta("minor gc", tstamp);
|
||||||
#endif
|
#endif
|
||||||
// if this thread has a continuation (i.e. it is not cancelled)
|
// Let it all go, Neo...
|
||||||
// then we can continue after the minor GC, otherwise we return
|
longjmp(*(((gc_thread_data *) data)->jmp_start), 1);
|
||||||
// to the destructor which initiated the minor GC.
|
|
||||||
if (cont != NULL) {
|
|
||||||
// Let it all go, Neo...
|
|
||||||
longjmp(*(((gc_thread_data *) data)->jmp_start), 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6615,8 +6598,9 @@ void Cyc_make_shared_object(void *data, object k, object obj)
|
||||||
case port_tag:
|
case port_tag:
|
||||||
case c_opaque_tag:
|
case c_opaque_tag:
|
||||||
case complex_num_tag:{
|
case complex_num_tag:{
|
||||||
object hp = gc_alloc(heap, gc_allocated_bytes(obj, NULL, NULL), obj, thd,
|
object hp =
|
||||||
heap_grown);
|
gc_alloc(heap, gc_allocated_bytes(obj, NULL, NULL), obj, thd,
|
||||||
|
heap_grown);
|
||||||
return_closcall1(data, k, hp);
|
return_closcall1(data, k, hp);
|
||||||
}
|
}
|
||||||
// Objs w/children force minor GC to guarantee everything is relocated:
|
// Objs w/children force minor GC to guarantee everything is relocated:
|
||||||
|
@ -6801,8 +6785,7 @@ static primitive_type Cyc_91installation_91dir_primitive =
|
||||||
{ {0}, primitive_tag, &_Cyc_91installation_91dir, "Cyc-installation-dir" };
|
{ {0}, primitive_tag, &_Cyc_91installation_91dir, "Cyc-installation-dir" };
|
||||||
static primitive_type Cyc_91compilation_91environment_primitive =
|
static primitive_type Cyc_91compilation_91environment_primitive =
|
||||||
{ {0}, primitive_tag, &_Cyc_91compilation_91environment,
|
{ {0}, primitive_tag, &_Cyc_91compilation_91environment,
|
||||||
"Cyc-compilation-environment"
|
"Cyc-compilation-environment" };
|
||||||
};
|
|
||||||
static primitive_type command_91line_91arguments_primitive =
|
static primitive_type command_91line_91arguments_primitive =
|
||||||
{ {0}, primitive_tag, &_command_91line_91arguments, "command-line-arguments"
|
{ {0}, primitive_tag, &_command_91line_91arguments, "command-line-arguments"
|
||||||
};
|
};
|
||||||
|
@ -6883,12 +6866,10 @@ static primitive_type open_91output_91file_primitive =
|
||||||
{ {0}, primitive_tag, &_open_91output_91file, "open-output-file" };
|
{ {0}, primitive_tag, &_open_91output_91file, "open-output-file" };
|
||||||
static primitive_type open_91binary_91input_91file_primitive =
|
static primitive_type open_91binary_91input_91file_primitive =
|
||||||
{ {0}, primitive_tag, &_open_91binary_91input_91file,
|
{ {0}, primitive_tag, &_open_91binary_91input_91file,
|
||||||
"open-binary-input-file"
|
"open-binary-input-file" };
|
||||||
};
|
|
||||||
static primitive_type open_91binary_91output_91file_primitive =
|
static primitive_type open_91binary_91output_91file_primitive =
|
||||||
{ {0}, primitive_tag, &_open_91binary_91output_91file,
|
{ {0}, primitive_tag, &_open_91binary_91output_91file,
|
||||||
"open-binary-output-file"
|
"open-binary-output-file" };
|
||||||
};
|
|
||||||
static primitive_type close_91port_primitive =
|
static primitive_type close_91port_primitive =
|
||||||
{ {0}, primitive_tag, &_close_91port, "close-port" };
|
{ {0}, primitive_tag, &_close_91port, "close-port" };
|
||||||
static primitive_type close_91input_91port_primitive =
|
static primitive_type close_91input_91port_primitive =
|
||||||
|
@ -6897,8 +6878,7 @@ static primitive_type close_91output_91port_primitive =
|
||||||
{ {0}, primitive_tag, &_close_91output_91port, "close-output-port" };
|
{ {0}, primitive_tag, &_close_91output_91port, "close-output-port" };
|
||||||
static primitive_type Cyc_91flush_91output_91port_primitive =
|
static primitive_type Cyc_91flush_91output_91port_primitive =
|
||||||
{ {0}, primitive_tag, &_Cyc_91flush_91output_91port,
|
{ {0}, primitive_tag, &_Cyc_91flush_91output_91port,
|
||||||
"Cyc-flush-output-port"
|
"Cyc-flush-output-port" };
|
||||||
};
|
|
||||||
static primitive_type file_91exists_127_primitive =
|
static primitive_type file_91exists_127_primitive =
|
||||||
{ {0}, primitive_tag, &_file_91exists_127, "file-exists?" };
|
{ {0}, primitive_tag, &_file_91exists_127, "file-exists?" };
|
||||||
static primitive_type delete_91file_primitive =
|
static primitive_type delete_91file_primitive =
|
||||||
|
@ -7145,12 +7125,6 @@ void *Cyc_init_thread(object thread_and_thunk, int argc, object * args)
|
||||||
gc_add_mutator(thd);
|
gc_add_mutator(thd);
|
||||||
ck_pr_cas_int((int *)&(thd->thread_state), CYC_THREAD_STATE_NEW,
|
ck_pr_cas_int((int *)&(thd->thread_state), CYC_THREAD_STATE_NEW,
|
||||||
CYC_THREAD_STATE_RUNNABLE);
|
CYC_THREAD_STATE_RUNNABLE);
|
||||||
if (ck_pr_cas_int(&cyclone_thread_key_create, 1, 0)) {
|
|
||||||
int r = pthread_key_create(&cyclone_thread_key,
|
|
||||||
(void (*)(void *))Cyc_cancel_thread);
|
|
||||||
assert(r == 0);
|
|
||||||
}
|
|
||||||
pthread_setspecific(cyclone_thread_key, thd);
|
|
||||||
Cyc_start_trampoline(thd);
|
Cyc_start_trampoline(thd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -7207,25 +7181,9 @@ void Cyc_exit_thread(void *data, object _, int argc, object * args)
|
||||||
gc_remove_mutator(thd);
|
gc_remove_mutator(thd);
|
||||||
ck_pr_cas_int((int *)&(thd->thread_state), CYC_THREAD_STATE_RUNNABLE,
|
ck_pr_cas_int((int *)&(thd->thread_state), CYC_THREAD_STATE_RUNNABLE,
|
||||||
CYC_THREAD_STATE_TERMINATED);
|
CYC_THREAD_STATE_TERMINATED);
|
||||||
gc_start_major_collection(thd);
|
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Cancel a thread
|
|
||||||
*/
|
|
||||||
static void Cyc_cancel_thread(gc_thread_data * thd)
|
|
||||||
{
|
|
||||||
// do a minor GC without a continuation, so that we return
|
|
||||||
// here without performing a longjmp
|
|
||||||
GC(thd, (closure) NULL, (object *) NULL, 0);
|
|
||||||
if (gc_is_mutator_active(thd)) {
|
|
||||||
gc_remove_mutator(thd);
|
|
||||||
}
|
|
||||||
ck_pr_cas_int((int *)&(thd->thread_state), CYC_THREAD_STATE_RUNNABLE,
|
|
||||||
CYC_THREAD_STATE_TERMINATED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Accept a number of seconds to sleep according to SRFI-18
|
* @brief Accept a number of seconds to sleep according to SRFI-18
|
||||||
*/
|
*/
|
||||||
|
@ -7578,11 +7536,11 @@ static void _read_add_to_tok_buf(port_type * p, char c)
|
||||||
*/
|
*/
|
||||||
static int _read_is_numeric(const char *tok, int len)
|
static int _read_is_numeric(const char *tok, int len)
|
||||||
{
|
{
|
||||||
return (len && ((isdigit(tok[0])) || (((len == 2) && tok[1] == 'i')
|
return (len &&
|
||||||
&& (tok[0] == '-' || tok[0] == '+')) ||
|
((isdigit(tok[0])) ||
|
||||||
((len > 1) && tok[0] == '.' && isdigit(tok[1])) ||
|
((len > 1) && tok[0] == '.' && isdigit(tok[1])) ||
|
||||||
((len > 1) && (tok[1] == '.' || isdigit(tok[1]))
|
((len > 1) && (tok[1] == '.' || isdigit(tok[1]))
|
||||||
&& (tok[0] == '-' || tok[0] == '+'))));
|
&& (tok[0] == '-' || tok[0] == '+'))));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7973,6 +7931,9 @@ static void _read_return_number(void *data, port_type * p, int base, int exact)
|
||||||
*/
|
*/
|
||||||
static void _read_return_complex_number(void *data, port_type * p, int len)
|
static void _read_return_complex_number(void *data, port_type * p, int len)
|
||||||
{
|
{
|
||||||
|
// TODO: return complex num, see _read_return_number for possible template
|
||||||
|
// probably want to have that function extract/identify the real/imaginary components.
|
||||||
|
// can just scan the buffer and read out start/end index of each number.
|
||||||
int i;
|
int i;
|
||||||
make_empty_vector(vec);
|
make_empty_vector(vec);
|
||||||
make_string(str, p->tok_buf);
|
make_string(str, p->tok_buf);
|
||||||
|
@ -8541,32 +8502,32 @@ static const uint8_t utf8d[] = {
|
||||||
// The first part of the table maps bytes to character classes that
|
// The first part of the table maps bytes to character classes that
|
||||||
// to reduce the size of the transition table and create bitmasks.
|
// to reduce the size of the transition table and create bitmasks.
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0,
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||||
9, 9, 9, 9, 9, 9,
|
9, 9, 9, 9, 9, 9,
|
||||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||||
7, 7, 7, 7, 7, 7,
|
7, 7, 7, 7, 7, 7,
|
||||||
8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
2, 2, 2, 2, 2, 2,
|
2, 2, 2, 2, 2, 2,
|
||||||
10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 11, 6, 6, 6, 5, 8, 8, 8, 8,
|
10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 11, 6, 6, 6, 5, 8, 8, 8, 8,
|
||||||
8, 8, 8, 8, 8, 8, 8,
|
8, 8, 8, 8, 8, 8, 8,
|
||||||
|
|
||||||
// The second part is a transition table that maps a combination
|
// The second part is a transition table that maps a combination
|
||||||
// of a state of the automaton and a character class to a state.
|
// of a state of the automaton and a character class to a state.
|
||||||
0, 12, 24, 36, 60, 96, 84, 12, 12, 12, 48, 72, 12, 12, 12, 12, 12, 12, 12, 12,
|
0, 12, 24, 36, 60, 96, 84, 12, 12, 12, 48, 72, 12, 12, 12, 12, 12, 12, 12, 12,
|
||||||
12, 12, 12, 12,
|
12, 12, 12, 12,
|
||||||
12, 0, 12, 12, 12, 12, 12, 0, 12, 0, 12, 12, 12, 24, 12, 12, 12, 12, 12, 24,
|
12, 0, 12, 12, 12, 12, 12, 0, 12, 0, 12, 12, 12, 24, 12, 12, 12, 12, 12, 24,
|
||||||
12, 24, 12, 12,
|
12, 24, 12, 12,
|
||||||
12, 12, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12,
|
12, 12, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12,
|
||||||
12, 12, 24, 12, 12,
|
12, 12, 24, 12, 12,
|
||||||
12, 12, 12, 12, 12, 12, 12, 36, 12, 36, 12, 12, 12, 36, 12, 12, 12, 12, 12,
|
12, 12, 12, 12, 12, 12, 12, 36, 12, 36, 12, 12, 12, 36, 12, 12, 12, 12, 12,
|
||||||
36, 12, 36, 12, 12,
|
36, 12, 36, 12, 12,
|
||||||
12, 36, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
|
12, 36, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8806,7 +8767,7 @@ int num2ratio(double x, double *numerator, double *denominator)
|
||||||
|
|
||||||
double round_to_nearest_even(double x)
|
double round_to_nearest_even(double x)
|
||||||
{
|
{
|
||||||
return x - remainder(x, 1.0);
|
return x-remainder(x,1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -407,7 +407,7 @@
|
||||||
(else (error "cond-expand: bad feature" x)))
|
(else (error "cond-expand: bad feature" x)))
|
||||||
(memq x (features))))
|
(memq x (features))))
|
||||||
(let expand ((ls (cdr expr)))
|
(let expand ((ls (cdr expr)))
|
||||||
(cond ((null? ls) (error "cond-expand: no expansions" expr))
|
(cond ((null? ls)) ; (error "cond-expand: no expansions" expr)
|
||||||
((not (pair? (car ls))) (error "cond-expand: bad clause" (car ls)))
|
((not (pair? (car ls))) (error "cond-expand: bad clause" (car ls)))
|
||||||
((eq? 'else (caar ls)) ;(identifier->symbol (caar ls)))
|
((eq? 'else (caar ls)) ;(identifier->symbol (caar ls)))
|
||||||
(if (pair? (cdr ls))
|
(if (pair? (cdr ls))
|
||||||
|
@ -1251,16 +1251,13 @@
|
||||||
(define error-object-message car)
|
(define error-object-message car)
|
||||||
(define error-object-irritants cdr)
|
(define error-object-irritants cdr)
|
||||||
(define (error msg . args)
|
(define (error msg . args)
|
||||||
(raise-error (cons msg args)))
|
(raise (cons msg args)))
|
||||||
(define (raise obj)
|
(define (raise obj)
|
||||||
((Cyc-current-exception-handler)
|
((Cyc-current-exception-handler)
|
||||||
(cons 'raised obj)))
|
(cons 'raised (if (pair? obj) obj (list obj)))))
|
||||||
(define (raise-continuable obj)
|
(define (raise-continuable obj)
|
||||||
((Cyc-current-exception-handler)
|
((Cyc-current-exception-handler)
|
||||||
(cons 'continuable obj)))
|
(cons 'continuable (if (pair? obj) obj (list obj)))))
|
||||||
(define (raise-error obj)
|
|
||||||
((Cyc-current-exception-handler)
|
|
||||||
(cons 'error obj)))
|
|
||||||
;; A simpler exception handler based on the one from Bigloo:
|
;; A simpler exception handler based on the one from Bigloo:
|
||||||
;; https://www-sop.inria.fr/indes/fp/Bigloo/doc/bigloo-17.html#g20889
|
;; https://www-sop.inria.fr/indes/fp/Bigloo/doc/bigloo-17.html#g20889
|
||||||
;(define (with-handler handler body)
|
;(define (with-handler handler body)
|
||||||
|
@ -1440,10 +1437,10 @@
|
||||||
(error "exact non-negative integer required" k))
|
(error "exact non-negative integer required" k))
|
||||||
(let* ((s (if (bignum? k)
|
(let* ((s (if (bignum? k)
|
||||||
(bignum-sqrt k)
|
(bignum-sqrt k)
|
||||||
(exact (truncate (_sqrt k)))))
|
(exact (truncate (sqrt k)))))
|
||||||
(r (- k (* s s))))
|
(r (- k (* s s))))
|
||||||
(values s r)))
|
(values s r)))
|
||||||
(define-c _sqrt
|
(define-c sqrt
|
||||||
"(void *data, int argc, closure _, object k, object z)"
|
"(void *data, int argc, closure _, object k, object z)"
|
||||||
" return_inexact_double_op(data, k, sqrt, z);"
|
" return_inexact_double_op(data, k, sqrt, z);"
|
||||||
"(void *data, object ptr, object z)"
|
"(void *data, object ptr, object z)"
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
memloc
|
memloc
|
||||||
)
|
)
|
||||||
(begin
|
(begin
|
||||||
(define *version-number* "0.37.0")
|
(define *version-number* "0.36.0")
|
||||||
(define *version-name* "")
|
(define *version-name* "")
|
||||||
(define *version* (string-append *version-number* " " *version-name* ""))
|
(define *version* (string-append *version-number* " " *version-name* ""))
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
@@ @@ Cyclone Scheme->C compiler
|
@@ @@ Cyclone Scheme->C compiler
|
||||||
,@ http://justinethier.github.io/cyclone/
|
,@ http://justinethier.github.io/cyclone/
|
||||||
'@
|
'@
|
||||||
.@ (c) 2014-2025 Justin Ethier
|
.@ (c) 2014-2024 Justin Ethier
|
||||||
@@ #@ Version " *version* "
|
@@ #@ Version " *version* "
|
||||||
`@@@#@@@.
|
`@@@#@@@.
|
||||||
#@@@@@
|
#@@@@@
|
||||||
|
|
|
@ -20,8 +20,7 @@
|
||||||
(srfi 2)
|
(srfi 2)
|
||||||
(srfi 69)
|
(srfi 69)
|
||||||
)
|
)
|
||||||
)
|
))
|
||||||
(else #f))
|
|
||||||
|
|
||||||
;; symbol -> hash-table -> boolean
|
;; symbol -> hash-table -> boolean
|
||||||
;; Is it OK to inline code replacing ref, based on call graph data from lookup table?
|
;; Is it OK to inline code replacing ref, based on call graph data from lookup table?
|
||||||
|
@ -262,5 +261,4 @@
|
||||||
; (ast:ast->pp-sexp
|
; (ast:ast->pp-sexp
|
||||||
; (opt:local-var-reduction (ast:sexp->ast sexp)))
|
; (opt:local-var-reduction (ast:sexp->ast sexp)))
|
||||||
;)
|
;)
|
||||||
)
|
))
|
||||||
(else #f))
|
|
||||||
|
|
|
@ -14,9 +14,7 @@
|
||||||
(scheme cyclone ast)
|
(scheme cyclone ast)
|
||||||
(scheme cyclone primitives)
|
(scheme cyclone primitives)
|
||||||
(scheme cyclone util)
|
(scheme cyclone util)
|
||||||
(scheme cyclone pretty-print)))
|
(scheme cyclone pretty-print))))
|
||||||
(else
|
|
||||||
#f))
|
|
||||||
|
|
||||||
;; Local variable reduction:
|
;; Local variable reduction:
|
||||||
;; Reduce given sexp by replacing certain lambda calls with a let containing
|
;; Reduce given sexp by replacing certain lambda calls with a let containing
|
||||||
|
@ -436,5 +434,4 @@
|
||||||
(ast:ast->pp-sexp
|
(ast:ast->pp-sexp
|
||||||
(opt:local-var-reduction (ast:sexp->ast sexp)))
|
(opt:local-var-reduction (ast:sexp->ast sexp)))
|
||||||
)
|
)
|
||||||
)
|
))
|
||||||
(else #f))
|
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
(scheme cyclone util)
|
(scheme cyclone util)
|
||||||
(scheme cyclone pretty-print)
|
(scheme cyclone pretty-print)
|
||||||
(srfi 2)
|
(srfi 2)
|
||||||
(srfi 69)))
|
(srfi 69)
|
||||||
(else
|
)
|
||||||
#f))
|
))
|
||||||
|
|
||||||
;; Predicate to determine if a function can be memoized
|
;; Predicate to determine if a function can be memoized
|
||||||
;; var - symbol - global name of the function
|
;; var - symbol - global name of the function
|
||||||
|
@ -371,5 +371,4 @@
|
||||||
;; ; (ast:ast->pp-sexp
|
;; ; (ast:ast->pp-sexp
|
||||||
;; ; (opt:local-var-reduction (ast:sexp->ast sexp)))
|
;; ; (opt:local-var-reduction (ast:sexp->ast sexp)))
|
||||||
;; ;)
|
;; ;)
|
||||||
)
|
))
|
||||||
(else #f))
|
|
||||||
|
|
|
@ -1665,7 +1665,7 @@
|
||||||
|
|
||||||
;; Full beta expansion phase, make a pass over all of the program's AST
|
;; Full beta expansion phase, make a pass over all of the program's AST
|
||||||
(define (opt:beta-expand exp)
|
(define (opt:beta-expand exp)
|
||||||
;(trace:info `(opt:beta-expand ,exp)) (flush-output-port)
|
;(write `(DEBUG opt:beta-expand ,exp)) (newline)
|
||||||
(cond
|
(cond
|
||||||
((ast:lambda? exp)
|
((ast:lambda? exp)
|
||||||
(ast:%make-lambda
|
(ast:%make-lambda
|
||||||
|
@ -1694,7 +1694,6 @@
|
||||||
(else exp)))
|
(else exp)))
|
||||||
|
|
||||||
(define (analyze-cps exp)
|
(define (analyze-cps exp)
|
||||||
;(trace:info `(analyze-cps ,exp))
|
|
||||||
(analyze:find-named-lets exp)
|
(analyze:find-named-lets exp)
|
||||||
(analyze:find-direct-recursive-calls exp)
|
(analyze:find-direct-recursive-calls exp)
|
||||||
(analyze:find-recursive-calls exp)
|
(analyze:find-recursive-calls exp)
|
||||||
|
@ -2231,17 +2230,11 @@
|
||||||
(scan (if->then exp) def-sym)
|
(scan (if->then exp) def-sym)
|
||||||
(scan (if->else exp) def-sym))
|
(scan (if->else exp) def-sym))
|
||||||
((app? exp)
|
((app? exp)
|
||||||
;(trace:info `(analyze:find-recursive-calls scan app ,exp))
|
(when (equal? (car exp) def-sym)
|
||||||
(cond
|
(trace:info `("recursive call" ,exp))
|
||||||
((equal? (car exp) def-sym)
|
(with-var! def-sym (lambda (var)
|
||||||
(trace:info `("recursive call" ,exp))
|
(adbv:set-self-rec-call! var #t)))
|
||||||
(with-var! def-sym (lambda (var)
|
))
|
||||||
(adbv:set-self-rec-call! var #t))))
|
|
||||||
(else
|
|
||||||
(for-each
|
|
||||||
(lambda (e)
|
|
||||||
(scan e def-sym))
|
|
||||||
exp))))
|
|
||||||
(else #f)))
|
(else #f)))
|
||||||
|
|
||||||
;; TODO: probably not good enough, what about recursive functions that are not top-level??
|
;; TODO: probably not good enough, what about recursive functions that are not top-level??
|
||||||
|
|
|
@ -14,8 +14,7 @@
|
||||||
(scheme base)
|
(scheme base)
|
||||||
(scheme read)
|
(scheme read)
|
||||||
(scheme cyclone pretty-print)
|
(scheme cyclone pretty-print)
|
||||||
(scheme cyclone util)))
|
(scheme cyclone util))))
|
||||||
(else #f))
|
|
||||||
;;
|
;;
|
||||||
;; TODO: call this from cyclone.scm after it works, probably after "resolve macros"
|
;; TODO: call this from cyclone.scm after it works, probably after "resolve macros"
|
||||||
|
|
||||||
|
@ -60,9 +59,7 @@
|
||||||
(define (search exp vars)
|
(define (search exp vars)
|
||||||
(cond-expand
|
(cond-expand
|
||||||
(program
|
(program
|
||||||
(pretty-print `(search ,exp ,vars))(newline)) ;; Debugging
|
(pretty-print `(search ,exp ,vars))(newline))) ;; Debugging
|
||||||
(else
|
|
||||||
#f))
|
|
||||||
(cond
|
(cond
|
||||||
;((ast:lambda? exp) 'TODO)
|
;((ast:lambda? exp) 'TODO)
|
||||||
((const? exp) #f)
|
((const? exp) #f)
|
||||||
|
@ -114,5 +111,4 @@
|
||||||
;(if 1 2 3 4)
|
;(if 1 2 3 4)
|
||||||
|
|
||||||
(let ((sexp (read-all (open-input-file "validation.scm"))))
|
(let ((sexp (read-all (open-input-file "validation.scm"))))
|
||||||
(validate-keyword-syntax sexp)))
|
(validate-keyword-syntax sexp))))
|
||||||
(else #f))
|
|
||||||
|
|
|
@ -89,26 +89,17 @@
|
||||||
((analyze exp *global-environment* rename-env '()) *global-environment*)
|
((analyze exp *global-environment* rename-env '()) *global-environment*)
|
||||||
((analyze exp (car env) rename-env '()) (car env))))
|
((analyze exp (car env) rename-env '()) (car env))))
|
||||||
|
|
||||||
;; Called from the C runtime to support apply
|
|
||||||
(define (eval-from-c exp . _env)
|
(define (eval-from-c exp . _env)
|
||||||
(let ((env (if (null? _env) *global-environment* (car _env))))
|
(let ((env (if (null? _env) *global-environment* (car _env))))
|
||||||
(eval (wrapc exp) env)))
|
(eval (wrapc exp) env)))
|
||||||
|
|
||||||
;; Helper function for eval-from-c
|
;; Expressions received from C code are already evaluated, but sometimes too much so.
|
||||||
;;
|
;; Try to wrap
|
||||||
;; Expressions received from C code are already evaluated,
|
|
||||||
;; however any quoted expressions will have the quotes
|
|
||||||
;; stripped off. This is a problem for expressions that
|
|
||||||
;; aren't self evaluating - like (1 2) - so we re-quote
|
|
||||||
;; the expressions here so a subsequent eval will work.
|
|
||||||
;;
|
|
||||||
(define (wrapc exp)
|
(define (wrapc exp)
|
||||||
(cond
|
(cond
|
||||||
((application? exp)
|
((application? exp)
|
||||||
(cond
|
(cond
|
||||||
((or (primitive-procedure? (car exp))
|
((compound-procedure? (car exp))
|
||||||
(compound-procedure? (car exp))
|
|
||||||
(procedure? (car exp)))
|
|
||||||
(cons
|
(cons
|
||||||
(car exp)
|
(car exp)
|
||||||
(map
|
(map
|
||||||
|
|
|
@ -69,6 +69,7 @@
|
||||||
(/ (c-log z1) (c-log z2*)))))
|
(/ (c-log z1) (c-log z2*)))))
|
||||||
(define-inexact-op c-log "log" "clog")
|
(define-inexact-op c-log "log" "clog")
|
||||||
(define-inexact-op exp "exp" "cexp")
|
(define-inexact-op exp "exp" "cexp")
|
||||||
|
(define-inexact-op sqrt "sqrt" "csqrt")
|
||||||
(define-inexact-op sin "sin" "csin")
|
(define-inexact-op sin "sin" "csin")
|
||||||
(define-inexact-op cos "cos" "ccos")
|
(define-inexact-op cos "cos" "ccos")
|
||||||
(define-inexact-op tan "tan" "ctan")
|
(define-inexact-op tan "tan" "ctan")
|
||||||
|
@ -92,58 +93,4 @@
|
||||||
(* (if (eqv? y -0.0) -1 1)
|
(* (if (eqv? y -0.0) -1 1)
|
||||||
(if (eqv? x -0.0) 3.141592653589793 x))
|
(if (eqv? x -0.0) 3.141592653589793 x))
|
||||||
(atan1 (/ y x))))))))
|
(atan1 (/ y x))))))))
|
||||||
|
|
||||||
(define-c
|
|
||||||
sqrt
|
|
||||||
"(void *data, int argc, closure _, object k, object z)"
|
|
||||||
" double complex result;
|
|
||||||
Cyc_check_num(data, z);
|
|
||||||
if (obj_is_int(z)) {
|
|
||||||
result = csqrt(obj_obj2int(z));
|
|
||||||
} else if (type_of(z) == integer_tag) {
|
|
||||||
result = csqrt(((integer_type *)z)->value);
|
|
||||||
} else if (type_of(z) == bignum_tag) {
|
|
||||||
result = csqrt(mp_get_double(&bignum_value(z)));
|
|
||||||
} else if (type_of(z) == complex_num_tag) {
|
|
||||||
result = csqrt(complex_num_value(z));
|
|
||||||
} else {
|
|
||||||
result = csqrt(((double_type *)z)->value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cimag(result) == 0.0) {
|
|
||||||
if (obj_is_int(z) && creal(result) == round(creal(result))) {
|
|
||||||
return_closcall1(data, k, obj_int2obj(creal(result)));
|
|
||||||
}
|
|
||||||
make_double(d, creal(result));
|
|
||||||
return_closcall1(data, k, &d);
|
|
||||||
} else {
|
|
||||||
complex_num_type cn;
|
|
||||||
assign_complex_num((&cn), result);
|
|
||||||
return_closcall1(data, k, &cn);
|
|
||||||
} "
|
|
||||||
"(void *data, object ptr, object z)"
|
|
||||||
" double complex result;
|
|
||||||
Cyc_check_num(data, z);
|
|
||||||
if (obj_is_int(z)) {
|
|
||||||
result = csqrt(obj_obj2int(z));
|
|
||||||
} else if (type_of(z) == integer_tag) {
|
|
||||||
result = csqrt(((integer_type *)z)->value);
|
|
||||||
} else if (type_of(z) == bignum_tag) {
|
|
||||||
result = csqrt(mp_get_double(&bignum_value(z)));
|
|
||||||
} else if (type_of(z) == complex_num_tag) {
|
|
||||||
result = csqrt(complex_num_value(z));
|
|
||||||
} else {
|
|
||||||
result = csqrt(((double_type *)z)->value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cimag(result) == 0.0) {
|
|
||||||
if (obj_is_int(z) && creal(result) == round(creal(result))) {
|
|
||||||
return obj_int2obj(creal(result));
|
|
||||||
}
|
|
||||||
assign_double(ptr, creal(result));
|
|
||||||
} else {
|
|
||||||
assign_complex_num(ptr, result);
|
|
||||||
}
|
|
||||||
return ptr;
|
|
||||||
")
|
|
||||||
))
|
))
|
||||||
|
|
|
@ -294,10 +294,7 @@
|
||||||
(substring t 0 end)
|
(substring t 0 end)
|
||||||
(substring t end (- len 1))))
|
(substring t end (- len 1))))
|
||||||
(real (string->number real-str))
|
(real (string->number real-str))
|
||||||
(imag (cond
|
(imag (string->number imag-str))
|
||||||
((equal? "+" imag-str) 1) ;; Special case, +i w/no number
|
|
||||||
((equal? "-" imag-str) -1) ;; Special case, -i
|
|
||||||
(else (string->number imag-str))))
|
|
||||||
)
|
)
|
||||||
(Cyc-make-rect real imag)))
|
(Cyc-make-rect real imag)))
|
||||||
(else
|
(else
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
(define (repl)
|
(define (repl)
|
||||||
(with-handler
|
(with-handler
|
||||||
(lambda (obj)
|
(lambda (obj)
|
||||||
|
(display "Error: ")
|
||||||
(cond
|
(cond
|
||||||
((error-object? obj)
|
((error-object? obj)
|
||||||
(display "Error: ")
|
|
||||||
(display (error-object-message obj))
|
(display (error-object-message obj))
|
||||||
(if (not (null? (error-object-irritants obj)))
|
(if (not (null? (error-object-irritants obj)))
|
||||||
(display ": "))
|
(display ": "))
|
||||||
|
@ -31,8 +31,18 @@
|
||||||
(write o)
|
(write o)
|
||||||
(display " "))
|
(display " "))
|
||||||
(error-object-irritants obj)))
|
(error-object-irritants obj)))
|
||||||
|
((pair? obj)
|
||||||
|
(when (string? (car obj))
|
||||||
|
(display (car obj))
|
||||||
|
(if (not (null? (cdr obj)))
|
||||||
|
(display ": "))
|
||||||
|
(set! obj (cdr obj)))
|
||||||
|
(for-each
|
||||||
|
(lambda (o)
|
||||||
|
(write o)
|
||||||
|
(display " "))
|
||||||
|
obj))
|
||||||
(else
|
(else
|
||||||
(display "Error: ")
|
|
||||||
(display obj)))
|
(display obj)))
|
||||||
(newline)
|
(newline)
|
||||||
(repl))
|
(repl))
|
||||||
|
|
|
@ -388,7 +388,7 @@
|
||||||
#ifdef AI_V4MAPPED
|
#ifdef AI_V4MAPPED
|
||||||
return_closcall1(data, k, obj_int2obj(AI_V4MAPPED));
|
return_closcall1(data, k, obj_int2obj(AI_V4MAPPED));
|
||||||
#else
|
#else
|
||||||
return_closcall1(data, k, obj_int2obj(0));
|
Cyc_rt_raise_msg(data, \"AI_V4MAPPED is not available on this platform\");
|
||||||
#endif
|
#endif
|
||||||
")
|
")
|
||||||
(define *ai-all* (ai-all))
|
(define *ai-all* (ai-all))
|
||||||
|
@ -398,7 +398,7 @@
|
||||||
#ifdef AI_ALL
|
#ifdef AI_ALL
|
||||||
return_closcall1(data, k, obj_int2obj(AI_ALL));
|
return_closcall1(data, k, obj_int2obj(AI_ALL));
|
||||||
#else
|
#else
|
||||||
return_closcall1(data, k, obj_int2obj(0));
|
Cyc_rt_raise_msg(data, \"AI_ALL is not available on this platform\");
|
||||||
#endif
|
#endif
|
||||||
")
|
")
|
||||||
(make-const ai-addrconfig "AI_ADDRCONFIG" )
|
(make-const ai-addrconfig "AI_ADDRCONFIG" )
|
||||||
|
|
45
srfi/18.sld
45
srfi/18.sld
|
@ -74,7 +74,6 @@
|
||||||
;; - internal
|
;; - internal
|
||||||
;; - end of thread cont (or #f for default)
|
;; - end of thread cont (or #f for default)
|
||||||
;; - end-result - Result of thread that terminates successfully
|
;; - end-result - Result of thread that terminates successfully
|
||||||
;; - internal thread context at termination, e.g. parameterised objects
|
|
||||||
(vector
|
(vector
|
||||||
'cyc-thread-obj
|
'cyc-thread-obj
|
||||||
thunk
|
thunk
|
||||||
|
@ -83,7 +82,6 @@
|
||||||
#f
|
#f
|
||||||
#f
|
#f
|
||||||
#f
|
#f
|
||||||
#f
|
|
||||||
#f)))
|
#f)))
|
||||||
|
|
||||||
(define (thread-name t) (vector-ref t 3))
|
(define (thread-name t) (vector-ref t 3))
|
||||||
|
@ -100,7 +98,7 @@
|
||||||
(%get-thread-data))
|
(%get-thread-data))
|
||||||
|
|
||||||
(define *primordial-thread*
|
(define *primordial-thread*
|
||||||
(vector 'cyc-thread-obj #f #f "main thread" #f #f #f #f))
|
(vector 'cyc-thread-obj #f #f "main thread" #f #f))
|
||||||
|
|
||||||
(define-c %current-thread
|
(define-c %current-thread
|
||||||
"(void *data, int argc, closure _, object k)"
|
"(void *data, int argc, closure _, object k)"
|
||||||
|
@ -120,21 +118,13 @@
|
||||||
make_c_opaque(co, td);
|
make_c_opaque(co, td);
|
||||||
return_closcall1(data, k, &co); ")
|
return_closcall1(data, k, &co); ")
|
||||||
|
|
||||||
(define-c %end-thread!
|
|
||||||
"(void *data, int argc, closure _, object k, object ret)"
|
|
||||||
" gc_thread_data *d = data;
|
|
||||||
vector_type *v = d->scm_thread_obj;
|
|
||||||
v->elements[7] = ret; // Store thread result
|
|
||||||
Cyc_end_thread(d);
|
|
||||||
return_closcall1(data, k, boolean_f);")
|
|
||||||
|
|
||||||
(define (thread-start! t)
|
(define (thread-start! t)
|
||||||
;; Initiate a GC prior to running the thread, in case
|
;; Initiate a GC prior to running the thread, in case
|
||||||
;; it contains any closures on the "parent" thread's stack
|
;; it contains any closures on the "parent" thread's stack
|
||||||
(let* ((thunk (vector-ref t 1))
|
(let* ((thunk (vector-ref t 1))
|
||||||
(thread-params (cons t (lambda ()
|
(thread-params (cons t (lambda ()
|
||||||
(vector-set! t 5 #f)
|
(vector-set! t 5 #f)
|
||||||
(let ((r (thunk))) (%end-thread! r))))))
|
(thunk)))))
|
||||||
(vector-set! t 5 (%get-thread-data)) ;; Temporarily make parent thread
|
(vector-set! t 5 (%get-thread-data)) ;; Temporarily make parent thread
|
||||||
;; data available for child init
|
;; data available for child init
|
||||||
(Cyc-minor-gc)
|
(Cyc-minor-gc)
|
||||||
|
@ -142,33 +132,9 @@
|
||||||
t))
|
t))
|
||||||
|
|
||||||
(define (thread-yield!) (thread-sleep! 1))
|
(define (thread-yield!) (thread-sleep! 1))
|
||||||
|
(define-c thread-terminate!
|
||||||
(define-c %thread-terminate!
|
"(void *data, object _, int argc, object *args)"
|
||||||
"(void *data, int argc, closure _, object k, object thread_data_opaque)"
|
" Cyc_end_thread(data); ")
|
||||||
" gc_thread_data *td;
|
|
||||||
if (thread_data_opaque == boolean_f) {
|
|
||||||
/* primordial thread */
|
|
||||||
__halt(boolean_f);
|
|
||||||
} else {
|
|
||||||
td = (gc_thread_data *)(opaque_ptr(thread_data_opaque));
|
|
||||||
if (td == data) {
|
|
||||||
Cyc_end_thread(td);
|
|
||||||
} else {
|
|
||||||
pthread_cancel(td->thread_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return_closcall1(data, k, boolean_t);")
|
|
||||||
(define (thread-terminate! t)
|
|
||||||
(cond
|
|
||||||
((and (thread? t)
|
|
||||||
(or (Cyc-opaque? (vector-ref t 2)) (equal? *primordial-thread* t)))
|
|
||||||
(begin
|
|
||||||
(Cyc-minor-gc)
|
|
||||||
(vector-set! t 5 (%get-thread-data)) ;; remember calling thread
|
|
||||||
(%thread-terminate! (vector-ref t 2))
|
|
||||||
#t))
|
|
||||||
(else
|
|
||||||
#f))) ;; TODO: raise an error instead?
|
|
||||||
|
|
||||||
;; TODO: not good enough, need to return value from thread
|
;; TODO: not good enough, need to return value from thread
|
||||||
;; TODO: perhaps not an ideal solution using a loop/polling below, but good
|
;; TODO: perhaps not an ideal solution using a loop/polling below, but good
|
||||||
|
@ -190,7 +156,6 @@
|
||||||
(cond
|
(cond
|
||||||
((and (thread? t) (Cyc-opaque? (vector-ref t 2)))
|
((and (thread? t) (Cyc-opaque? (vector-ref t 2)))
|
||||||
(%thread-join! (vector-ref t 2))
|
(%thread-join! (vector-ref t 2))
|
||||||
(Cyc-minor-gc)
|
|
||||||
(vector-ref t 7))
|
(vector-ref t 7))
|
||||||
(else
|
(else
|
||||||
#f))) ;; TODO: raise an error instead?
|
#f))) ;; TODO: raise an error instead?
|
||||||
|
|
51
test-lib.c
51
test-lib.c
|
@ -1,51 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include "include/cyclone/types.h"
|
|
||||||
#include "include/cyclone/runtime.h"
|
|
||||||
#include "include/cyclone/runtime-main.h"
|
|
||||||
|
|
||||||
/* Future considerations:
|
|
||||||
int main(int argc, char **argv, char **envp)
|
|
||||||
{gc_thread_data *thd;
|
|
||||||
long stack_size = global_stack_size = STACK_SIZE;
|
|
||||||
long heap_size = global_heap_size = HEAP_SIZE;
|
|
||||||
init_polyfills();
|
|
||||||
mclosure0(clos_halt,&Cyc_halt); // Halt if final closure is reached
|
|
||||||
mclosure0(entry_pt,&c_entry_pt); // First function to execute
|
|
||||||
_cyc_argc = argc;
|
|
||||||
_cyc_argv = argv;
|
|
||||||
set_env_variables(envp);
|
|
||||||
gc_initialize();
|
|
||||||
thd = malloc(sizeof(gc_thread_data));
|
|
||||||
gc_thread_data_init(thd, 0, (char *) &stack_size, stack_size);
|
|
||||||
thd->gc_cont = &entry_pt;
|
|
||||||
thd->gc_args[0] = &clos_halt;
|
|
||||||
thd->gc_num_args = 1;
|
|
||||||
thd->thread_id = pthread_self();
|
|
||||||
gc_add_mutator(thd);
|
|
||||||
Cyc_heap_init(heap_size);
|
|
||||||
thd->thread_state = CYC_THREAD_STATE_RUNNABLE;
|
|
||||||
Cyc_start_trampoline(thd);
|
|
||||||
return 0;}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void test_exact() {
|
|
||||||
common_type ptr;
|
|
||||||
make_double(d, 42.5);
|
|
||||||
assert(obj_int2obj(42) == Cyc_exact_no_cps(NULL, &ptr, obj_int2obj(42)));
|
|
||||||
object result = Cyc_exact_no_cps(NULL, &ptr, &d);
|
|
||||||
assert( result == obj_int2obj(43));
|
|
||||||
|
|
||||||
// TODO: unit tests for below as examples:
|
|
||||||
//void Cyc_exact(void *data, object cont, object z)
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
assert(boolean_t == boolean_t);
|
|
||||||
assert(boolean_t != boolean_f);
|
|
||||||
|
|
||||||
test_exact();
|
|
||||||
|
|
||||||
printf("All tests passed successfully!\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -9,9 +9,6 @@
|
||||||
|
|
||||||
(import
|
(import
|
||||||
(scheme base)
|
(scheme base)
|
||||||
(scheme eval)
|
|
||||||
(scheme inexact)
|
|
||||||
(scheme write)
|
|
||||||
(cyclone test))
|
(cyclone test))
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,12 +30,6 @@
|
||||||
(test '() (make-list -2))
|
(test '() (make-list -2))
|
||||||
)
|
)
|
||||||
|
|
||||||
(test-group
|
|
||||||
"apply"
|
|
||||||
(test '(5 1 2) (eval '(apply cons '(5 (1 2)))))
|
|
||||||
(test '(5 1 2) (apply cons '(5 (1 2))))
|
|
||||||
)
|
|
||||||
|
|
||||||
(cond-expand
|
(cond-expand
|
||||||
(memory streams
|
(memory streams
|
||||||
(test-group
|
(test-group
|
||||||
|
@ -55,7 +46,6 @@
|
||||||
(test "o" (read-line p))
|
(test "o" (read-line p))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(else #f)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
(test-group
|
(test-group
|
||||||
|
@ -112,18 +102,6 @@
|
||||||
(test 2.0 (denominator (inexact (/ 6 4))))
|
(test 2.0 (denominator (inexact (/ 6 4))))
|
||||||
)
|
)
|
||||||
|
|
||||||
(test-group
|
|
||||||
"sqrt"
|
|
||||||
(test 1i (sqrt -1))
|
|
||||||
(test 1i (sqrt -1.0))
|
|
||||||
(test +i (sqrt -1.0))
|
|
||||||
(test 2 (sqrt 4))
|
|
||||||
(test 2.0 (sqrt 4.0))
|
|
||||||
(test 2i (sqrt -4.0))
|
|
||||||
(test #t (complex? (sqrt -1)))
|
|
||||||
(test #t (complex? (sqrt -i)))
|
|
||||||
)
|
|
||||||
|
|
||||||
(test-group
|
(test-group
|
||||||
"exact"
|
"exact"
|
||||||
(test -1 (exact -1))
|
(test -1 (exact -1))
|
||||||
|
@ -173,45 +151,5 @@
|
||||||
(test #f (memq 0.0 (list m)))
|
(test #f (memq 0.0 (list m)))
|
||||||
)
|
)
|
||||||
|
|
||||||
(test-group
|
|
||||||
"exception handling"
|
|
||||||
(define (capture-output thunk)
|
|
||||||
(let ((output-string (open-output-string)))
|
|
||||||
(parameterize ((current-output-port output-string))
|
|
||||||
(thunk))
|
|
||||||
(let ((result (get-output-string output-string)))
|
|
||||||
(close-output-port output-string)
|
|
||||||
result)))
|
|
||||||
(test
|
|
||||||
"should be a number65"
|
|
||||||
(capture-output
|
|
||||||
(lambda ()
|
|
||||||
(with-exception-handler
|
|
||||||
(lambda (con)
|
|
||||||
(cond
|
|
||||||
((string? con)
|
|
||||||
(display con))
|
|
||||||
(else
|
|
||||||
(display "a warning has been issued")))
|
|
||||||
42)
|
|
||||||
(lambda ()
|
|
||||||
(display
|
|
||||||
(+ (raise-continuable "should be a number")
|
|
||||||
23)))))))
|
|
||||||
(test
|
|
||||||
"condition: an-error"
|
|
||||||
(capture-output
|
|
||||||
(lambda ()
|
|
||||||
(call-with-current-continuation
|
|
||||||
(lambda (k)
|
|
||||||
(with-exception-handler
|
|
||||||
(lambda (x)
|
|
||||||
(display "condition: ")
|
|
||||||
(write x)
|
|
||||||
(k "exception"))
|
|
||||||
(lambda ()
|
|
||||||
(+ 1 (raise 'an-error)))))))))
|
|
||||||
)
|
|
||||||
|
|
||||||
(test-exit)
|
(test-exit)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue