This is subject to change with the addition of Optional to the
standard library.
"""
-get :: (use map: &Map, key: map.Key_Type) -> map.Value_Type {
+get :: (use map: &Map, key: map.Key_Type) -> ? map.Value_Type {
lr := lookup(map, key);
if lr.entry_index >= 0 do return entries[lr.entry_index].value;
//
// Helper operator overloads for accessing values, accessing
// values by pointer, and setting values.
-#operator [] macro (map: Map($K, $V), key: K) -> V { return #this_package.get(&map, key); }
+#operator [] macro (map: Map($K, $V), key: K) -> ?V { return #this_package.get(&map, key); }
#operator &[] macro (map: Map($K, $V), key: K) -> &V { return #this_package.get_ptr(&map, key); }
#operator []= macro (map: Map($K, $V), key: K, value: V) { #this_package.put(&map, key, value); }
//
// Use a custom formatter, if one is registered for the type.
- if formatting.custom_format && custom_formatters->has(v.type) {
- custom_formatters[v.type](output, formatting, v.data);
- return;
+ if formatting.custom_format {
+ custom_formatters->get(v.type)->with([formatter] {
+ formatter(output, formatting, v.data);
+ return;
+ });
}
switch v.type {
#overload
parse_any :: (target: rawptr, data_type: type_expr, to_parse: str, string_allocator := context.allocator) -> bool {
- if custom_parsers->has(data_type) {
- return custom_parsers[data_type](target, to_parse, string_allocator);
- }
+ custom_parsers->get(data_type)->with([parser] {
+ return parser(target, to_parse, string_allocator);
+ });
use runtime.info {*};
info := get_type_info(data_type);
__exited :: (id: i32) {
sync.scoped_mutex(&thread_mutex);
- thread := thread_map->get(id);
+ thread := thread_map->get(id)?;
if thread != null {
thread.alive = false;
#if runtime.Wait_Notify_Available {
}
while turn != 2021 {
- st := map.get(&nums, last_num);
+ st := map.get(&nums, last_num) ?? .{};
if st.previous == 0 do last_num = 0;
else do last_num = st.recent - st.previous;
- st = map.get(&nums, last_num);
+ st = map.get(&nums, last_num) ?? .{};
st.previous = st.recent;
st.recent = turn;
map.put(&nums, last_num, st);
for x: -1 .. 2 do for y: -1 .. 2 do for z: -1 .. 2 do for w: -1 .. 2 {
if x == 0 && y == 0 && z == 0 && w == 0 do continue;
key := CubePos.{ pos.x + x, pos.y + y, pos.z + z, pos.w + w };
- state := map.get(cubes, key);
- if state.alive do count += 1;
+ map.get(cubes, key)->with([s] {
+ if s.alive do count += 1;
+ });
}
return count;
}
for &cube: cubes_to_consider {
- state := map.get(&cubes, *cube);
+ state := map.get(&cubes, *cube) ?? .{};
ncount := get_neighbor_count(&cubes, *cube);
if state.alive {
}
for &cube: cubes_to_consider {
- state := map.get(&cubes, *cube);
+ state := map.get(&cubes, *cube) ?? .{};
state.alive = state.next;
map.put(&cubes, *cube, state);
}
if grid[tid.pos_x + 12 * tid.pos_y] != 0 do continue;
- tile_ptr := map.get(&tile_map, tid.match.tile);
+ tile_ptr := map.get(&tile_map, tid.match.tile)->unwrap();
tile_ptr.pos_x = tid.pos_x;
tile_ptr.pos_y = tid.pos_y;
grid[tid.pos_x + 12 * tid.pos_y] = tid.match.tile;
forest : [12 * 8 * 12 * 8] u8;
for y: 0 .. 12 {
for x: 0 .. 12 {
- tile := map.get(&tile_map, grid[y * 12 + x]);
+ tile := map.get(&tile_map, grid[y * 12 + x])->unwrap();
for fy: 0 .. 8 {
for fx: 0 .. 8 {
array.push(&food.ingredients, ingredient_name);
- ingredient := map.get(&ingredient_map, ingredient_name);
- if ingredient.name.data == null {
- ingredient.name = ingredient_name;
- array.init(&ingredient.appears_on, 4);
- }
+ ingredient := map.get(&ingredient_map, ingredient_name) ?? .{
+ name = ingredient_name,
+ appears_on = make([..] u32, 4)
+ };
array.push(&ingredient.appears_on, line_num);
array.push(&food.allergens, allergen_name);
- allergen := map.get(&allergen_map, allergen_name);
- if allergen.name.data == null {
- allergen.name = allergen_name;
- array.init(&allergen.appears_on, 4);
- }
+ allergen := map.get(&allergen_map, allergen_name) ?? .{
+ name = allergen_name,
+ appears_on = make([..] u32, 4)
+ };
array.push(&allergen.appears_on, line_num);
potential_allergen_count := 0;
for &allergen_name: potential_allergens {
c := array_count_contains(&potential_allergens, *allergen_name, string.equal);
- allergen := map.get(&allergen_map, *allergen_name);
+ allergen := map.get(&allergen_map, *allergen_name)->unwrap();
if c == allergen.appears_on.count {
potential_allergen_count += 1;
}
total_safe := 0;
for safe: definitely_safe {
- ingredient := map.get(&ingredient_map, safe);
+ ingredient := map.get(&ingredient_map, safe)->unwrap();
total_safe += ingredient.appears_on.count;
map.delete(&ingredient_map, safe);
}
if match_count == 1 {
- ingredient := map.get(&ingredient_map, matching_ingredient_name);
+ ingredient := map.get(&ingredient_map, matching_ingredient_name)->unwrap();
map.delete(&ingredient_map, matching_ingredient_name);
ingredient.allergen = allergen_entry.key;
}
- curr := map.get(&grid, loc);
+ curr := map.get(&grid, loc) ?? .{};
map.put(&grid, loc, .{ alive = !curr.alive });
}
}
for &cell: cells_to_consider {
- state := map.get(&grid, *cell);
+ state := map.get(&grid, *cell) ?? .{};
ncount := get_neighbor_count(&grid, *cell);
if state.alive {
count := 0;
for &dir: Hex_Directions {
- cell := map.get(grid, Vec2.{ x = pos.x + dir.x, y = pos.y + dir.y });
+ cell := map.get(grid, Vec2.{ x = pos.x + dir.x, y = pos.y + dir.y }) ?? .{};
if cell.alive do count += 1;
}
tmp = ~~b;
for i: 0 .. m {
if map.has(&t, ~~tmp) {
- v := map.get(&t, ~~tmp);
+ v := map.get(&t, ~~tmp) ?? 0;
return i * m + v;
}
}
bg_get_node :: (use graph: &BagGraph, name: str) -> &BagNode {
- node := map.get(&node_map, name);
+ node := map.get(&node_map, name) ?? null;
if node == null {
node = calloc(sizeof BagNode);
for &line: lines {
for p: line_points(*line) {
- if point_count->has(p) {
- point_count[p] = point_count[p] + 1;
- } else {
- point_count[p] = 1;
- }
+ point_count[p] = (point_count[p] ?? 0) + 1;
}
}
printf("Part 2: {}\n", count);
}
-}
\ No newline at end of file
+}
// Solve for bottom segment
for three_data {
- if solved_segments[it] == 4 do continue;
- if solved_segments[it] == 1 do continue;
+ if solved_segments[it] ?? 0 == 4 do continue;
+ if solved_segments[it] ?? 0 == 1 do continue;
for o: one_data do if it == o do continue continue;
solved_segments[it] = 7;
if seg.count != 5 do continue;
for four_data {
- if solved_segments[it] == 4 do continue;
+ if solved_segments[it] ?? 0 == 4 do continue;
for o: one_data do if it == o do continue continue;
if array.contains(seg, it) {
break;
}
- if solved_segments[it] == 0 {
+ if solved_segments[it] ?? 0 == 0 {
solved_segments[it] = 2;
}
}
for one_data {
- if solved_segments[it] == 0 do solved_segments[it] = 3;
+ if solved_segments[it] ?? 0 == 0 do solved_segments[it] = 3;
}
for *array.first(left_segments, (x) => x.count == 7) {
- if solved_segments[it] == 0 {
+ if solved_segments[it] ?? 0 == 0 {
solved_segments[it] = 5;
}
}
string.strip_whitespace(it);
num_segments : [7] bool;
- for w: *it do num_segments[solved_segments[w] - 1] = true;
+ for w: *it do num_segments[solved_segments[w] ?? 0 - 1] = true;
sum *= 10;
for i: 10 {
printf("Part {}: {}\n", 1 if PART == 1 else 2, answer);
}
-}
\ No newline at end of file
+}
potential << Pos.{t.x,t.y+1};
}
if t.x > 0 {
- if heightmap[Pos.{t.x-1,t.y}].height > 0 {
+ if heightmap[Pos.{t.x-1,t.y}]->unwrap().height > 0 {
potential << Pos.{t.x-1,t.y};
}
}
if t.y > 0 {
- if heightmap[Pos.{t.x,t.y-1}].height > 0 {
+ if heightmap[Pos.{t.x,t.y-1}]->unwrap().height > 0 {
potential << Pos.{t.x,t.y-1};
}
}
for y: height - 1 do for x: width {
map.update(&heightmap, .{x,y}) {
- it.dy = it.height - heightmap[Pos.{x,y+1}].height;
+ it.dy = it.height - heightmap[Pos.{x,y+1}]->unwrap().height;
}
}
for x: width - 1 do for y: height {
map.update(&heightmap, .{x,y}) {
- it.dx = it.height - heightmap[Pos.{x+1,y}].height;
+ it.dx = it.height - heightmap[Pos.{x+1,y}]->unwrap().height;
}
}
if y < height - 1 && h.dy >= 0 do continue;
if x > 0 {
- if heightmap[Pos.{x-1, y}].dx <= 0 do continue;
+ if heightmap[Pos.{x-1, y}]->unwrap().dx <= 0 do continue;
}
if y > 0 {
- if heightmap[Pos.{x, y-1}].dy <= 0 do continue;
+ if heightmap[Pos.{x, y-1}]->unwrap().dy <= 0 do continue;
}
lowest << .{x, y};
for ch: line {
switch ch {
case #char "(", #char "[", #char "<", #char "{" {
- char_stack << bracket_map[ch];
+ char_stack << bracket_map[ch]->unwrap();
}
case #char ")", #char "]", #char ">", #char "}" {
x := array.pop(&char_stack);
if x != ch {
// printf("Expected '{}', found '{}' instead.\n", x, ch);
- corrupted_score += score_map[ch];
+ corrupted_score += score_map[ch]->unwrap();
continue continue;
}
}
println(completion_scores);
printf("Part 2: {}\n", completion_scores[completion_scores.count / 2]);
}
-}
\ No newline at end of file
+}
node_idx := node_stack.count - 1;
defer node_stack[node_idx].child_idx += 1;
- children := edge_map[node_stack[node_idx].name];
+ children := edge_map[node_stack[node_idx].name] ?? .[];
valid := node_stack[node_idx].child_idx < children.count;
if valid {
mode: Map(u8, u64);
for& polymer_state.entries {
- mode[it.key.second] = mode[it.key.second] + it.value.now;
+ mode[it.key.second] = (mode[it.key.second] ?? .{}) + it.value.now;
}
maximum := array.fold(mode.entries, cast(u64) 0, (x, y) => math.max(x.value, y));
map.put(&ages, "Pam", 24);
print_age :: (ages: &map.Map(str, u32), name: str) {
- age := map.get(ages, name);
+ age := map.get(ages, name) ?? 0;
printf("{}'s age is {}.\n", name, age);
}
println(map.has(&imap, 50));
println(map.has(&imap, 51));
- printf("{}{}\n", map.get(&imap, 50), map.get(&imap, 1234));
+ printf("{}{}\n", map.get(&imap, 50)->unwrap(), map.get(&imap, 1234)->unwrap());
printf("{*p}\n", &imap);
if n <= 1 do return n;
- if map.has(&cache, n) do return map.get(&cache, n);
+ map.get(&cache, n)->with([n] { return n; });
res := cached_fib(n - 1) + cached_fib(n - 2);
map.put(&cache, n, res);