Browse Source

compiler: Refactor Compiler.Parse: extract parsePackage

pull/6/head
Ayke van Laethem 7 years ago
parent
commit
9a988dd1d1
  1. 179
      tgo.go

179
tgo.go

@ -209,6 +209,95 @@ func (c *Compiler) Parse(mainPath string, buildTags []string) error {
}
for _, pkg := range packageList {
c.parsePackage(program, pkg)
}
return nil
}
func (c *Compiler) getLLVMType(goType types.Type) (llvm.Type, error) {
fmt.Println(" type:", goType)
switch typ := goType.(type) {
case *types.Array:
elemType, err := c.getLLVMType(typ.Elem())
if err != nil {
return llvm.Type{}, err
}
return llvm.ArrayType(elemType, int(typ.Len())), nil
case *types.Basic:
switch typ.Kind() {
case types.Bool:
return llvm.Int1Type(), nil
case types.Int8, types.Uint8:
return llvm.Int8Type(), nil
case types.Int16, types.Uint16:
return llvm.Int16Type(), nil
case types.Int32, types.Uint32:
return llvm.Int32Type(), nil
case types.Int, types.Uint:
return c.intType, nil
case types.Int64, types.Uint64:
return llvm.Int64Type(), nil
case types.String:
return c.stringType, nil
case types.Uintptr:
return c.uintptrType, nil
case types.UnsafePointer:
return llvm.PointerType(llvm.Int8Type(), 0), nil
default:
return llvm.Type{}, errors.New("todo: unknown basic type: " + fmt.Sprintf("%#v", typ))
}
case *types.Interface:
return c.interfaceType, nil
case *types.Named:
return c.getLLVMType(typ.Underlying())
case *types.Pointer:
ptrTo, err := c.getLLVMType(typ.Elem())
if err != nil {
return llvm.Type{}, err
}
return llvm.PointerType(ptrTo, 0), nil
case *types.Struct:
members := make([]llvm.Type, typ.NumFields())
for i := 0; i < typ.NumFields(); i++ {
member, err := c.getLLVMType(typ.Field(i).Type())
if err != nil {
return llvm.Type{}, err
}
members[i] = member
}
return llvm.StructType(members, false), nil
default:
return llvm.Type{}, errors.New("todo: unknown type: " + fmt.Sprintf("%#v", goType))
}
}
func (c *Compiler) getInterfaceType(typ types.Type) llvm.Value {
if _, ok := c.itfTypeNumbers[typ]; !ok {
num := uint64(len(c.itfTypes))
c.itfTypes = append(c.itfTypes, typ)
c.itfTypeNumbers[typ] = num
}
return llvm.ConstInt(llvm.Int32Type(), c.itfTypeNumbers[typ], false)
}
func (c *Compiler) getFunctionName(fn *ssa.Function) string {
if fn.Signature.Recv() != nil {
// Method on a defined type.
typeName := fn.Params[0].Type().(*types.Named).Obj().Name()
return pkgPrefix(fn.Pkg) + "." + typeName + "." + fn.Name()
} else {
// Bare function.
if strings.HasPrefix(fn.Name(), "_Cfunc_") {
// Name CGo functions directly.
return fn.Name()[len("_Cfunc_"):]
} else {
return pkgPrefix(fn.Pkg) + "." + fn.Name()
}
}
}
func (c *Compiler) parsePackage(program *ssa.Program, pkg *ssa.Package) error {
fmt.Println("package:", pkg.Pkg.Path())
// Make sure we're walking through all members in a constant order every
@ -239,9 +328,12 @@ func (c *Compiler) Parse(mainPath string, buildTags []string) error {
return err
}
frames[member] = frame
if member.Synthetic == "package initializer" {
c.initFuncs = append(c.initFuncs, frame.llvmFn)
}
case *ssa.NamedConst:
// Ignore package-level untyped constants. The SSA form doesn't
// need them.
// Ignore package-level untyped constants. The SSA form doesn't need
// them.
case *ssa.Global:
typ, err := c.getLLVMType(member.Type())
if err != nil {
@ -295,93 +387,10 @@ func (c *Compiler) Parse(mainPath string, buildTags []string) error {
}
}
}
}
return nil
}
func (c *Compiler) getLLVMType(goType types.Type) (llvm.Type, error) {
fmt.Println(" type:", goType)
switch typ := goType.(type) {
case *types.Array:
elemType, err := c.getLLVMType(typ.Elem())
if err != nil {
return llvm.Type{}, err
}
return llvm.ArrayType(elemType, int(typ.Len())), nil
case *types.Basic:
switch typ.Kind() {
case types.Bool:
return llvm.Int1Type(), nil
case types.Int8, types.Uint8:
return llvm.Int8Type(), nil
case types.Int16, types.Uint16:
return llvm.Int16Type(), nil
case types.Int32, types.Uint32:
return llvm.Int32Type(), nil
case types.Int, types.Uint:
return c.intType, nil
case types.Int64, types.Uint64:
return llvm.Int64Type(), nil
case types.String:
return c.stringType, nil
case types.Uintptr:
return c.uintptrType, nil
case types.UnsafePointer:
return llvm.PointerType(llvm.Int8Type(), 0), nil
default:
return llvm.Type{}, errors.New("todo: unknown basic type: " + fmt.Sprintf("%#v", typ))
}
case *types.Interface:
return c.interfaceType, nil
case *types.Named:
return c.getLLVMType(typ.Underlying())
case *types.Pointer:
ptrTo, err := c.getLLVMType(typ.Elem())
if err != nil {
return llvm.Type{}, err
}
return llvm.PointerType(ptrTo, 0), nil
case *types.Struct:
members := make([]llvm.Type, typ.NumFields())
for i := 0; i < typ.NumFields(); i++ {
member, err := c.getLLVMType(typ.Field(i).Type())
if err != nil {
return llvm.Type{}, err
}
members[i] = member
}
return llvm.StructType(members, false), nil
default:
return llvm.Type{}, errors.New("todo: unknown type: " + fmt.Sprintf("%#v", goType))
}
}
func (c *Compiler) getInterfaceType(typ types.Type) llvm.Value {
if _, ok := c.itfTypeNumbers[typ]; !ok {
num := uint64(len(c.itfTypes))
c.itfTypes = append(c.itfTypes, typ)
c.itfTypeNumbers[typ] = num
}
return llvm.ConstInt(llvm.Int32Type(), c.itfTypeNumbers[typ], false)
}
func (c *Compiler) getFunctionName(fn *ssa.Function) string {
if fn.Signature.Recv() != nil {
// Method on a defined type.
typeName := fn.Params[0].Type().(*types.Named).Obj().Name()
return pkgPrefix(fn.Pkg) + "." + typeName + "." + fn.Name()
} else {
// Bare function.
if strings.HasPrefix(fn.Name(), "_Cfunc_") {
// Name CGo functions directly.
return fn.Name()[len("_Cfunc_"):]
} else {
return pkgPrefix(fn.Pkg) + "." + fn.Name()
}
}
}
func (c *Compiler) parseFuncDecl(f *ssa.Function) (*Frame, error) {
f.WriteTo(os.Stdout)
name := c.getFunctionName(f)

Loading…
Cancel
Save