NAME map one key
PROG begin { @map[16] = 32; @map[64] = 128; for ($kv : @map) { print($kv); }  }
EXPECT (16, 32)
EXPECT (64, 128)

NAME map two keys
PROG begin { @map[16,17] = 32; @map[64,65] = 128; for ($kv : @map) { print($kv); }  }
EXPECT ((16, 17), 32)
EXPECT ((64, 65), 128)

NAME map one key elements
PROG begin { @map[16] = 32; for ($kv : @map) { printf("key: %d, val: %d\n", $kv.0, $kv.1); }  }
EXPECT key: 16, val: 32

NAME map two key elements
PROG begin { @map[16,17] = 32; for ($kv : @map) { printf("key: (%d,%d), val: %d\n", $kv.0.0, $kv.0.1, $kv.1); }  }
EXPECT key: (16,17), val: 32

NAME map strings
PROG begin { @map["abc"] = "aa"; @map["def"] = "dd"; for ($kv : @map) { print($kv); }  }
EXPECT (abc, aa)
EXPECT (def, dd)

NAME map create map in body
PROG begin { @map[16] = 32; @map[64] = 128; for ($kv : @map) { @new[$kv.1] = $kv.0; } print(@new);  }
EXPECT @new[32]: 16
EXPECT @new[128]: 64

NAME map multiple loops
PROG begin { @mapA[16] = 32; @mapA[17] = 33; @mapB[64] = 128; @mapB[65] = 129; for ($kv : @mapA) { print($kv); } for ($kv : @mapB) { print($kv); }  }
EXPECT (16, 32)
EXPECT (17, 33)
EXPECT (64, 128)
EXPECT (65, 129)

NAME map multiple probes
PROG begin { @mapA[16] = 32; @mapA[17] = 33; @mapB[64] = 128; @mapB[65] = 129; for ($kv : @mapA) { print($kv); }  } end { for ($kv : @mapB) { print($kv); } }
EXPECT (16, 32)
EXPECT (17, 33)
EXPECT (64, 128)
EXPECT (65, 129)

NAME map nested vals
PROG begin { @mapA[16] = 32; @mapB[64] = 128; @mapB[65] = 129; for ($kv : @mapA) { print($kv); for ($kv2 : @mapB) { print($kv2); } }  }
EXPECT (16, 32)
EXPECT (64, 128)
EXPECT (65, 129)

NAME map nested count
PROG begin { @mapA[16] = 32; @mapA[17] = 33; @mapB[64] = 128; @mapB[65] = 129; @mapB[66] = 130; for ($kv : @mapA) { printf("A"); for ($kv2 : @mapB) { printf("B"); } }  }
EXPECT ABBBABBB

NAME map delete
PROG begin { @[0,0,0] = 1; @[0,0,1] = 1; @[0,1,0] = 1; @[1,0,0] = 1; for ($kv : @) { if ($kv.0.1 == 1) { delete(@, $kv.0); } }  }
EXPECT @[0, 0, 0]: 1
EXPECT @[0, 0, 1]: 1
EXPECT @[1, 0, 0]: 1
EXPECT_NONE @[0, 1, 0]: 1

NAME variable context read only
PROG begin { @map[0] = 0; $var = 123; for ($kv : @map) { print($var); }  }
EXPECT 123

NAME variable context update
PROG begin { @map[0] = 0; @map[1] = 1; $var = 123; for ($kv : @map) { print($var); $var *= 2; } print($var);  }
EXPECT_REGEX ^123\n246\n492$

NAME variable context string
PROG begin { @map[0] = 0; @map[1] = 1; $var = "abc"; for ($kv : @map) { print($var); $var = "def"; } print($var);  }
EXPECT_REGEX ^abc\ndef\ndef$

NAME variable context multiple
PROG begin { @map[0] = 0; $var1 = 123; $var2 = "abc"; for ($kv : @map) { print(($var1, $var2)); }  }
EXPECT (123, abc)

NAME map two keys with a per cpu aggregation
REQUIRES_FEATURE lookup_percpu_elem
PROG begin { @map[16,17] = count(); @map[16,17] = count(); @map[1,2] = count(); for ($kv : @map) { print($kv); }  }
EXPECT ((16, 17), 2)
EXPECT ((1, 2), 1)

NAME map stack key with a per cpu aggregation
REQUIRES_FEATURE lookup_percpu_elem
PROG begin { @map[kstack(raw)] = count(); for ($kv : @map) { print($kv.1); }  }
EXPECT 1

NAME map with break
PROG begin { @map["foo"] = 1; @map["bar"] = 2; print("start"); for ($i : @map) { print($i.0); break; } print("done");  }
EXPECT_REGEX .*start\n(foo|bar)\ndone\n\n

NAME map with continue
PROG begin { @map["foo"] = 1; @map["bar"] = 2; print("start"); for ($i : @map) { if ($i.0 == "bar") { continue; } print($i.0); }  }
EXPECT_REGEX .*start\nfoo\n\n

NAME range basic
PROG begin { for ($i : 0..5) { print($i); }  }
EXPECT_REGEX .*\n0\n1\n2\n3\n4\n\n

NAME range with variables
PROG begin { $start = 2; $end = 7; for ($i : $start..$end) { print($i); }  }
EXPECT_REGEX .*\n2\n3\n4\n5\n6\n\n

NAME range with expressions
PROG begin { for ($i : (1+1)..(2*4)) { print($i); }  }
EXPECT_REGEX .*\n2\n3\n4\n5\n6\n7\n\n

NAME range with map as expression
PROG begin { @map[5] = 8; for ($i : 0..@map[5]) { print($i); }  }
EXPECT_REGEX .*\n2\n3\n4\n5\n6\n7\n\n

NAME range with zero iterations
PROG begin { for ($i : 1..0) { print("here"); }  }
EXPECT_NONE here

NAME range with negative start
PROG begin { for ($i : (-3)..3) { print($i); }  }
EXPECT_REGEX .*\n-3\n-2\n-1\n0\n1\n2\n\n

NAME range with same start and end
PROG begin { for ($i : 5..5) { print("here"); }  }
EXPECT_NONE here

NAME range with variable modification
PROG begin { $sum = 0; for ($i : 1..5) { $sum += $i; } print($sum);  }
EXPECT_REGEX ^10

NAME range using a map
PROG begin { @a = 10; for ($i : 0..@a) { print($i); @a += 1; }  }
EXPECT_REGEX @a: 20

NAME range with break
PROG begin { for ($i : 1..4) { if ($i == 2) { break; } print($i); } print("5");  }
EXPECT_REGEX .*\n1\n5\n\n

NAME range with continue
PROG begin { for ($i : 1..4) { if ($i == 2) { continue; } print($i); }  }
EXPECT_REGEX .*\n1\n3\n\n
