⚖️ A tool for transpiling C to Go.
A tool for converting C to Go.
The goals of this project are:
c2gorequires Go 1.9 or newer.
go get -u github.com/elliotchance/c2go
c2go transpile myfile.c
The
c2goprogram processes a single C file and outputs the translated code in Go. Let's use an included example, prime.c:
#includeint 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; } </stdio.h>
c2go transpile prime.c go run prime.go
Enter a number 23 Prime number.
prime.golooks like:
package mainimport "unsafe"
import "github.com/elliotchance/c2go/noarch"
// ... lots of system types in Go removed for brevity.
var stdin *noarch.File var stdout *noarch.File var stderr *noarch.File
func main() { __init() var n int var c int noarch.Printf([]byte("Enter a number\n\x00")) noarch.Scanf([]byte("%d\x00"), (*[1]int)(unsafe.Pointer(&n))[:]) if n == 2 { noarch.Printf([]byte("Prime number.\n\x00")) } else { for c = 2; c <= n-1; func() int { c += 1 return c }() { if n%c == 0 { break } } if c != n { noarch.Printf([]byte("Not prime.\n\x00")) } else { noarch.Printf([]byte("Prime number.\n\x00")) } } return }
func __init() { stdin = noarch.Stdin stdout = noarch.Stdout stderr = noarch.Stderr }
This is the process:
The C code is preprocessed with clang. This generates a larger file (
pp.c), but removes all the platform-specific directives and macros.
pp.cis parsed with the clang AST and dumps it in a colourful text format that looks like this. Apart from just parsing the C and dumping an AST, the AST contains all of the resolved information that a compiler would need (such as data types). 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 in a semi-intelligent way and producing Go. Easy, right!?
By default only unit tests are run with
go test. You can also include the integration tests:
go test -tags=integration ./...
Integration tests in the form of complete C programs that can be found in the tests directory.
Integration tests work like this:
Contributing is done with pull requests. There is no help that is too small! :)
If you're looking for where to start I can suggest finding a simple C program (like the other examples) that does not successfully translate into Go.
Or, if you don't want to do that you can submit it as an issue so that it can be picked up by someone else.