compilationlisppackagecommon-lispprototyping

Compilation of a file as if its contents were in specified package


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.


Solution

  • 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").