[Chicken-users] Re: number->string bug
One thing I forgot to mention is that any of the numbers that provide the wrong output in the code below work correctly when evaluating them in isolation, like at the csi prompt. On Tue, Jan 06, 2009 at 09:20:32PM -0600, Kevin Beranek wrote: > I've stumbled upon some interesting behavior of number->string. It > appears that there was previously a ticket filed for a similar bug in > version 2.6 (http://trac.callcc.org/ticket/160). What I've been > observing doesn't seem to be exactly the same but it is perhaps related > because I've only noticed it with base 2 as was the case with the > previous bug. > > Below is a test case followed by some sample output. One interesting > thing to note about the output is that (number->string 99 2) produced > two different values (2 and 75). Also of note is that I've tried > various constructions of the following code with let statements at > different levels, using let vs. set! in different places and different > methods of looping but the bug remains in every combination I've tried. > Behavior is also unchanged between csi and csc. > > Just to be clear about what the code below is intended to do, it is > randomly constructing values in a given range, converting them to a > binary string via number->string, determining if the string is valid by > checking that all characters in the string are either #\0 or #\1 and if > not it prints the offending value along with the generated string. > > CODE: > > (let ((i 0) (val 0) (binary-val 0) (invalid #f) (j 0) (c 0)) > > (do ((i 0 (+ i 1))) ((= i 5000)) > (set! val (random 100)) > (set! binary-val (number->string val 2)) > (set! invalid #f) > > (do ((j 0 (+ j 1))) ((= j (string-length binary-val))) > (set! c (string-ref binary-val j)) > (if (not (or (char=? c #\0) (char=? c #\1))) > (set! invalid #t))) > > (if invalid > (printf "(number->string ~a 2) = ~a\n" val binary-val > > OUTPUT: > > (number->string 99 2) = 2 > (number->string 51 2) = 99 > (number->string 8 2) = 51 > (number->string 30 2) = 8 > (number->string 2 2) = 30 > (number->string 75 2) = 2 > (number->string 99 2) = 75 > > > -- > Kevin Beranek -- Kevin Beranek ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] number->string bug
I've stumbled upon some interesting behavior of number->string. It appears that there was previously a ticket filed for a similar bug in version 2.6 (http://trac.callcc.org/ticket/160). What I've been observing doesn't seem to be exactly the same but it is perhaps related because I've only noticed it with base 2 as was the case with the previous bug. Below is a test case followed by some sample output. One interesting thing to note about the output is that (number->string 99 2) produced two different values (2 and 75). Also of note is that I've tried various constructions of the following code with let statements at different levels, using let vs. set! in different places and different methods of looping but the bug remains in every combination I've tried. Behavior is also unchanged between csi and csc. Just to be clear about what the code below is intended to do, it is randomly constructing values in a given range, converting them to a binary string via number->string, determining if the string is valid by checking that all characters in the string are either #\0 or #\1 and if not it prints the offending value along with the generated string. CODE: (let ((i 0) (val 0) (binary-val 0) (invalid #f) (j 0) (c 0)) (do ((i 0 (+ i 1))) ((= i 5000)) (set! val (random 100)) (set! binary-val (number->string val 2)) (set! invalid #f) (do ((j 0 (+ j 1))) ((= j (string-length binary-val))) (set! c (string-ref binary-val j)) (if (not (or (char=? c #\0) (char=? c #\1))) (set! invalid #t))) (if invalid (printf "(number->string ~a 2) = ~a\n" val binary-val OUTPUT: (number->string 99 2) = 2 (number->string 51 2) = 99 (number->string 8 2) = 51 (number->string 30 2) = 8 (number->string 2 2) = 30 (number->string 75 2) = 2 (number->string 99 2) = 75 -- Kevin Beranek ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] using macros at runtime
im using chicken 3.0.0 . I have a file with some define-macro in it like this: (define-macro (send place . args) (expand-send place args)) I include that file in my main file ChickenBridge.scm (include "mymacros.scm") (declare (unit cm) (run-time-macros) (uses extras ) (usual-integrations) (export ... send )) I csc main main file and build my exictuable csc -c++ -embedded -t ChickenBridge.scm now when i start my executable my functions work but the send maco isnt defined: (send "mp:tuning" 3) Error: unbound variable: send ive also tried (define-for-syntax (send place . args) (expand-send place args)) but that doesnt work either. Im not sure what im doing wrong, im pretty sure I had this working at some point! Any help would be greatly appreciated. I read the faq but i cant get define-syntax to work either. --rick ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] srfi-19 date comparison
Here is a bug report for date comparison. Thank you. $ csi CHICKEN (c)2008 The Chicken Team (c)2000-2007 Felix L. Winkelmann Version 3.4.0 - linux-unix-gnu-x86-64 [ 64bit manyargs dload ptables applyhook ] SVN rev. 11987 compiled 2008-12-02 on chew-z (Linux) #;1> (use srfi-19) ; loading /usr/local/lib/chicken/3/srfi-19.scm ... ; loading /usr/local/lib/chicken/3/srfi-19-core.so ... ; loading /usr/local/lib/chicken/3/numbers-base.so ... ; loading /usr/local/lib/chicken/3/locale.so ... ; loading /usr/local/lib/chicken/3/locale-posix.so ... ; loading /usr/local/lib/chicken/3/locale-categories.so ... ; loading /usr/local/lib/chicken/3/locale-components.so ... ; loading /usr/local/lib/chicken/3/locale-parameters.so ... ; loading /usr/local/lib/chicken/3/srfi-19-io.so ... ; loading /usr/local/lib/chicken/3/srfi-29.so ... ; loading /usr/local/lib/chicken/3/lookup-table.so ... ; loading /usr/local/lib/chicken/3/misc-extn-control-support.so ... ; loading /usr/local/lib/chicken/3/misc-extn-directory.so ... ; loading /usr/local/lib/chicken/3/misc-extn-list-support.so ... ; loading /usr/local/lib/chicken/3/stack-support.so ... ; loading /usr/local/lib/chicken/3/srfi-19-period.so ... #;2> (define (make-date-ymd year month day) (make-date 0 0 0 12 day month year 0)) #;3> (date=? (make-date-ymd 2008 11 24) (make-date-ymd 2008 11 04)) #t #;4> (date -- Anthony Carrico signature.asc Description: OpenPGP digital signature ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] windows shell problem
On Tue, Jan 6, 2009 at 1:09 PM, Matthew Flatt wrote: > > If you put an extra set of quotation marks around the argument, won't > they effectively cancel the quotation marks added by system()? > > That is, pass > > ""c:\home\chicken-trunk\bin\csi" -bnq -e "(require-library setup-api)" > -e "(import setup-api)" "c:\...some...path...\defstruct.setup"" > > to system(), which will then send on > > """c:\home\chicken-trunk\bin\csi" -bnq -e "(require-library setup-api)" > -e "(import setup-api)" "c:\...some...path...\defstruct.setup""" > > to the shell, which will then parse out > > """c:\home\chicken-trunk\bin\csi" = c:\home\chicken-trunk\bin\csi > I don't understand why this works, but when it could, I'll try it. cheers, felix ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] windows shell problem
At Tue, 6 Jan 2009 11:29:24 +0100, "felix winkelmann" wrote: > On Mon, Jan 5, 2009 at 6:58 PM, John Cowan wrote: > > felix winkelmann scripsit: > > > >> The handling of backslashes as escaping characters is not the problem, > >> it seems. If I pass this string (verbatim, just like it is printed here) to > >> system(3): > >> > >> "c:\home\chicken-trunk\bin\csi" -bnq -e "(require-library setup-api)" > >> -e "(import setup-api)" "c:\...some...path...\defstruct.setup" > >> > >> I get an error message that tells me that the program > >> > >> "c:\home\chicken-trunk\bin\csi" -bnq -e "" > > > > That suggests to me is that what's happening is that system(foo) is > > spawning the shell (from $SHELL or $COMSPEC) with "/c \" + foo + "\"". > > If foo already has quotation marks in it, you're hosed. > > That would mean it is impossible to pass arguments containing whitespace. > Can it be that bad? If you put an extra set of quotation marks around the argument, won't they effectively cancel the quotation marks added by system()? That is, pass ""c:\home\chicken-trunk\bin\csi" -bnq -e "(require-library setup-api)" -e "(import setup-api)" "c:\...some...path...\defstruct.setup"" to system(), which will then send on """c:\home\chicken-trunk\bin\csi" -bnq -e "(require-library setup-api)" -e "(import setup-api)" "c:\...some...path...\defstruct.setup""" to the shell, which will then parse out """c:\home\chicken-trunk\bin\csi" = c:\home\chicken-trunk\bin\csi as the program name. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] windows shell problem
On Tue, Jan 6, 2009 at 12:00 AM, Tobia Conforto wrote: > > Have you tried adding an .exe extension to csi? > > Like: "c:\home\chicken-trunk\bin\csi.exe" > > I know it sounds stupid... No, it doesn't. But I'm quite sure John is right with his assumption. > > > You could try and translate the first filename (the csi executable) to a > short name and use single quotes on the rest of the line, assuming the C > library csi is linked to understands single quotes: Does the Windows shell handle single quotes? > > c:\home\chicke~1\bin\csi -bnq -e '(require-library setup-api)' -e '(import > setup-api)' 'c:\...some...path...\defstruct.setup' > > > Anyways, I think you should dump system(3) and just use CreateProcess: > > char *exe = "c:\\home\\chicken-trunk\\bin\\csi.exe"; > char *cmdline = "csi -bnq -e \"(require-library setup-api)\" -e \"(import > setup-api)\" \"c:\\...some...path...\\defstruct.setup\""; > > STARTUPINFO si; > PROCESS_INFORMATION pi; > memset(&si, 0, sizeof(si)); > si.cb = sizeof(si); > > if (! CreateProcess(exe, cmdline, 0,0,0,0,0,0, &si, &pi)) { >printf("Error %d executing:\n%s\n%s\n", GetLastError(), exe, > cmdline); >exit(1); > } > This might be the right solution. I'll try this, or alternatively use get short-path-name trick given by Lars. cheers, felix ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] windows shell problem
On Mon, Jan 5, 2009 at 6:58 PM, John Cowan wrote: > felix winkelmann scripsit: > >> The handling of backslashes as escaping characters is not the problem, >> it seems. If I pass this string (verbatim, just like it is printed here) to >> system(3): >> >> "c:\home\chicken-trunk\bin\csi" -bnq -e "(require-library setup-api)" >> -e "(import setup-api)" "c:\...some...path...\defstruct.setup" >> >> I get an error message that tells me that the program >> >> "c:\home\chicken-trunk\bin\csi" -bnq -e "" > > That suggests to me is that what's happening is that system(foo) is > spawning the shell (from $SHELL or $COMSPEC) with "/c \" + foo + "\"". > If foo already has quotation marks in it, you're hosed. That would mean it is impossible to pass arguments containing whitespace. Can it be that bad? cheers, felix ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] Is there any way programmatically to determine a macro?
On Mon, Jan 5, 2009 at 11:48 PM, Lam Luu wrote: > Hello all! > Given an S-Expression, (here is an example), is there any way to write a > script to determine whether or not that expression is a procedure-call or a > macro? If it is a macro call, is there anyway to expand it back to the > lowest level of special form possible? > Currently, the only way I know if is using expand-syntax procedure, but that > seems to be for interactive use only. You can use `(macro? )' to check whether a symbol is a macro, and run `macroexpand' (or `expand' in chicken 4) repeatedly for s-expressions that have a macro name as first element. Full expansion of arbitrary expressions will need a code-walker, though. cheers, felix ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] newbie: foreign pointers that depend on Scheme objects
On Sat, Dec 20, 2008 at 4:09 PM, Alejandro Forero Cuervo wrote: >> I'm not sure I can follow your example completely (I always get >> quickly confused with these scenarios), but I understand the >> "weak"/"finalizable" GC-root suggestion. I have to think more about >> it, but it should be possible. > > I think this should be implemented: right now it is *impossible* to > store pointers to Scheme-data inside C-data without the potential for > memory leaks. > Attached is a patch against chicken 4 (should work with chicken 3). The new C function "CHICKEN_new_finalizable_gc_root" creates gc roots that can refer to data which is about to be finalized. cheers, felix Index: chicken.h === --- chicken.h (revision 12937) +++ chicken.h (working copy) @@ -549,6 +549,7 @@ { C_word value; struct C_gc_root_struct *next, *prev; + int finalizable; } C_GC_ROOT; typedef struct C_ptable_entry_struct @@ -1161,6 +1162,8 @@ C_fctexport C_word CHICKEN_run(void *toplevel); C_fctexport C_word CHICKEN_continue(C_word k); C_fctexport void *CHICKEN_new_gc_root(); +C_fctexport void *CHICKEN_new_finalizable_gc_root(); +C_fctexport void *CHICKEN_new_gc_root_2(int finalizable); C_fctexport void CHICKEN_delete_gc_root(void *root); C_fctexport void *CHICKEN_global_lookup(char *name); C_fctexport int CHICKEN_is_running(); Index: manual/Embedding === --- manual/Embedding (revision 12936) +++ manual/Embedding (working copy) @@ -279,6 +279,16 @@ an unspecified value. +=== CHICKEN_new_finalizable_gc_root + + [C function] void* CHICKEN_new_finalizable_gc_root () + +Similar to {{CHICKEN_new_gc_root}}, but allows the stored value to +be finalized: if this gc root holds reference to an otherwise +unreferenced data object that has a finalizer, the finalizer is still +invoked. + + === CHICKEN_delete_gc_root [C function] void CHICKEN_delete_gc_root (void *root) Index: tests/runtests.sh === --- tests/runtests.sh (revision 12936) +++ tests/runtests.sh (working copy) @@ -96,6 +96,9 @@ echo " finalizer tests ..." $interpret -s test-finalizers.scm +echo " finalizer tests (2) ..." +$compile test-finalizers-2.scm && ./a.out + echo " locative stress test ..." $compile locative-stress-test.scm && ./a.out Index: tests/test-finalizers-2.scm === --- tests/test-finalizers-2.scm (revision 0) +++ tests/test-finalizers-2.scm (revision 0) @@ -0,0 +1,60 @@ + test-finalizers-2.scm - test finalizers + GC roots + + +(use srfi-1) + +(define *n* 1000) +(define *count* 0) + +#> +static void * +makef(int f, ___scheme_value x) +{ + void *r = f ? CHICKEN_new_finalizable_gc_root() : CHICKEN_new_gc_root(); + + CHICKEN_gc_root_set(r, x); + return r; +} + +static void +freef(void *r) +{ + CHICKEN_delete_gc_root(r); +} +<# + + +(define makef (foreign-lambda c-pointer "makef" bool scheme-object)) +(define freef (foreign-lambda void "freef" c-pointer)) + +(define ((fin f e) x) + (set! *count* (add1 *count*)) + (assert ((if e even? odd?) (car x))) + (when e (freef f))) + +(print "creating gc roots") + +(let* ((x (list-tabulate *n* list)) + (fs (circular-list #t #f)) + (rs (map makef fs x))) + (for-each + (lambda (x f e) + (set-finalizer! x (fin f e))) + x rs fs) + (print "forcing finalizers") + (##sys#force-finalizers) + (assert (zero? *count*)) + (print "dropping data") + (set! x #f) + (print "forcing finalizables") + (##sys#force-finalizers) + (print *count*) + (assert (= (quotient *n* 2) *count*)) + (print "releasing non-finalizable gc roots") + (for-each + (lambda (f e) + (unless e (freef f))) + rs fs) + (print "forcing remaining") + (##sys#force-finalizers) + (assert (= *n* *count*))) Index: runtime.c === --- runtime.c (revision 12937) +++ runtime.c (working copy) @@ -807,7 +807,7 @@ } -void *CHICKEN_new_gc_root() +void *CHICKEN_new_gc_root_2(int finalizable) { C_GC_ROOT *r = (C_GC_ROOT *)C_malloc(sizeof(C_GC_ROOT)); @@ -817,6 +817,7 @@ r->value = C_SCHEME_UNDEFINED; r->next = gc_root_list; r->prev = NULL; + r->finalizable = finalizable; if(gc_root_list != NULL) gc_root_list->prev = r; @@ -825,6 +826,18 @@ } +void *CHICKEN_new_gc_root() +{ + return CHICKEN_new_gc_root_2(0); +} + + +void *CHICKEN_new_finalizable_gc_root() +{ + return CHICKEN_new_gc_root_2(1); +} + + void CHICKEN_delete_gc_root(void *root) { C_GC_ROOT *r = (C_GC_ROOT *)root; @@ -2702,9 +2715,10 @@ for(msp = collectibles; msp < collectibles_top; ++msp) if(*msp != NULL) mark(*msp); -/* mark GC roots: */ -for(gcrp = gc_root_list; gcr