我在Common Lisp之上编写了一种DSL。该域非常奇怪,我的语言与Common Lisp本身完全不同。我已将所有界面放入包foo
:
(defpackage :foo
(:use :common-lisp
:internal-machinery)
(:shadow :in-package
:*packages*))
在包之间切换超出了语言概念,因此我通过隐藏符号in-package
和*package*
来禁用此功能。现在我的语言的用户(程序员)将无法切换包。细
显然,我想使用Common Lisp编译器来编译用这种语言编写的程序。函数compile-file
对我来说很合适。但是有困难。
我想编译一个文件,好像它的内容在我的foo
包中。将(in-package :foo)
置于我的原型语言中的每个程序之上是一个不受欢迎的选择。
更糟糕的是,我必须在函数内编译一个文件:
(in-package :internal-machinery)
(defun compile-stuff (filename)
(in-package :foo) ; it will have no effect, because
; this macro must be top level form
(compile-file filename) ; other options are omitted
(in-package :internal-machinery)) ; no way, even if it were top level
; form, in-package is shadowed
我不知道它是否可能,所以任何帮助都会受到赞赏。
答案 0 :(得分:6)
怎么样
(defun compile-stuff (filename)
(let ((*package* (find-package '#:foo)))
(compile-file filename)))
PS。正如Rainer在评论中提到的那样,如果您向用户提供REPL,那么用(cl:in-package "CL-USER")
更改软件包的用户不是安全的。