0

我目前正在尝试为我创建的编程语言创建一个使用 flex、bison 和 llvm (3.2) 的编译器,我希望允许程序员插入 C++ 代码。

例子 :

//some code using my own language
extern
{
    int i = 42;
    // Other code..
    std::cout << "I'm here !" << std::endl;
}
//some other code using my own language

在语法分析之后,我的 AST 中有一个包含 C++ 代码的对象。如何将其插入 IR 代码中?

奖金 :

我也想做类似的事情:

myInt i = 42; // myInt : 64bits
extern
{
    std::cout << i << std::endl;
}

这可能吗 ?

4

2 回答 2

0

您尝试做的事情可能非常复杂,您应该仔细考虑提议的语义。除非您正在生成 C++ 代码,否则还需要编译 C++ 代码块。编译 C++ 块的最简单方法是clang用作库。它可以从 C++ 代码为您生成 LLVM IR。但是要对该 IR 做任何远程有用的事情,它必须与编译器生成的实际 IR 相关联这就是事情可以任意复杂的地方——这一切都取决于更严格定义的语义。

于 2013-05-07T13:42:47.853 回答
0

我看到了两种相对“可行”的方法来实现这一目标:

  1. 预解析您的翻译单元以发出 C/C++ 源代码和您的可编译代码。例如转换这个:

    myInt i = 42; // myInt : 64bits
    extern
    {
        std::cout << i << std::endl;
    }
    

    分成2个文件:

    1. 具有以下功能的 cppsource:

      void ____genfunc1 (int i) {
          std::cout << i << std::endl;
      }
      
    2. 用您的语言编写的“干净”源文件(尽管我猜您也可以直接发出 LLVM IR),措辞如下:

      myInt i = 42; // myInt : 64bits
      ___native_call (____genfunc1, i);
      

    您的“___native_call”函数必须将对象编组到/从 C/C++(并且可能执行其他运行时 mumbo-jumbo - 获取/释放监视器、递增/递减引用计数器/在不同内存空间之间复制值)并调用该函数本身。

    这样,您将获得 2 个传递给链接器以生成可执行文件的对象。请注意,尝试混合不同的语言有无数的陷阱,尤其是当它们代表截然不同的抽象级别时。

  2. 将您的编译器变成将发出 C++ 源文件的预处理器 - 例如将您的语言翻译成 C++。调试信息管理可能会变成地狱,一次 :)

无论哪种方式,这都会很笨拙,并且可能会让最终用户感到困惑。为什么不简单地支持适当的 ABI 并让用户将 C++ 代码保存在 C++ 文件中?

于 2013-05-07T22:22:54.780 回答