From f5f64782ceaf9b859caad9539f0b00d5fbee7383 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Fri, 20 Apr 2018 14:50:52 +0200 Subject: [PATCH] Add casting between types --- tgo.go | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tgo.go b/tgo.go index faa6215d..45a0f48e 100644 --- a/tgo.go +++ b/tgo.go @@ -539,6 +539,8 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { return c.parseCall(frame, expr) case *ssa.Const: return c.parseConst(expr) + case *ssa.Convert: + return c.parseConvert(frame, expr) case *ssa.Extract: value, err := c.parseExpr(frame, expr.Tuple) if err != nil { @@ -697,6 +699,42 @@ func (c *Compiler) parseConst(expr *ssa.Const) (llvm.Value, error) { } } +func (c *Compiler) parseConvert(frame *Frame, expr *ssa.Convert) (llvm.Value, error) { + value, err := c.parseExpr(frame, expr.X) + if err != nil { + return value, nil + } + + typeFrom, err := c.getLLVMType(expr.X.Type()) + if err != nil { + return llvm.Value{}, err + } + typeTo, err := c.getLLVMType(expr.Type()) + if err != nil { + return llvm.Value{}, err + } + sizeFrom := typeFrom.IntTypeWidth() + sizeTo := typeTo.IntTypeWidth() + + if sizeFrom >= sizeTo { + return c.builder.CreateTruncOrBitCast(value, typeTo, ""), nil + } else { // sizeFrom < sizeTo: extend + switch typ := expr.X.Type().(type) { // typeFrom + case *types.Basic: + if typ.Info() & types.IsInteger == 0 { // if not integer + return llvm.Value{}, errors.New("todo: convert: extend non-integer type") + } + if typ.Info() & types.IsUnsigned != 0 { // if unsigned + return c.builder.CreateZExt(value, typeTo, ""), nil + } else { + return c.builder.CreateSExt(value, typeTo, ""), nil + } + default: + return llvm.Value{}, errors.New("todo: convert: extend non-basic type") + } + } +} + func (c *Compiler) parseUnOp(frame *Frame, unop *ssa.UnOp) (llvm.Value, error) { x, err := c.parseExpr(frame, unop.X) if err != nil {