Browse Source

Add type methods

pull/6/head
Ayke van Laethem 7 years ago
parent
commit
013b375904
  1. 6
      src/examples/hello/hello.go
  2. 42
      tgo.go

6
src/examples/hello/hello.go

@ -5,6 +5,10 @@ type Thing struct {
name string
}
func (t Thing) String() string {
return t.name
}
const SIX = 6
func main() {
@ -16,7 +20,7 @@ func main() {
println("sumrange(100) =", sumrange(100))
thing := Thing{"foo"}
println("thing:", thing.name)
println("thing:", thing.String())
}
func calculateAnswer() int {

42
tgo.go

@ -174,7 +174,15 @@ func (c *Compiler) Parse(pkgName string) error {
global.SetLinkage(llvm.PrivateLinkage)
}
case *ssa.Type:
// TODO
ms := program.MethodSets.MethodSet(member.Type())
for i := 0; i < ms.Len(); i++ {
fn := program.MethodValue(ms.At(i))
frame, err := c.parseFuncDecl(pkgPrefix, fn)
if err != nil {
return err
}
frames[fn] = frame
}
default:
return errors.New("todo: member: " + fmt.Sprintf("%#v", member))
}
@ -185,7 +193,8 @@ func (c *Compiler) Parse(pkgName string) error {
member := pkg.Members[name]
fmt.Println("member:", member.Token(), member)
if member, ok := member.(*ssa.Function); ok {
switch member := member.(type) {
case *ssa.Function:
if member.Blocks == nil {
continue // external function
}
@ -193,6 +202,15 @@ func (c *Compiler) Parse(pkgName string) error {
if err != nil {
return err
}
case *ssa.Type:
ms := program.MethodSets.MethodSet(member.Type())
for i := 0; i < ms.Len(); i++ {
fn := program.MethodValue(ms.At(i))
err := c.parseFunc(frames[fn], fn)
if err != nil {
return err
}
}
}
}
}
@ -241,15 +259,19 @@ func (c *Compiler) getLLVMType(goType types.Type) (llvm.Type, error) {
}
}
func (c *Compiler) getPackageRelativeName(frame *Frame, name string) string {
if strings.IndexByte(name, '.') == -1 {
name = frame.pkgPrefix + "." + name
func (c *Compiler) getFunctionName(pkgPrefix string, 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 + "." + typeName + "." + fn.Name()
} else {
// Bare function.
return pkgPrefix + "." + fn.Name()
}
return name
}
func (c *Compiler) parseFuncDecl(pkgPrefix string, f *ssa.Function) (*Frame, error) {
name := pkgPrefix + "." + f.Name()
name := c.getFunctionName(pkgPrefix, f)
frame := &Frame{
pkgPrefix: pkgPrefix,
name: name,
@ -413,7 +435,7 @@ func (c *Compiler) parseBuiltin(frame *Frame, instr *ssa.CallCommon, call *ssa.B
func (c *Compiler) parseFunctionCall(frame *Frame, call *ssa.CallCommon, fn *ssa.Function) (llvm.Value, error) {
fmt.Printf(" function: %s\n", fn)
name := c.getPackageRelativeName(frame, fn.Name())
name := c.getFunctionName(frame.pkgPrefix, fn)
target := c.mod.NamedFunction(name)
if target.IsNil() {
return llvm.Value{}, errors.New("undefined function: " + name)
@ -484,7 +506,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
}
return c.builder.CreateGEP(val, indices, ""), nil
case *ssa.Global:
return c.mod.NamedGlobal(c.getPackageRelativeName(frame, expr.Name())), nil
return c.mod.NamedGlobal(expr.Name()), nil
case *ssa.Parameter:
llvmFn := c.mod.NamedFunction(frame.name)
return llvmFn.Param(frame.params[expr]), nil
@ -559,7 +581,7 @@ func (c *Compiler) parseConst(expr *ssa.Const) (llvm.Value, error) {
case constant.String:
str := constant.StringVal(expr.Value)
strLen := llvm.ConstInt(c.stringLenType, uint64(len(str)), false)
strPtr := c.builder.CreateGlobalStringPtr(str, ".str")
strPtr := c.builder.CreateGlobalStringPtr(str, ".str") // TODO: remove \0 at end
strObj := llvm.ConstStruct([]llvm.Value{strLen, strPtr}, false)
return strObj, nil
case constant.Int:

Loading…
Cancel
Save