plum

#treesitter#compiler#wasm

git clone https://git.pyrossh.dev/plum

A statically typed, imperative programming language inspired by rust, python


8ef7e9a — Peter John 2026-11-01T16:38:57+05:30
T2: Map.init variadic
Files changed (1) hide show
  1. plum-std/Map.plum +57 -5
plum-std/Map.plum CHANGED
@@ -31,16 +31,19 @@ enum Map[K, V] =
31
31
  # a big-enough fixed count keeps small-to-medium maps fast in practice.
32
32
  BUCKET_COUNT = 16
33
33
 
34
- # `Map[Str, Int]()` — explicit generics required (nothing in a no-arg call
34
+ # `Map[Str, Int]()` builds an empty map; `Map(Pair("a", 1), ...)` infers
35
+ # `K`/`V` from its entries (a later duplicate key wins, as in `set`).
35
- # pins down `K`/`V`), builds `BUCKET_COUNT` empty bucket lists up front via
36
+ # Builds `BUCKET_COUNT` empty bucket lists up front via `Array`'s `push`-to-grow.
36
- # `Array`'s `push`-to-grow.
37
- fun init() -> Map[K, V] =
37
+ fun init(entries: ...Pair[K, V]) -> Map[K, V] =
38
38
  b := Array[List[Pair[K, V]]]()
39
39
  i := 0
40
40
  while i < BUCKET_COUNT
41
41
  b = b.push(List[Pair[K, V]]())
42
42
  i = i + 1
43
- return Map(buckets: b, size: 0)
43
+ m := Map(buckets: b, size: 0)
44
+ for e := range entries
45
+ m.set(e.key, e.val)
46
+ return m
44
47
 
45
48
  # `k`'s bucket index — `hash`'s sign is unconstrained (a plain `%` on a
46
49
  # negative `Int` stays negative in Plum, matching wasm's signed
@@ -277,3 +280,52 @@ test "empty map iterates zero times"
277
280
  for k, v := range m
278
281
  n = n + 1
279
282
  assert n == 0
283
+
284
+ test "init_infers_kv_from_pairs: K and V come from the pairs"
285
+ m := Map(Pair("a", 1))
286
+ m.set("b", 2)
287
+ assert m.get("a")! == 1
288
+ assert m.get("b")! == 2
289
+ assert m.length() == 2
290
+
291
+ test "init: two pairs give length 2"
292
+ assert Map(Pair("a", 1), Pair("b", 2)).length() == 2
293
+
294
+ test "init: duplicate key, last wins"
295
+ m := Map(Pair("a", 1), Pair("a", 9))
296
+ assert m.get("a")! == 9
297
+ assert m.length() == 1
298
+
299
+ test "init: Map[Str, Int]() is empty"
300
+ assert Map[Str, Int]().isEmpty() == true
301
+
302
+ test "init_many_entries_cross_buckets: 20 pairs all read back"
303
+ m := Map(Pair("0", 0), Pair("1", 1), Pair("2", 2), Pair("3", 3), Pair("4", 4), Pair("5", 5), Pair("6", 6), Pair("7", 7), Pair("8", 8), Pair("9", 9), Pair("10", 10), Pair("11", 11), Pair("12", 12), Pair("13", 13), Pair("14", 14), Pair("15", 15), Pair("16", 16), Pair("17", 17), Pair("18", 18), Pair("19", 19))
304
+ assert m.length() == 20
305
+ assert m.get("0")! == 0
306
+ assert m.get("1")! == 1
307
+ assert m.get("2")! == 2
308
+ assert m.get("3")! == 3
309
+ assert m.get("4")! == 4
310
+ assert m.get("5")! == 5
311
+ assert m.get("6")! == 6
312
+ assert m.get("7")! == 7
313
+ assert m.get("8")! == 8
314
+ assert m.get("9")! == 9
315
+ assert m.get("10")! == 10
316
+ assert m.get("11")! == 11
317
+ assert m.get("12")! == 12
318
+ assert m.get("13")! == 13
319
+ assert m.get("14")! == 14
320
+ assert m.get("15")! == 15
321
+ assert m.get("16")! == 16
322
+ assert m.get("17")! == 17
323
+ assert m.get("18")! == 18
324
+ assert m.get("19")! == 19
325
+
326
+ test "init_int_keys"
327
+ assert Map(Pair(1, "x"), Pair(2, "y")).get(2)! == "y"
328
+
329
+ test "init_nested_value"
330
+ m := Map(Pair("a", Map(Pair("x", 1))))
331
+ assert m.get("a")!.get("x")! == 1