A tool for converting C to Go.
I created this project as a proof of concept. It is written in python and uses the python clang bindings to do all of the hard work.
Let's use prime.c:
#include <stdio.h>
int main()
{
int n, c;
printf("Enter a number\n");
scanf("%d", &n);
if ( n == 2 )
printf("Prime number.\n");
else
{
for ( c = 2 ; c <= n - 1 ; c++ )
{
if ( n % c == 0 )
break;
}
if ( c != n )
printf("Not prime.\n");
else
printf("Prime number.\n");
}
return 0;
}
python c2go.py tests/prime.c
package main
import (
"fmt"
)
// ... lots of system types in Go removed for brevity.
func main() {
var n int
var c int
fmt.Printf("Enter a number\n")
fmt.Scanf("%d", &n)
if n == 2 {
fmt.Printf("Prime number.\n")
} else {
for c = 2; c <= n - 1; c += 1 {
if n % c == 0 {
break
}
}
if c != n {
fmt.Printf("Not prime.\n")
} else {
fmt.Printf("Prime number.\n")
}
}
return
}
This is the process:
-
The C code is preprocessed with clang. This generates a larger file, but removes all the platform specific directives and macros.
-
The new file is parsed with the clang AST which has bindings with python. Apart from just parsing the C and exposing an AST, the AST contains all of the resolved information that a compiler would need. This means that the code must compile successfully under clang for the AST to also be usable.
-
Since we have all the types in the AST it's just a matter of traversing the tree is a semi-intelligent way and producing Go.
Testing is done with a set of integrations tests in the form of complete C programs that can be found in the tests directory.
For each of those files:
- Clang compiles the C to a binary as normal.
- c2go converts the C file to Go.
- The Go is built to produce another binary.
- Both binaries are executed and the output is compared. All C files will contain some output.
The test suite is run with run-tests.sh.
As I said it is just a proof of concept (sorry for all the hacky Python).
Contributing is done with pull requests. If you're looking for where to start I can suggesting finding a simple C program (like the other examples) that does not successful translate to Go and fixing up the Python so that it does.