From b0b5b01fd947d65e6408e7d14e42f6bdb237908b Mon Sep 17 00:00:00 2001 From: Brian Picciano Date: Sun, 21 Aug 2016 12:20:07 -0600 Subject: [PATCH] make Tuple compile to a struct --- expr/build.go | 32 ++++++++++++++++++++++++++++---- expr/expr.go | 5 +++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/expr/build.go b/expr/build.go index e517f19..b6a3887 100644 --- a/expr/build.go +++ b/expr/build.go @@ -87,11 +87,35 @@ func (bctx BuildCtx) buildExprTill(ctx Ctx, e Expr, fn func(e Expr) bool) Expr { case Statement: return bctx.BuildStmt(ctx, ea) case Tuple: + // if the tuple is empty then it is a void + if len(ea) == 0 { + return llvmVal(llvm.Undef(llvm.VoidType())) + } + ea2 := make(Tuple, len(ea)) for i := range ea { ea2[i] = bctx.buildExprTill(ctx, ea[i], fn) } - return ea2 + + // if the fields of the tuple are all llvmVal then we can make a proper + // struct + vals := make([]llvm.Value, len(ea2)) + typs := make([]llvm.Type, len(ea2)) + for i := range ea2 { + if v, ok := ea2[i].(llvmVal); ok { + val := llvm.Value(v) + vals[i] = val + typs[i] = val.Type() + } else { + return ea2 + } + } + + str := llvm.Undef(llvm.StructType(typs, false)) + for i := range vals { + str = bctx.B.CreateInsertValue(str, vals[i], i, "") + } + return llvmVal(str) case List: ea2 := make(Tuple, len(ea)) for i := range ea { @@ -119,9 +143,9 @@ var _ = func() bool { globalCtx = &Ctx{ macros: map[Macro]MacroFn{ "add": func(bctx BuildCtx, ctx Ctx, e Expr) Expr { - tup := bctx.buildExpr(ctx, e).(Tuple) - a := bctx.buildVal(ctx, tup[0]) - b := bctx.buildVal(ctx, tup[1]) + tup := bctx.buildExpr(ctx, e).(llvmVal) + a := bctx.B.CreateExtractValue(llvm.Value(tup), 0, "") + b := bctx.B.CreateExtractValue(llvm.Value(tup), 1, "") return llvmVal(bctx.B.CreateAdd(a, b, "")) }, diff --git a/expr/expr.go b/expr/expr.go index e3d6697..1c61642 100644 --- a/expr/expr.go +++ b/expr/expr.go @@ -141,6 +141,11 @@ func (tup Tuple) equal(e equaler) bool { return ok && exprsEqual(tup, tuptup) } +func isTuple(e Expr) bool { + _, ok := e.(Tuple) + return ok +} + //////////////////////////////////////////////////////////////////////////////// // List represents an ordered set of Exprs, all of the same type. A List's size