2012-12-04 22 views
5

Chcę rozszerzyć srfi-78 o makro, które testuje wyjątek składni. Chcę coś takiego:Jak wychwycić wyjątek z składni

#! /usr/bin/env scheme-script 
#!r6rs 

(import (rnrs) (srfi :78 lightweight-testing)) 

; the macros I want to test 
(define-syntax some-macros 
    (syntax-rules() 
    [(_) 'ok])) 

; the extension to srfi-78 
(define-syntax check-exception 
    (syntax-rules() 
     ; ... some code ... 
     )) 

; tests 

; prints "correct" or someting like that 
(check (some-macros) => 'ok) 

; should print "correct" (i. e. the test passed) 
(check-exception (some-macros 'arg)) 

; should print "error" 
; (i. e. the exception was not thrown as expected) 
(check-exception (some-macros)) 

Czy to w ogóle możliwe? Jeśli nie, w jaki sposób napiszesz testy dla makr?

Wiem o test-read-eval-string z srfi-64. Akceptuje ciąg znaków, tłumaczy go na formularz i ocenia ten formularz w początkowym środowisku. Chcę makro, które ocenia daną formę w bieżącym środowisku i wyjątków od połowów.

Odpowiedz

3

Jedynym przenośnym sposobem, aby to zrobić, jest wywołanie kodu przez eval i zawinięcie go w osłonę.

Np

(define (safe-eval code env) 
    (guard [e [(syntax-violation? e) (display e)]] 
    (eval code env))) 

Zastosowanie:

> (safe-eval '(let a v) (environment '(rnrs))) 
&who: let 
&message: "invalid syntax" 
&syntax: 
    form: (let a v) 
    subform: #f 
+0

To nie powinno działać dla makr jako ekspansja makra idzie przed oceną 'safe-eval' – amakarov

+0

Hm, to działa. Dziękuję Ci. Postaram się zrozumieć, dlaczego. – amakarov

+1

Należy zauważyć, że kod jest cytowany, więc ekspansja nastąpi tylko w eval. – leppie