From 850fef98529ffee6908a9f46f0a06e02861afa4b Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Thu, 19 Apr 2018 20:23:48 +0200 Subject: [PATCH] Add builtin len(string) --- src/examples/hello/hello.go | 5 +++++ tgo.go | 19 ++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/examples/hello/hello.go b/src/examples/hello/hello.go index f5d35cc5..ea6d14ac 100644 --- a/src/examples/hello/hello.go +++ b/src/examples/hello/hello.go @@ -18,11 +18,16 @@ func main() { println("3 + 12 =", add(3, 12)) println("fib(11) =", fib(11)) println("sumrange(100) =", sumrange(100)) + println("strlen foo:", strlen("foo")) thing := Thing{"foo"} println("thing:", thing.String()) } +func strlen(s string) int { + return len(s) +} + func calculateAnswer() int { seven := 7 return SIX * seven diff --git a/tgo.go b/tgo.go index 223f58aa..ab14d9e6 100644 --- a/tgo.go +++ b/tgo.go @@ -76,7 +76,7 @@ func NewCompiler(pkgName, triple string) (*Compiler, error) { c.intType = llvm.Int32Type() c.stringLenType = llvm.Int32Type() - // Length-prefixed string. + // Go string: tuple of (len, ptr) c.stringType = llvm.StructType([]llvm.Type{c.stringLenType, llvm.PointerType(llvm.Int8Type(), 0)}, false) printstringType := llvm.FunctionType(llvm.VoidType(), []llvm.Type{c.stringType}, false) @@ -427,6 +427,23 @@ func (c *Compiler) parseBuiltin(frame *Frame, instr *ssa.CallCommon, call *ssa.B c.builder.CreateCall(c.printnlFunc, nil, "") } return llvm.Value{}, nil // print() or println() returns void + case "len": + arg := instr.Args[0] + value, err := c.parseExpr(frame, arg) + if err != nil { + return llvm.Value{}, err + } + switch typ := arg.Type().(type) { + case *types.Basic: + switch typ.Kind() { + case types.String: + return c.builder.CreateExtractValue(value, 0, "len"), nil + default: + return llvm.Value{}, errors.New("todo: len: unknown basic type") + } + default: + return llvm.Value{}, errors.New("todo: len: unknown type") + } default: return llvm.Value{}, errors.New("todo: builtin: " + name) }