我正在尝试实现参数化错误处理。如果发生错误并且参数 SAFE 为 true,则会引发错误并停止程序。但如果 SAFE 为 false,则会打印警告并继续程序。
#lang racket
(require syntax/parse/define)
;; raises parameterized error message
(define-simple-macro
(err param:id msg)
(if (param)
(error msg)
(display (format "Here be dragons: ~a\n" msg))))
;; a problematic procedure
(define (bad-thing?) (thunk #t))
;; default value of SAFE = #t
(define SAFE (make-parameter #t))
;; prints warning
(parameterize ([SAFE #f])
(when (bad-thing?)
(err SAFE "better watch out.")))
;; raises error
(when (bad-thing?)
(err SAFE "Hell's bells, an exception has occurred!"))
err
宏的问题在于,当引发错误时,它会追溯到定义宏的位置,而不是调用有问题的过程bad-thing?
的位置。
必须有更好的方法!有人能指出我正确的方向吗?
如果您使用基础
syntax-parse
而不是更高级别的包装器来获取表示宏调用站点的语法对象,则可以将 error
包装在 syntax/loc
中以使位置显示如下:
#lang racket
(require (for-syntax syntax/parse))
;; raises parameterized error message
(define-syntax (err stx)
(syntax-parse stx
[(err param:id msg)
#`(if (param)
#,(syntax/loc stx (error msg))
(display (format "Here be dragons: ~a\n" msg)))]))
;; a problematic procedure
(define (bad-thing?) (thunk #t))
;; default value of SAFE = #t
(define SAFE (make-parameter #t))
;; prints warning
(parameterize ([SAFE #f])
(when (bad-thing?)
(err SAFE "better watch out.")))
;; raises error
(when (bad-thing?)
(err SAFE "Hell's bells, an exception has occurred!"))