aboutsummaryrefslogtreecommitdiffhomepage
path: root/compiler/map.go
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2018-10-20 17:54:16 +0200
committerAyke van Laethem <[email protected]>2018-10-20 17:54:16 +0200
commit7c2a6169b0ad59909b87dbac405e7e0e23979363 (patch)
tree28c8707f95c696ad50d74f7a6d2e73f4fa6810ce /compiler/map.go
parentda89464a63a7c181e928a68f4ac392bd841a00b2 (diff)
downloadtinygo-7c2a6169b0ad59909b87dbac405e7e0e23979363.tar.gz
tinygo-7c2a6169b0ad59909b87dbac405e7e0e23979363.zip
compiler: support comma-ok in map lookup
Diffstat (limited to 'compiler/map.go')
-rw-r--r--compiler/map.go18
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 {