-
Notifications
You must be signed in to change notification settings - Fork 159
A Walkthrough the Code
This wiki page is a starting point for anyone that is interested in understanding how c2go works internally or are interested in learning the code base to work on issues.
This page is still a work in progress.
The basic process is this:
- The
clang
program preprocesses the C input file and produces a temporary file,/tmp/pp.c
. This file contains a lot more source code because all the of the#include
directives have been evaluated. - The
clang
program is used again to parse thepp.c
file and produce an AST. This is the coloured output you will see below. - The
clang
output (which is text) is converted by theast
package into a real AST. - The
transpiler
package converts the AST into Go's internal AST. - The Go AST is rendered into Go code.
The clang
program parses C and produces text that represents the internal clang AST, here is an example of the output:
This text (once the colours have been removed) is parsed by ast.Parse()
to produce an object that looks similar to:
*ast.FunctionDecl {
Name: "foo"
Type: "void (struct S *)"
Children: []*ast.Node{
*ast.ParmVarDecl{
Used: true
Name: "s"
Type: "struct S *"
}
*ast.CompoundStmt{
Children: []*ast.Node{
*ast.CallExpr{
// ...
}
}
}
}
}
I say similar because there are lots of other attributes extract that are not shown to keep the output short.
Transpiling (an amalgamation of the words, translate and compile) is the process of translating some course code to some other source code. This can be done in all sorts of different ways by we iterate through the AST structure and produce a new Go AST.
The transpiling is done in the transpiler
package. When we pass in the AST in the example above to transpiler.TranspileAST()
it will return a new Go AST that looks similar:
*ast.FuncDecl{
Name: "foo"
Type: *ast.FuncType{
Params: []*goast.Field{
*ast.Field{
Names: []*ast.Ident{"s"}
Type: "struct S *"
}
}
Body: *ast.CompoundStmt{
// ...
}
}
One ambiguous thing is that both packages are called "ast". When using the Go AST it is aliased to "goast".
Here is a short description of where you will find things:
-
ast
contains the code for parsing the clang AST output and building the AST. Each file in the package represents a different AST node and has an associated test file with examples. -
transpiler
contains methods for transpiling theast
nodes into the Go AST. This is where most of the code is currently located. -
noarch
,darwin
andlinux
contains Go implementations of low-level functions for each system. These functions are usually provided by cstdlib.noarch
contains that are required on multiple system or are the same implementation on multiple systems. -
util
contains helper functions and other common utilities that is shared by the other packages.