From 18e2a96b76f7e5d338602279eb825f11d6d2d436 Mon Sep 17 00:00:00 2001 From: hl-valdemar Date: Tue, 23 Jun 2026 17:57:32 +0200 Subject: [PATCH] pointer field passthrough --- TODO.md | 3 ++ testbed/main.bro | 87 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 testbed/main.bro diff --git a/TODO.md b/TODO.md index a1a317a..156e60e 100644 --- a/TODO.md +++ b/TODO.md @@ -141,6 +141,9 @@ - backing-type operators and reverse explicit conversions remain deferred - concrete runtime backing types are supported; unresolved, `int`, `void`, function, and opaque backings are rejected +9. allow pointer field access pass-through (implemented) + - having a pointer (`ptr`) to a struct, we should allow access through `ptr.field` as opposed to mandating `ptr^.field` + ## A word on multi-unwrap Unwrap multiple optionals with `and`. This **short-circuits**: if the first optional is none, subsequent expressions are not evaluated. diff --git a/testbed/main.bro b/testbed/main.bro new file mode 100644 index 0000000..c6597a9 --- /dev/null +++ b/testbed/main.bro @@ -0,0 +1,87 @@ +printf :: c_func(format *c_char, ...) c_int + +PlayerID :: distinct u32 + +Tier :: enum(u8) { + bronze = 1 + silver + gold +} + +Player :: struct { + id PlayerID + name *c_char + tier Tier + score i32 + streak i32 + active bool +} + +tier_bonus :: func(tier Tier) i32 { + if tier == .gold { + return 30 + } else if tier == .silver { + return 15 + } + return 5 +} + +projected_score :: func(player Player) i32 { + total i32 = player.score + total += tier_bonus(player.tier) + if player.active and player.streak > 2 { + total += player.streak * 3 + } + return total +} + +apply_decay :: func(players []mut Player) void { + for players |@player| { + if !player.active { + player.score -= 4 + } + } +} + +best_player :: func(players []mut Player) ?@mut Player { + best ?@mut Player = none + best_score i32 = 0 + + for players |@player| { + score :: projected_score(player^) + if best |_| { + if score > best_score { + best = player + best_score = score + } + } else { + best = player + best_score = score + } + } + + return best +} + +main :: func() i32 { + players [4]mut Player = [ + Player { id = PlayerID(1), name = "Ada", tier = .gold, score = 41, streak = 4, active = true }, + Player { id = PlayerID(2), name = "Ken", tier = .silver, score = 56, streak = 1, active = true }, + Player { id = PlayerID(3), name = "Edsger", tier = .bronze, score = 64, streak = 0, active = false }, + Player { id = PlayerID(4), name = "Grace", tier = .gold, score = 33, streak = 5, active = true }, + ] + + apply_decay((&players)[..]) + + for (&players) |@player, index| { + score :: projected_score(player^) + _ = printf("%d: %s projected=%d\n", index, player.name, score) + } + + if best_player((&players)[..]) |winner : projected_score(winner^) >= 80| { + _ = printf("winner: %s\n", winner.name) + return 0 + } + + return 1 +}