compiler-construction - 使用内存数据编译文件而不是 Common Lisp 中的真实文件

标签 compiler-construction common-lisp

有没有办法实现compile-file的效果但不是磁盘上的常规文件,而是流或内存中的字符串? (即,如果我没有文件并且不想使用此内存数据创建临时文件)

编辑

我正在考虑以下用例:从文件系统以外的其他地方加载代码。例如来自存档(类似于 Java 的 jars 或 Python zip 处理功能)或来自网络。也许有其他方法可以解决这个问题,而不仅仅是弯曲 compile-file机械。

最佳答案

Rainer Joswig 的第一条评论指出了这一点:

Not in standard Common Lisp.



您可以在每个实现中搜索来自 compile-file 的调用。查看底层实现是否采用流。

如果您想自己实现这一点,您将实现一个非常低效的 compile-file 版本。用于生成适合 load 的可加载表单的输入和输出流或您自己的版本。

with-compilation-unit 包装编译,您必须特别小心 macroexpand输入顶级表单,请确保 progn表单被视为顶级表单,locally , macroletsymbol-macrolet表单建立绑定(bind)并将其表单处理为具有非空词法环境的顶层(其操作也不可移植),并处理eval-when表格,其中某些表格可能会被评估、处理或两者兼而有之。然后,生成可外部化的表单,关心什么可以合并,什么不能(例如符号和包),调用 make-load-form对于 standard-object , structure-objectcondition实例,并特别注意符号和包,例如检查要编译的流是否具有第一个非原子 in-packageload 的情况下是否能够发出错误信号使用不同的值 *package* 调用.

这只是最小编译的最顶层步骤,或多或少,没有提到编译实际发生的时间(编译时或加载时),load-time-value表格和许多细节。有些步骤需要代码遍历。

我的建议:只需从压缩数据和套接字中提取并保存您拥有的任何源代码,然后调用 compile-file后跟 load , 如果你想保留编译和加载语义。对于更简单的事情,您可以执行以下操作:
(let* ((*package* *package*)
       (*readtable* *readtable*)
       (eof (copy-symbol 'eof))
       (form nil))
  (loop
    (setf form (read stream nil eof))
    (when (eq form eof)
      (return))
    (funcall (compile nil `(lambda () ,form)))))

如果您不太关心可移植性,请让您的实现能够处理压缩文件,例如,向 compile-file 提供解压缩的外部格式。 ,并使您的实现能够打开 URL(URI、IRI,无论您关心什么),而不仅仅是路径名。 AFAIK,ABCL 可以打开 URL 进行输入。然而,compile-file 的输出文件是什么?当使用这样的外部资源调用时?也许自己做compile-and-load这说明了要同时使用的临时文件 compile-fileoutput-file关键参数和 load .

关于compiler-construction - 使用内存数据编译文件而不是 Common Lisp 中的真实文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12204947/

相关文章:

documentation - sbcl:(例如)#'sb-ext:string-to-octets 的附加文档

functional-programming - 在 Common Lisp 中反转多个值的顺序

c++ - 为了确保 C++ 类型是 POD,我必须遵循哪些规则?

common-lisp - 普通 Lisp : Why is cl lnterning symbols to the wrong package when reading from file?

compilation - SBCL 的内联编译和 block 编译有什么区别?

C 编译器使用常量的默认行为

lisp - 我怎样才能定义一个 LISP 函数,它接受一个数组作为参数?

c# - 将 C# 编译为 Native?

Objective-C 属性赋值返回赋值?

c# - C# 编译器如何优化代码片段?