【问题标题】:Compiled dynamic language编译动态语言
【发布时间】:2009-11-03 21:05:33
【问题描述】:

我搜索存在编译器并支持自修改代码的编程语言。我听说 Lisp 支持这些功能,但我想知道是否有更多具有这些功能的 C/C++/D-Like 语言。

澄清我的意思:

我希望能够以某种方式在运行时访问程序代码并对其应用任何类型的更改,即删除命令、添加命令、更改它们。 好像我有我的程序的 AstTree。当然,我不能在编译语言中拥有那棵树,所以它必须做得不同。编译需要将自修改命令转换为二进制等效修改,以便它们可以在运行时与编译后的代码一起工作。

我不想依赖虚拟机,这就是我编译的意思:)

【问题讨论】:

  • “自修改代码”是什么意思,“动态”是什么意思?这两者通常不被视为同义词。如果您能说明您想要什么,我们可能会为您提供更好的帮助。
  • 是的,我之前看过 wiki 页面,但我希望其他语言,更像 c/c++。
  • 用例是什么?为什么你希望能够在运行时编译代码?您是否尝试过简单地调用 gcc 或其他编译器并将代码加载为动态库?
  • 没有我需要这个的单一用例。我更愿意使用这样的语言,玩弄它。一个可能的美国案例可能是 AI 编程和优化,但对我来说,这只是我真正想接触的东西

标签: reflection programming-languages lisp compiled self-modifying


【解决方案1】:

Lisp 之所以如此,或许是有原因的? Lisp 旨在编程其他语言并使用代码和数据的符号表示进行计算。代码和数据之间的界限不再存在。这会影响编程语言的设计和实现。

Lisp 具有生成新代码、翻译该代码并执行它的语法特性。因此,预解析代码也使用与其他程序相同的数据结构(符号、列表、数字、字符……)。

Lisp 在运行时知道它的数据——你可以查询它的类型或类的所有东西。类本身就是对象,函数也是。所以编程语言和程序的这些元素也是一流的对象,它们可以这样操作。 动态语言与“动态类型”无关。

“动态语言”是指编程语言的元素(例如通过元类和元对象协议)和程序(它的类、函数、方法、槽、继承......)可以在运行时查看,也可以在运行时修改。

可能你添加到一种语言中的这些功能越多,它就越像 Lisp。因为 Lisp 几乎是一种简单、动态、可编程的编程语言的局部最大值。如果您想要其中的一些特性,那么您可能想考虑您必须放弃或愿意放弃的其他程序语言的哪些特性。例如,对于简单的代码即数据语言,整个 C 语法模型可能并不实用。

因此,类 C 和“动态语言”可能不太适合 - 语法是整个画面的一部分。但即使是 C 语法模型也限制了我们使用动态语言的难易程度。

【讨论】:

  • 感谢您的详细回答。我已经知道其中的某些部分,但我仍然想知道是否可以使用更像 c 的方式以及是否有人这样做。我想我会更彻底地了解 lisp。
【解决方案2】:

C# 一直允许自修改代码。

  • C# 1 允许您在本质上动态创建和编译代码。
  • C# 3 添加了“表达式树”,它提供了一种使用对象模型和抽象语法树动态生成代码的有限方法。
  • C# 4 在此基础上加入了对“动态语言运行时”的支持。这可能与您在 .NET 平台上以编译语言获得类似 LISP 的功能一样接近。

【讨论】:

  • 但它不是本地编译的(在 clr 内运行)。 OP 对此并不清楚。
  • 这不一定是真的。 C# 在某些平台(例如 iPhone 和 XBox 360)上确实可以编译为本机代码。但是,您不能在这些平台上使用 Reflection.Emit。
【解决方案3】:

您可能需要考虑将 C++ 与 LLVM 一起用于(大部分)可移植代码生成。你甚至可以拉入clang 以在 C 解析树中工作(请注意,clang 目前对 C++ 的支持不完整,但它是用 C++ 本身编写的)

