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,,, >> >> >
