Ah I think this variation on what I sent below will work!
Instead of (identifier-syntax (raise <>)) I can use
(lambda (o) (syntax-case o () (_ (raise <>))))

There are two minor defects with this whole approach - do you know how
they might be fixed?
1. I'm using make-who-condition instead of my own new condition type
because constructing a condition defined in the test script would be
an out of context error... but it would be better to use a custom
condition so I don't accidentally skip a legitimate who condition.
2. I have to write the (library-being-tested) name twice - once in the
import line of the script and once in the call to environment in
define-missing-exports. Can I have it in only one place?

On Sun, Jun 14, 2009 at 9:50 PM, Ramana Kumar<[email protected]> wrote:
> I thought this code would do what you say is impossible (I do believe
> you, though =P). The problem it runs into is that the call to raise
> (produced by the identifier-syntax) isn't necessarily evaluated first
> in an offending expression. (And if you raise the exception in the
> transformer rather than creating an identifier-syntax, it doesn't get
> caught by the with-exception-handler in test.) There may be bigger
> problems with it, though - if you feel like educating, let me know if
> you see any.
>
> (define-syntax define-missing-exports
>  (lambda (o)
>    (syntax-case o ()
>      ((_ var ...)
>       #`(begin .
>           #,(let rec ((ls #'(var ...)))
>               (cond
>                 ((null? ls) '())
>                 ((call/cc
>                    (lambda (k)
>                      (with-exception-handler
>                        (lambda (x) (k (not (undefined-violation? x))))
>                        (lambda () (eval (syntax->datum (car ls))
> (environment '(library-being-tested)))))))
>                  (rec (cdr ls)))
>                 (else
>                   `(,#`(define-syntax #,(car ls)
>                          (identifier-syntax (raise
> (make-who-condition '#,(car ls)))))
>                     . ,(rec (cdr ls)))))))))))
>
> (define-missing-exports set of all possible exports from the library
> being tested)
>
> (define-syntax test
>  (syntax-rules ()
>    ((_ expr)
>     (call/cc
>       (lambda (k)
>         (with-exception-handler
>           (lambda (x)
>             (if (who-condition? x)
>               (begin
>                 (display (string-append "missing export: "
> (symbol->string (condition-who x))))
>                 (newline)
>                 (k))
>               (raise-continuable x)))
>           (lambda () expr)))))))
>
>
> On Sun, Jun 14, 2009 at 9:25 PM, Abdulaziz Ghuloum<[email protected]> wrote:
>>
>> On Jun 14, 2009, at 2:10 PM, Ramana Kumar wrote:
>>
>>>> So, you have a library that may or may not export a macro, say let^,
>>>> and you have an expression that may or may not reference let^.  If
>>>> the expression references let^, and let^ was not exported, which
>>>> would normally result in a syntax error, you want to defer the error
>>>> until run time instead of being signaled at macro-expansion time.
>>>
>>> I actually don't want the error at all - I want to detect that let^ is
>>> not exported and therefore remove the expression that references it
>>> (or replace it with something). This can happen at macro expansion
>>> time. Still not possible?
>>
>> It's the same thing.  You want to handle the syntax-error exception by
>> replacing the offending expression with another one of your choice.
>> The replacement may be just #f or (asserion-violation 'foo "unbound")
>> or whatever.  Still, not possible to do correctly without hacking on
>> psyntax.
>>
>> Aziz,,,
>>
>>
>

Reply via email to