出于好奇,是否有许多编译器有哪些目标.pyc
文件?
经过一番谷歌搜索,我能找到的唯一两个是:
所以……还有吗?
(作为旁注,我之所以考虑这个是因为我想编写一个 Scheme-to-pyc 编译器)
(作为第二个旁注,我并不认为 Scheme-to-pyc 编译器会有用,但它会给我一个令人难以置信的借口来学习 Scheme 和 Python 的一些内部知识)
出于好奇,是否有许多编译器有哪些目标.pyc
文件?
经过一番谷歌搜索,我能找到的唯一两个是:
所以……还有吗?
(作为旁注,我之所以考虑这个是因为我想编写一个 Scheme-to-pyc 编译器)
(作为第二个旁注,我并不认为 Scheme-to-pyc 编译器会有用,但它会给我一个令人难以置信的借口来学习 Scheme 和 Python 的一些内部知识)
“我想写一个 Scheme-to-pyc 编译器”。
我的脑袋疼!你为什么想这么做?Python 字节码是一种中间语言,专为满足 Python 语言的需求而设计,旨在在 Python 虚拟机上运行,这些虚拟机再次针对 Python 的需求进行了定制。目前 Python 开发的一些最重要的领域正在将 Python 迁移到其他“虚拟机”,例如Jython (JVM)、IronPython (.NET)、PyPy和Unladen Swallow项目(将 CPython 迁移到LLVM基于表示)。试图将另一种非常不同的语言(Scheme)的语法和语义压缩到另一种高级语言的中间表示中似乎是在错误的级别上攻击问题(无论问题是什么)。所以,一般来说,似乎不会有很多 .pyc 编译器,这是有充分理由的。
几年前,我编写了一个编译器,它接受一种名为“Noodle”的类 lisp 语言并生成 Python 字节码。虽然它从来没有变得特别有用,但对于更好地理解 Common Lisp(我复制了它的几个特性)和更好地理解 Python 来说,这是一次非常好的学习体验。
我可以想到两种特殊情况,直接针对 Python 字节码而不是生成 Python 并将其传递给 Python 编译器可能有用:
nonlocal
关键字之前)中,如果不借助字节码骇客,就无法修改封闭变量的值。您可以改为改变值,因此通常的做法是让闭包引用一个列表,例如,从内部范围更改其中的第一个元素。这真的很烦人。但是,限制是语法的一部分,而不是 Python VM。我的语言有明确的变量声明,所以它成功地提供了带有可修改封闭值的“正常”闭包。所以,是的,这可能比它的价值多得多,但我喜欢它,你也可能喜欢。
我建议你专注于 CPython。
http://www.network-theory.co.uk/docs/pytut/CompiledPythonfiles.html
我建议你编写一个 Scheme 到 Python 的翻译器,而不是一个 Scheme 到 .pyc 的翻译器,然后让 CPython 处理到 .pyc 的转换。(这样做有先例;第一个 C++ 编译器是Cfront,它将 C++ 翻译成 C,然后让系统 C 编译器完成剩下的工作。)
根据我对 Scheme 的了解,将 Scheme 翻译成 Python 并不难。
一个警告:Python 虚拟机对于 Scheme 来说可能不如 Scheme 本身那么快。例如,Python 不会自动将尾递归转化为迭代;并且 Python 的堆栈相对较浅,因此您实际上需要将尾递归转换为您的翻译器的迭代。
作为奖励,一旦 Unladen Swallow 加速了 Python,你的 Scheme 到 Python 的翻译器将会受益,并且到那时甚至可能变得实用!
如果这对您来说似乎是一个有趣的项目,我说去吧。并非每个项目都必须立即实用。
PS 如果你想要一个更实用的项目,你可能想写一个 AWK 到 Python 的翻译器。这样,使用旧版 AWK 脚本的人就可以轻松地向 Python 迈进!
只是为了您的兴趣,我编写了一个从简单的 LISP 到 Python 的玩具编译器。实际上,这是 pyc 编译器的 LISP。
聚会可能有点晚了,但如果你仍然感兴趣,clojure-py 项目 (https://github.com/halgari/clojure-py) 现在能够将 clojure 的一个重要子集编译为 python 字节码——但是一些帮助总是受欢迎的。
定位字节码本身并不难,除了一件事:它跨平台不稳定(例如,MAKE_FUNCTION 在 Python 3 中从堆栈中弹出 2 个元素,但在 Python 2 中只有 1 个),并且这些差异没有清楚地记录在一个单一的文件中点(afaict)——所以你可能需要一些抽象层。