[Chicken-hackers] [PATCH] Make quasiquote extensible with custom handlers
Fellow Chickeneers, find attached a patch which allows user code to hook into the quasiquote code expander. "What good can come from that?" you might ask. Let me elaborate! As you know, Chicken supports custom reader extensions via set-read-syntax! and friends. This is all fine unless you try to add custom read syntax for compound data structures. One example of those are SRFI 10 reader constructors which are also supported by core Chicken. Let me give you an example how they work: #;1> (define-record point x y) #;2> (define-reader-ctor 'point make-point) #;3> '#,(point 10 20) # #;4> (point-x #3) 10 #;5> (point-y #3) 20 That's pretty straight forward. Now try this: #;6> `#,(point ,(+ 5 5) 20) # #;7> (point-x #6) (unquote (+ 5 5)) Oops, not quite what we'd expect! Now, this problem was also discovered in 2004 by Bradd W. Szonye (see http://srfi.schemers.org/srfi-10/post-mail-archive/msg0.html), alas it was in the post-finalization phase of SRFI 10 and unfortunatley it doesn't seem like there was much interest in that anymore then. So I went ahead and tried to come up with a solution for that problem. What I think is needed for this to work is to be able to hook into the quasiquote expander (as noted above). The result of that is the attached patch. It allows us to do this: #;8> (define-quasiquote-handler point? (lambda (r walk n p) (list (r 'make-point) (walk (point-x p) n) (walk (point-y p) n #;9> `#,(point ,(+ 5 5) 20) # #;10> (point-x #9) 10 I think this kind of mechanism is something we should have in order to provide proper support for custom read syntax and to make SRFI 10 syntax behave as expected. Let me know if you have any suggestions for improving the API (not sure if quasiquote-handler is the best name for this kind of thing) or implementation (I don't know whether we need to pass the `n' argument to handlers or if we can hide it in a closure, for example). Also I'm not sure about where to put the code (maybe define-quasiquote-handler should not live in expand.scm). Thanks! Moritz >From b4c197c93c94bbfbab781e81a058d5fc3ad90f0a Mon Sep 17 00:00:00 2001 From: Moritz Heidkamp Date: Thu, 21 Feb 2013 18:53:08 +0100 Subject: [PATCH] Make quasiquote extensible with custom handlers This patch introduces the define-quasiquote-handler form which allows hooking into the quasiquote walker, allowing custom reader extensions for compound data literals (such as SRFI 10 reader constructors) to properly support unquoting. --- expand.scm | 29 +++-- tests/reader-tests.scm | 11 +++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/expand.scm b/expand.scm index b278ec0..8677eff 100644 --- a/expand.scm +++ b/expand.scm @@ -35,7 +35,9 @@ macro-alias check-for-multiple-bindings d dd dm dx map-se - lookup check-for-redef) + lookup check-for-redef + quasiquote-handler-ref + quasiquote-handlers) (not inline ##sys#syntax-error-hook ##sys#compiler-syntax-hook ##sys#toplevel-definition-hook)) @@ -1241,6 +1243,26 @@ (car (cdr (cdr b))) ) ) bindings) ) ) ) ) ) ) ) ) + +(define quasiquote-handlers + (list)) + +(define (define-quasiquote-handler pred handler) + (set! quasiquote-handlers +(if handler +(cons (cons pred handler) quasiquote-handlers) +(let loop ((qh quasiquote-handlers)) + (cond ((null? qh) '()) +((eq? (caar qh) pred) (loop (cdr qh))) +(else (cons (car qh) (loop (cdr qh) + +(define (quasiquote-handler-ref x) + (let loop ((qh quasiquote-handlers)) +(and (pair? qh) + (if ((caar qh) x) + (cdar qh) + (loop (cdr qh)) + (##sys#extend-macro-environment 'quasiquote '() @@ -1251,7 +1273,10 @@ (%unquote-splicing (r 'unquote-splicing))) (define (walk x n) (simplify (walk1 x n))) (define (walk1 x n) - (cond ((vector? x) + (cond ((quasiquote-handler-ref x) => + (lambda (handle) + (handle r walk n x))) + ((vector? x) `(##sys#list->vector ,(walk (vector->list x) n)) ) ((not (pair? x)) `(##core#quote ,x)) (else diff --git a/tests/reader-tests.scm b/tests/reader-tests.scm index 894e846..58ad4c5 100644 --- a/tests/reader-tests.scm +++ b/tests/reader-tests.scm @@ -23,3 +23,14 @@ (assert (string=? output "hi\nfoo\nbaz\nbye\n")) (assert (string=? " ." (with-input-from-string "\x20\u0020\U0020\056" read-all))) + + +(define-record foo bar) +(define-reader-ctor 'foo make-foo) +(define-quasiquote-handler foo? + (lambda (rename walk n x) +(list (rename 'make-foo) + (walk (foo-bar x) n + +(assert (= 1 (foo-bar '#,(foo 1 +(assert (= 3 (foo-bar `#,(foo ,(+ 1 2) -- 1.8.1.4 ___ Chicken-hackers mailing list Chicken-hackers@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-hackers
Re: [Chicken-hackers] [PATCH] Make quasiquote extensible with custom handlers
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 02/22/2013 08:02 AM, Moritz Heidkamp wrote: > I think this kind of mechanism is something we should have in order to > provide proper support for custom read syntax and to make SRFI 10 syntax > behave as expected. Let me know if you have any suggestions for > improving the API (not sure if quasiquote-handler is the best name for > this kind of thing) or implementation (I don't know whether we need to > pass the `n' argument to handlers or if we can hide it in a closure, for > example). Also I'm not sure about where to put the code (maybe > define-quasiquote-handler should not live in expand.scm). What might a handler use the `n' argument for? If it's always just plumbed through to walk unchanged, I'd say put it in a closure. If it might be useful to do something with it, leave it exposed. Also: If this gets accepted, I've offered to write an SRFI documenting its final form - it's a natural fit with SRFI-10 or any other reader extension mechanism! > > Thanks! > Moritz > ABS - -- Alaric Snell-Pym http://www.snell-pym.org.uk/alaric/ -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAlEnNTEACgkQRgz/WHNxCGrP3wCcCRyvxYCy4fxEL6MFUO5iUUqJ W4wAnRFkT8zlQSFid1DPdsyQ6i1BPNUH =GQj9 -END PGP SIGNATURE- ___ Chicken-hackers mailing list Chicken-hackers@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-hackers
Re: [Chicken-hackers] software-type and software-version for android
* Moritz Heidkamp [130221 17:49]: > Christian Kellermann writes: > > Probably android for both, since android does not come with all > > posix things. pthreads for example. > > That's not quite true, is it? See > https://android.googlesource.com/platform/prebuilts/ndk/+/master/8/platforms/android-9/arch-arm/usr/include/pthread.h Ah the NDK... > I vote for software-type unix, too, although it is unclear to me what > this actually means :-) POSIX compliance can't be sufficient factor as > Windows has that, too. Unix [tm] can't be as well as that would > disqualify Linux. Ok, instead of doing further guesswork, I checked the source. Well the software type is used to branch off to do system dependend things in csc (generate a manifest for windows), in eval.scm to do the windows dll loading dance. So if you want to support android and will do different things while compiling (providing a correct manifest etc.) having a distinct 'android type still makes more sense to me than declaring it all unix. Android is definitely not unix at all. Cheers, Christian -- In the world, there is nothing more submissive and weak than water. Yet for attacking that which is hard and strong, nothing can surpass it. --- Lao Tzu ___ Chicken-hackers mailing list Chicken-hackers@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-hackers
Re: [Chicken-hackers] [Chicken-users] using types
On Feb 21 2013, Jörg F. Wittenberger wrote: Somehow I can't verify that my type declarations are actually effective. I've been able to verify that my .types files are not ever consulted. Using strace I found that the "foo.types" file is searched for in stat("/usr/lib/chicken/6/foo.types", 0x7fffc1895400) = -1 ENOENT (No such file or directory) But since that's not an extension but just a simple module, which is part of a larger program, there is no good reason to ever install the .types file in the repository. To deal with the issue I tried to use -setup-mode. No effect at all. Further it seem to be the case that CHICKEN_REPOSITORY must be s imple directory and may not be some colon-separated path. At this moment I don't see any solution how to make chicken read the .types files it produced *within* a single directory. How would I do that? Thanks a lot! /Jörg So far I noticed that when I make usage-error wrt. types I - within a single file that is - get an error in tje compilation step.. Which is what I like. Now that I've got a .types file for each module, I tried to enforce this situation by violating the declared procedures signature. But it did *not* give me the expected error. Maybe I'm doing something wrong? So far I'm relying on these lines from "manual/Types": If library code is used with {{require-extension}} or {{(declare (unit ...))}} and a {{.types}} file of the same name exists in the extension repository path, then it is automatically consulted. This allows code using these libraries to take advantage of type-information for library definitions. I have a file foo.types, which declares (: bar (fixnum) -> . *) in foobar.scm I have (declare (unit foobar) (uses foo) ...) but the attempt to provoke an error by calling (bar some-fixnum-which-is-from-working-code-anyway 27) -- which clearly violates the given signature above giving the additional parameter "27" (while the signature in turn was verified to be correct in foo.types) I did *not* result in any warning, let alone the stop-compile-on-error I hoped to receive. I'd like to add that prior to this experiment I went without the (declare ... (uses foo) ...) having only an import statement (import foo) in my foobar.scm - while this would be an analogous use to the declare-variant it would be undocumented AFAI can see. Now I dunno how I can make (sure) use of my type declarations short of manually adding a "-types foo.types" entry for each an every import in the scheme source to my Makefile. Any help much apprecuated. /Jörg ___ Chicken-users mailing list chicken-us...@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-u ___ Chicken-hackers mailing list Chicken-hackers@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-hackers
[Chicken-hackers] [PATCH] Numbered tests
I've assigned a number to each test (sequentially from 101 to 158) and added the TEST variable. In this way you can select a single test to be executed. For example: # make PLATFORM=macosx PREFIX=/tmp/chicken check TEST=102 make -f ./Makefile.macosx CONFIG= check cd tests; sh runtests.sh [102] compiler inlining tests ... ../chicken inlining-tests.scm -output-file a.c -verbose -include-path .. -optimize-level 3 gcc a.c -o a.o -c -no-cpp-precomp -fno-strict-aliasing -fwrapv -fno-common -DHAVE_CHICKEN_CONFIG_H -m64 -DC_ENABLE_PTABLES -Os -fomit-frame-pointer -I.. -I"/tmp/chicken/include/chicken" rm a.c gcc a.o -o a.out -m64 -L.. -L"/tmp/chicken/lib" -lchicken -lm install_name_tool -change libchicken.dylib /tmp/chicken/lib/libchicken.dylib a.out rm a.o done. You can also specify a range. For example: # make PLATFORM=macosx PREFIX=/tmp/chicken check TEST=126-127 make -f ./Makefile.macosx CONFIG= check cd tests; sh runtests.sh [126] syntax tests (loopy-loop) ... (PASS) stepping (PASS) basic in-list (PASS) in-list with result (PASS) in-list with collecting (PASS) uneven length in-list's (PASS) in-lists (PASS) flatten (recursion test) (PASS) in-string (PASS) in-string with start (PASS) in-string with start and end (PASS) in-string with start, end and step (PASS) in-string-reverse (PASS) in-vector (PASS) in-permutations (PASS) in-permutations with length (PASS) in-combinations (PASS) in-hash-table 17 tests completed in 0.703 seconds 17 (100.00%) tests passed 0 (0.00%) tests failed [127] r4rstest ... (expect mult-float-print-test to fail) done. More complex use cases (e.g. TEST=101,126-127) should be possible if needed (not implemented). Just a proof-of-concept as usual. Feel free to improve. Feel free to discard if useless. Regards, Michele 0001-numbered-tests-and-TEST-variable.patch Description: Binary data ___ Chicken-hackers mailing list Chicken-hackers@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-hackers
Re: [Chicken-hackers] software-type and software-version for android
> Android is definitely not unix at all. And anyone producing cross-platform applications is going to greatly appreciate being able to check 'android, 'ios, 'nativeclient, et cetera; rather than check 'unix and then access a secondary egg or their own custom code to differentiate between what are, fundamentally, distinct compilation targets. Thanks, -Dan ___ Chicken-hackers mailing list Chicken-hackers@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-hackers