From c3cb22030f948bd75ebc6d9200819d38d6c7bc11 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Wed, 22 Aug 2018 00:56:11 +0200 Subject: [PATCH] Implement == and != for strings --- compiler.go | 25 +++++++++++++++++++++---- src/runtime/runtime.go | 12 ++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/compiler.go b/compiler.go index ce68b27f..0fbe99ba 100644 --- a/compiler.go +++ b/compiler.go @@ -1542,10 +1542,27 @@ func (c *Compiler) parseBinOp(frame *Frame, binop *ssa.BinOp) (llvm.Value, error // Go specific. Calculate "and not" with x & (~y) inv := c.builder.CreateNot(y, "") // ~y return c.builder.CreateAnd(x, inv, ""), nil - case token.EQL: // == - return c.builder.CreateICmp(llvm.IntEQ, x, y, ""), nil - case token.NEQ: // != - return c.builder.CreateICmp(llvm.IntNE, x, y, ""), nil + case token.EQL, token.NEQ: // ==, != + switch typ := binop.X.Type().Underlying().(type) { + case *types.Basic: + if typ.Info()&types.IsInteger != 0 || typ.Kind() == types.UnsafePointer { + if binop.Op == token.EQL { + return c.builder.CreateICmp(llvm.IntEQ, x, y, ""), nil + } else { + return c.builder.CreateICmp(llvm.IntNE, x, y, ""), nil + } + } else if typ.Kind() == types.String { + result := c.builder.CreateCall(c.mod.NamedFunction("runtime.stringequal"), []llvm.Value{x, y}, "") + if binop.Op == token.NEQ { + result = c.builder.CreateNot(result, "") + } + return result, nil + } else { + return llvm.Value{}, errors.New("todo: equality operator on unknown basic type: " + typ.String()) + } + default: + return llvm.Value{}, errors.New("todo: equality operator on unknown type: " + typ.String()) + } case token.LSS: // < if signed { return c.builder.CreateICmp(llvm.IntSLT, x, y, ""), nil diff --git a/src/runtime/runtime.go b/src/runtime/runtime.go index 1e2c910a..1f85963c 100644 --- a/src/runtime/runtime.go +++ b/src/runtime/runtime.go @@ -17,6 +17,18 @@ func GOMAXPROCS(n int) int { return 1 } +func stringequal(x, y string) bool { + if len(x) != len(y) { + return false + } + for i := 0; i < len(x); i++ { + if x[i] != y[i] { + return false + } + } + return true +} + func _panic(message interface{}) { printstring("panic: ") printitf(message)