gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 08:40:11 24 4
gpt4 key购买 nike

有没有办法实现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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com