读取限定符号
Reading qualified symbols
我正在为 Lisp 开发代码格式化程序,它使用 reader 将代码读入 S 表达式格式。
这适用于普通符号。
它对限定符号不太适用。 foo:bar
只有定义了包 foo
才可读,当然对于格式化程序而言,它还没有,因为与编译器不同,格式化程序只是读取代码,而不是执行它。
我怎样才能告诉 reader 继续并即时自动创建一个包 foo
,否则,不要担心,只需阅读 foo:bar
, 本身不是一个符号,但在某种明确的格式下我可以作为一种特殊情况处理?
我认为你不应该为此使用 reader,因为那是有损的(你会丢失注释,以及通过 reader 宏更改的任何内容,例如读取时间值,阅读时间参考等)。
但如果你愿意,你可以自动创建包,也可以通过处理错误导出符号,例如。 G。在 SBCL 上:
(handler-bind ((sb-int:simple-reader-package-error
(lambda (e)
(let ((p (sb-int::package-error-package e)))
(ctypecase p
(string
(make-package p)
(invoke-restart 'retry))
(package
(export (intern (first (simple-condition-format-arguments e)) p) p)
(invoke-restart 'retry)))))))
(with-simple-restart (retry "Retry")
(read-from-string "foo:bar")))
这有点 hacky,我们不能保证条件的格式保持不变。
我正在为 Lisp 开发代码格式化程序,它使用 reader 将代码读入 S 表达式格式。
这适用于普通符号。
它对限定符号不太适用。 foo:bar
只有定义了包 foo
才可读,当然对于格式化程序而言,它还没有,因为与编译器不同,格式化程序只是读取代码,而不是执行它。
我怎样才能告诉 reader 继续并即时自动创建一个包 foo
,否则,不要担心,只需阅读 foo:bar
, 本身不是一个符号,但在某种明确的格式下我可以作为一种特殊情况处理?
我认为你不应该为此使用 reader,因为那是有损的(你会丢失注释,以及通过 reader 宏更改的任何内容,例如读取时间值,阅读时间参考等)。
但如果你愿意,你可以自动创建包,也可以通过处理错误导出符号,例如。 G。在 SBCL 上:
(handler-bind ((sb-int:simple-reader-package-error
(lambda (e)
(let ((p (sb-int::package-error-package e)))
(ctypecase p
(string
(make-package p)
(invoke-restart 'retry))
(package
(export (intern (first (simple-condition-format-arguments e)) p) p)
(invoke-restart 'retry)))))))
(with-simple-restart (retry "Retry")
(read-from-string "foo:bar")))
这有点 hacky,我们不能保证条件的格式保持不变。