Compiles Go to native executables via C++20.
One of the goals is for the compiler to be able to compile itself.
The intended use is not to convert entire existing Go programs to C++, but to help port parts of it to C++, or perhaps write programs from scratch and continually check that the program can be converted and compiled as C++.
- Only works with simple code samples, for now.
- Very few functions from the Go standard library are implemented. The ideal would be to be able to compile the official Go standard library.
- A good plan for how to implement
importis needed.
- Pretty fast.
- Simple to use.
- Few dependencies (for compiling
go2cpp, only the go compiler is needed). - Low complexity.
- Short source code.
g++with support for C++20 is used for compiling the generated C++ code.clang-formatis used for formatting the generated C++ code.
go install github.com/xyproto/go2cpp@latest
Then ~/go/bin/go2cpp should be available (unless GOPATH points somewhere else).
Compile to executable:
go2cpp main.go -o main
Output what the intermediate C++20 code looks like:
go2cpp main.go
Go input:
// Multiple return
package main
import (
"fmt"
)
func addsub(x int) (a, b int) {
return x + 2, x - 2
}
func main() {
y, z := addsub(4)
fmt.Println("y =", y)
fmt.Println("z =", z)
}C++ output:
#include <iostream>
#include <tuple>
// Multiple return
auto addsub(int x) -> std::tuple<int, int>
{
return std::tuple<int, int>{ x + 2, x - 2 };
}
auto main() -> int
{
auto [y, z] = addsub(4);
std::cout << "y ="
<< " " << y << std::endl;
std::cout << "z ="
<< " " << z << std::endl;
return 0;
}Go input:
package main
import (
"fmt"
)
func main() {
m := map[string]string{"first": "hi", "second": "you", "third": "there"}
first := true
for k, v := range m {
if first {
first = false
} else {
fmt.Print(" ")
}
fmt.Print(k + v)
}
fmt.Println()
}C++ output:
#include <iostream>
#include <string>
#include <unordered_map>
template <typename T> void _format_output(std::ostream& out, T x)
{
if constexpr (std::is_same<T, bool>::value) {
out << std::boolalpha << x << std::noboolalpha;
} else if constexpr (std::is_integral<T>::value) {
out << static_cast<int>(x);
} else {
out << x;
}
}
auto main() -> int
{
std::unordered_map<std::string, std::string> m{ { "first", "hi" }, { "second", "you" },
{ "third", "there" } };
auto first = true;
for (const auto& [k, v] : m) {
if (first) {
first = false;
} else {
std::cout << " ";
}
_format_output(std::cout, k + v);
}
std::cout << std::endl;
return 0;
}- Version: 0.4.0
- License: MIT
- backtick quoted strings:
`(one level deep only) -
iota
-
break -
case -
chan -
const -
continue -
default -
defer -
else -
fallthrough -
for -
func -
go -
goto -
if -
import(partially) -
interface -
map(needs more testing) -
package(partially) -
range -
return -
select -
struct(needs more testing) -
switch -
type(needs more testing) -
var
-
fmt.Println -
fmt.Print -
fmt.Printf(partially) -
fmt.Sprintf -
strings.Contains -
strings.HasPrefix -
strings.HasSuffix -
strings.Index -
strings.Join -
strings.NewReader -
strings.Replace -
strings.Split -
strings.SplitN -
strings.TrimSpace - All the rest
One goal is that all code in the standard library should transpile correctly to C++20.