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++.
import
is needed.go2cpp
, only the go compiler is needed).g++
with support for C++20 is used for compiling the generated C++ code.clang-format
is 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;
}
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
One goal is that all code in the standard library should transpile correctly to C++20.