diff --git a/hello/hello.go b/hello/hello.go index 0b8183f6..f64233f8 100644 --- a/hello/hello.go +++ b/hello/hello.go @@ -3,4 +3,5 @@ package main func main() { println("Hello world from Go!") + println("The answer is:", 42) } diff --git a/runtime/runtime.c b/runtime/runtime.c index f517b904..1d548d40 100644 --- a/runtime/runtime.c +++ b/runtime/runtime.c @@ -4,16 +4,35 @@ #include #include "runtime.h" +#define print(buf, len) write(STDOUT_FILENO, buf, len) + void __go_printstring(string_t *str) { write(STDOUT_FILENO, str->buf, str->len); } +void __go_printint(int32_t n) { + // Print integer in signed big-endian base-10 notation, for humans to + // read. + // TODO: don't recurse, but still be compact (and don't divide/mod + // more than necessary). + if (n < 0) { + print("-", 1); + n = -n; + } + int32_t prevdigits = n / 10; + if (prevdigits != 0) { + __go_printint(prevdigits); + } + char buf[1] = {(n % 10) + '0'}; + print(buf, 1); +} + void __go_printspace() { - write(STDOUT_FILENO, " ", 1); + print(" ", 1); } void __go_printnl() { - write(STDOUT_FILENO, "\n", 1); + print("\n", 1); } void go_main() __asm__("main.main"); diff --git a/tgo.go b/tgo.go index 4755915d..d0821db5 100644 --- a/tgo.go +++ b/tgo.go @@ -30,6 +30,7 @@ type Compiler struct { stringType llvm.Type stringPtrType llvm.Type printstringFunc llvm.Value + printintFunc llvm.Value printspaceFunc llvm.Value printnlFunc llvm.Value } @@ -53,6 +54,8 @@ func NewCompiler(path, triple string) (*Compiler, error) { printstringType := llvm.FunctionType(llvm.VoidType(), []llvm.Type{c.stringPtrType}, false) c.printstringFunc = llvm.AddFunction(c.mod, "__go_printstring", printstringType) + printintType := llvm.FunctionType(llvm.VoidType(), []llvm.Type{llvm.Int32Type()}, false) + c.printintFunc = llvm.AddFunction(c.mod, "__go_printint", printintType) printspaceType := llvm.FunctionType(llvm.VoidType(), nil, false) c.printspaceFunc = llvm.AddFunction(c.mod, "__go_printspace", printspaceType) printnlType := llvm.FunctionType(llvm.VoidType(), nil, false) @@ -179,6 +182,10 @@ func (c *Compiler) parseExpr(expr ast.Expr) error { ptr.SetLinkage(llvm.InternalLinkage) ptrCast := llvm.ConstPointerCast(ptr, c.stringPtrType) c.builder.CreateCall(c.printstringFunc, []llvm.Value{ptrCast}, "") + case token.INT: + n, _ := constant.Int64Val(val) // TODO: do something with the 'exact' return value? + val := llvm.ConstInt(llvm.Int32Type(), uint64(n), true) + c.builder.CreateCall(c.printintFunc, []llvm.Value{val}, "") default: return errors.New("todo: print anything other than strings") }