(Or has this been tried 33 times and always failed?)
(Or has this been tried 33 times and always failed?)
Rust might get compiled down through MIR, down through LLVM IR, down to assembly or wasm... which then might be JIT or AOT (re)compiled into other bytecodes... which might perhaps be decompiled back up to C... and C might be retranslated back to horrific unsafe-spamming Rust by the likes of https://c2rust.com/. We've come full circle!
The main issue is that retranslating high level languages into other high level languages isn't something that there's actually a lot of demand for, especially commercially, especially given the N x M translation matrix going on. So a lot of the projects "stabilize" (get abandoned). And automatically translating between the idioms of those languages gets even nastier in terms of matrix bloat.
Well, you've got stuff like MSIL and JVM bytecodes which are higher level, and preserve more type information, and can be compiled to / decompiled from while still preserving more structure, but they still form competing incompatible ecosystems.
The generated code isn’t particularly readable and it comes with some security issues[2] but the upshot is you have the benefits of a C++ compiler.
[1]https://docs.unity3d.com/530/Documentation/Manual/IL2CPP.htm...
Is there any? I think most modern compiler share the same codegen backend.
You don't get the benefit of the frontend when you transpile.
JIT-focused .NET is one of the ecosystems disparate from AOT-focused LLVM. While there's a bit more cross pollination now, at the time the C# to C++ transpiler was authored, there was much less so. I've taken a stab at porting mono to a new platform at a similar time period - it was rather nontrivial (I ran out of time and thus failed.) Worse still, many of Unity's targets (e.g. iOS, XB1, ...) explicitly ban JIT technology in the name of security, which wasn't something I had to deal with.
A MSIL bytecode -> C++ translator might be pretty quick and dirty... yet effective, gives you AOT compilation, avoids the need to explicitly target every architecture by hand. For all it's faults, it's not too terribly hard to figure out how to compile C++ for a given platform, typically, generally requiring exactly zero reverse engineering.
Obviously not “any” language but it has more compile targets than your average bear.
The closest you get to this sort of thing in practice is something like a parser generator, or an automatic interface generator. ANTLR and Tree-sitter both allow generating parsers in a variety of languages, but their input is basically a description of an AST in a highly specialized and extremely declarative context.
Once you start having actual logic in your code generation, there is very little benefit to codegening to a high-level language instead of going directly to a compiler IR, a bytecode, or assembly directly. The places where you see that happening--JavaScript being the biggest one--is largely limited to where there is no other alternative.
What reason would someone have for doing such a thing?
Technically it'd probably be possible to compile down to Rust. It's gc is essentially wrapping in Rc's. Though not sure it'd bring much vs linking to Nim's C output.
But C compatibility is everywhere. Almost every language has a FFI (foreign function interface) for C code. C interop shows up in every language because at the end of the day every language needs to be able to talk to the operating system. For example, to read and write files your language needs to call functions in libc (or equivalent). And that library is written in C.
So, Nodejs can call C via has native modules & NAPI. Java can call C through JNI. Ruby has the ffi gem. Python, Luajit, Go, C#, ... the list goes on. They all have a mechanism to call C code.
If you're looking for another language that can live alongside your C code, you can choose any.
https://docs.julialang.org/en/v1/manual/calling-c-and-fortra...