diff options
author | Ayke van Laethem <[email protected]> | 2018-10-20 17:54:16 +0200 |
---|---|---|
committer | Ayke van Laethem <[email protected]> | 2018-10-20 17:54:16 +0200 |
commit | 7c2a6169b0ad59909b87dbac405e7e0e23979363 (patch) | |
tree | 28c8707f95c696ad50d74f7a6d2e73f4fa6810ce /compiler/map.go | |
parent | da89464a63a7c181e928a68f4ac392bd841a00b2 (diff) | |
download | tinygo-7c2a6169b0ad59909b87dbac405e7e0e23979363.tar.gz tinygo-7c2a6169b0ad59909b87dbac405e7e0e23979363.zip |
compiler: support comma-ok in map lookup
Diffstat (limited to 'compiler/map.go')
-rw-r--r-- | compiler/map.go | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/compiler/map.go b/compiler/map.go index 23d216da4..d4d318bcc 100644 --- a/compiler/map.go +++ b/compiler/map.go @@ -9,29 +9,37 @@ import ( "github.com/aykevl/go-llvm" ) -func (c *Compiler) emitMapLookup(keyType, valueType types.Type, m, key llvm.Value) (llvm.Value, error) { +func (c *Compiler) emitMapLookup(keyType, valueType types.Type, m, key llvm.Value, commaOk bool) (llvm.Value, error) { llvmValueType, err := c.getLLVMType(valueType) if err != nil { return llvm.Value{}, err } mapValueAlloca := c.builder.CreateAlloca(llvmValueType, "hashmap.value") mapValuePtr := c.builder.CreateBitCast(mapValueAlloca, c.i8ptrType, "hashmap.valueptr") + var commaOkValue llvm.Value if t, ok := keyType.(*types.Basic); ok && t.Info()&types.IsString != 0 { // key is a string params := []llvm.Value{m, key, mapValuePtr} - c.createRuntimeCall("hashmapStringGet", params, "") - return c.builder.CreateLoad(mapValueAlloca, ""), nil + commaOkValue = c.createRuntimeCall("hashmapStringGet", params, "") } else if hashmapIsBinaryKey(keyType) { // key can be compared with runtime.memequal keyAlloca := c.builder.CreateAlloca(key.Type(), "hashmap.key") c.builder.CreateStore(key, keyAlloca) keyPtr := c.builder.CreateBitCast(keyAlloca, c.i8ptrType, "hashmap.keyptr") params := []llvm.Value{m, keyPtr, mapValuePtr} - c.createRuntimeCall("hashmapBinaryGet", params, "") - return c.builder.CreateLoad(mapValueAlloca, ""), nil + commaOkValue = c.createRuntimeCall("hashmapBinaryGet", params, "") } else { return llvm.Value{}, errors.New("todo: map lookup key type: " + keyType.String()) } + mapValue := c.builder.CreateLoad(mapValueAlloca, "") + if commaOk { + tuple := llvm.Undef(c.ctx.StructType([]llvm.Type{llvmValueType, c.ctx.Int1Type()}, false)) + tuple = c.builder.CreateInsertValue(tuple, mapValue, 0, "") + tuple = c.builder.CreateInsertValue(tuple, commaOkValue, 1, "") + return tuple, nil + } else { + return mapValue, nil + } } func (c *Compiler) emitMapUpdate(keyType types.Type, m, key, value llvm.Value) error { |