From b393c0ba4e91780d20ecc127f616a8af857e95e5 Mon Sep 17 00:00:00 2001 From: Burak Bilge Yalcinkaya Date: Thu, 19 Dec 2024 22:45:34 +0300 Subject: [PATCH] implement `map_keys` and `map_vals` --- src/komet/kdist/soroban-semantics/host/map.md | 30 ++++++++++ src/tests/integration/data/map.wast | 57 +++++++++++++++++++ .../contracts/test_containers/src/lib.rs | 15 ++++- 3 files changed, 100 insertions(+), 2 deletions(-) diff --git a/src/komet/kdist/soroban-semantics/host/map.md b/src/komet/kdist/soroban-semantics/host/map.md index 1179183..c37af91 100644 --- a/src/komet/kdist/soroban-semantics/host/map.md +++ b/src/komet/kdist/soroban-semantics/host/map.md @@ -199,6 +199,36 @@ increasing order. Its primary use is alongside [`map_val_by_pos`](#map_val_by_po orBool size(M) <=Int I ``` +## map_keys + +```k + + rule [hostCallAux-map-keys]: + hostCallAux("m", "7") + => allocObject(ScVec(sortedKeys(M))) + ~> returnHostVal + ... + + ScMap(M) : S => S + +``` + +## map_vals + +```k + + rule [hostCallAux-map-vals]: + hostCallAux("m", "8") + => allocObject(ScVec( + lookupMany(M, sortedKeys(M), Void) + )) + ~> returnHostVal + ... + + ScMap(M) : S => S + +``` + ## map_unpack_to_linear_memory Writes values from a map (`ScMap`) to a specified memory address. diff --git a/src/tests/integration/data/map.wast b/src/tests/integration/data/map.wast index 805e433..bbc395a 100644 --- a/src/tests/integration/data/map.wast +++ b/src/tests/integration/data/map.wast @@ -11,6 +11,8 @@ uploadWasm( b"test-wasm", (import "m" "4" (func $has (param i64 i64) (result i64))) (import "m" "5" (func $key_by_pos (param i64 i64) (result i64))) (import "m" "6" (func $val_by_pos (param i64 i64) (result i64))) + (import "m" "7" (func $keys (param i64) (result i64))) + (import "m" "8" (func $vals (param i64) (result i64))) (export "new" (func $new)) (export "put" (func $put)) @@ -20,6 +22,8 @@ uploadWasm( b"test-wasm", (export "has" (func $has)) (export "key_by_pos" (func $key_by_pos)) (export "val_by_pos" (func $val_by_pos)) + (export "keys" (func $keys)) + (export "vals" (func $vals)) ) ) @@ -294,4 +298,57 @@ callTx( Error(ErrObject, 1) ;; IndexBounds ) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; map_keys +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +callTx( + Account(b"test-caller"), + Contract(b"test-sc"), + "keys", + ListItem(ScMap( + Symbol(str("b")) |-> U32(1) + Symbol(str("a")) |-> U32(2) + )), + ScVec( + ListItem(Symbol(str("a"))) + ListItem(Symbol(str("b"))) + ) +) + +callTx( + Account(b"test-caller"), + Contract(b"test-sc"), + "keys", + ListItem(ScMap(.Map)), + ScVec(.List) +) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; map_vals +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +callTx( + Account(b"test-caller"), + Contract(b"test-sc"), + "vals", + ListItem(ScMap( + Symbol(str("b")) |-> U32(1) + Symbol(str("a")) |-> U32(2) + )), + ScVec( + ListItem(U32(2)) + ListItem(U32(1)) + ) +) + +callTx( + Account(b"test-caller"), + Contract(b"test-sc"), + "vals", + ListItem(ScMap(.Map)), + ScVec(.List) +) + setExitCode(0) \ No newline at end of file diff --git a/src/tests/integration/data/soroban/contracts/test_containers/src/lib.rs b/src/tests/integration/data/soroban/contracts/test_containers/src/lib.rs index ae5338d..26eb2ad 100644 --- a/src/tests/integration/data/soroban/contracts/test_containers/src/lib.rs +++ b/src/tests/integration/data/soroban/contracts/test_containers/src/lib.rs @@ -26,6 +26,8 @@ impl ContainersContract { true } + + // Iterate through the key-value pairs in the map ensuring keys are strictly increasing pub fn test_map_iterate(env: Env, n: u32) -> bool { let n = n % 100; @@ -37,16 +39,25 @@ impl ContainersContract { } assert_eq!(map.len(), n); - // Iterate through the key-value pairs in the map, ensuring: + let vals = map.values(); + let keys = map.keys(); + let mut cur = 0; for (i, x) in map { - // Keys are strictly increasing assert_eq!(cur, i); assert_eq!(x, -(i as i32)); cur += 1; } + for (i, k) in keys.iter().enumerate() { + assert_eq!(k, i as u32); + } + + for (i, x) in vals.iter().enumerate() { + assert_eq!(x, -(i as i32)); + } + true } }