I've written a sort of DSL on top of Common Lisp. The domain is quite strange and my language looks quite different from Common Lisp itself. I've put all interface into a package foo
:
(defpackage :foo
(:use :common-lisp
:internal-machinery)
(:shadow :in-package
:*packages*))
Switching between packages is beyond of the language concept, so I've disabled this ability by shadowing symbols in-package
and *package*
. Now user (programmer) of my language will be unable to switch packages. Fine.
Obviously, I want to use Common Lisp compiler to compile programs written in this language. Function compile-file
looks OK for me. But there are difficulties.
I want to compile a file as if its contents were inside of my foo
package. Putting (in-package :foo)
on top of every program in my prototypical language is an undesirable option.
To make things even worse, I have to compile a file inside of a function:
(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
I have no idea if it's possible or not, so any help would be appreciated.
How about
(defun compile-stuff (filename)
(let ((*package* (find-package '#:foo)))
(compile-file filename)))
PS. As Rainer mentioned in a comment, if you offer REPL to the user, you are not safe from the user changing the package with (cl:in-package "CL-USER")
.