我正在尝试使用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;
}
这可能吗?
答案 0 :(得分:0)
您尝试做的事情可能非常复杂,您应该仔细考虑建议的语义。除非您正在生成C ++代码,否则还需要编译C ++代码的块。编译C ++块的最简单方法是使用clang
作为库。它可以从C ++代码为您生成LLVM IR。但要做任何远程有用的IR,它必须与你的编译器生成的实际IR 相关联,这就是事情可以任意复杂的地方 - 这一切都取决于更严格定义的语义。 / p>
答案 1 :(得分:0)
我看到两种相对“可行”的方式来实现这个目标:
预翻译您的翻译单元以发出C / C ++源代码和可编译代码。例如。改变这个:
myInt i = 42; // myInt : 64bits
extern
{
std::cout << i << std::endl;
}
分为2个文件:
具有函数的cppsource:
void ____genfunc1 (int i) {
std::cout << i << std::endl;
}
用你的语言“清理”源文件(虽然我猜你也可以直接发出LLVM IR),其措辞如下:
myInt i = 42; // myInt : 64bits
___native_call (____genfunc1, i);
你的“___native_call”函数必须将对象编组到/从C / C ++编译(并且可能执行其他运行时mumbo-jumbo - 获取/释放监视器,在不同的内存空间之间递增/递减引用计数器/复制值)和调用函数本身。
通过这种方式,您可以获得2个传递给链接器的对象以生成可执行文件。 请注意,尝试混合不同语言存在无数陷阱,特别是如果它们代表截然不同的抽象级别。
将编译器转换为将发出C ++源文件的预处理器 - 例如将您的语言翻译成C ++。调试信息管理可能会成为地狱,一次:)
无论哪种方式,这将是笨重的,并可能使最终用户感到困惑。为什么不简单地支持适当的ABI并让用户将C ++代码保存在C ++文件中?