例如,您可以在 C++ 中编写一个自修改内核来与 clang 和 LLVM 进行交互,并在 C 中编写程序的其余部分。将主程序的解析树与自修改代码一起存储,然后对其进行操作在运行时发出叮当声。 Clang 将让您以任何方式直接操作 AST 树,然后将其一直编译为机器代码。

请记住,在编译语言中操作您的 AST 总是意味着在您的程序中包含一个编译器(或解释器)。 LLVM 只是一个简单的选择。

【讨论】:

  • 是的,我读过很多关于 LLVM 的文章。这是一个非常好的项目,但不是我在这个特定问题中所需要的:)
  • 实际上,这听起来正是您所需要的。我已经在我的回答中阐明了它的一种可能用途。
  • 在我脑海中的某个地方,我希望有某种方法可以直接应用此类修改,而无需再次编译它们——直接操作二进制代码。但如果不回到汇编程序,这似乎几乎是不可能的。
  • 直接操作二进制代码将非常痛苦。一方面,你无法从高层次的角度来做到这一点;编译器会混淆执行顺序,将随机变量保存在寄存器中等,因此 asm 和 C 代码之间的联系并不明显。 Linux 内核确实会进行一些自我修补 - 但仅限于非常有限的程度,并且仅限于内联汇编程序段。
【解决方案4】:

JavaScirpt + V8(Chrome JavaScript 编译器)

JavaScript 是

  • 动态
  • 自我修改(自我评估)(嗯,有点,取决于您的定义)
  • 具有类似 C 的语法(同样,在某种程度上,这是您将获得的最好的动态语法)

您现在可以使用 V8 编译它:http://code.google.com/p/v8/

【讨论】:

  • V8 是“及时”编译的,但它仍然在虚拟机中运行,提问者不希望这样。
  • 显然,自评估语言必须在 JIT 编译器或解释器上运行,否则它如何将数据作为代码运行?不存在 100% 预编译的自我评估语言。
【解决方案5】:

“动态语言”是一个涵盖各种概念的广义术语。 C# 4.0 支持动态类型,这是一种编译语言。 Objective-C 还支持动态语言的一些特性。然而,在支持自修改代码方面,它们都没有接近 Lisp。

要支持这种程度的动态性和自修改代码,您应该有一个功能齐全的编译器可以在运行时调用;这几乎就是解释器的真正含义。

【讨论】:

  • 一些 Lisp 实现本身没有解释器,而是通过动态编译来模拟它。我想当你首先获得解析形式的代码时它会有所帮助。
  • 大卫:确实。这就是我从“......你应该有一个全功能的编译器在运行时调用”的意思。解释器无缝地提供了这种功能,而在编译环境中,您基本上应该在运行时编译东西。不过,它不像静态编译的代码。
【解决方案6】:

试试 groovy。它是一种在运行时编译的基于动态 Java-JVM 的语言。它应该能够执行自己的代码。

http://groovy.codehaus.org/

否则,您总是会使用 Perl、PHP 等……但正如您所建议的那样,这些不是 C/C++/D 类语言。

【讨论】:

  • Perl 或 PHP 就足够了 c/c++/d 喜欢,我更想排除诸如 cobol、lisp 之类的东西。但我不想要 JIT,我真的希望它完全编译成独立的可执行文件
  • 在这种情况下,一定要使用 Perl...你永远不会回去。
【解决方案7】:

我不想依赖虚拟机,这就是我编译的意思:)

如果这就是您要寻找的全部内容,我建议您使用 Python 或 Ruby。它们都可以在自己的虚拟机以及 JVM 和 .Net CLR 上运行。因此,您可以选择所需的任何运行时。在这两者中,Ruby 似乎拥有更多的元编程工具,而 Python 似乎在其他平台上有更成熟的实现。

【讨论】:

  • 我的意思是,我不想拥有 any 那种虚拟机。 Ruby,java,所有这些,它都没有编译。我不想要那个
猜你喜欢
  • 2012-09-17
  • 1970-01-01
  • 2010-12-24
  • 1970-01-01
  • 2010-11-18
  • 1970-01-01
  • 2011-03-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多