a slightly different question from an earlier post, now that i’ve learned a few more things…
consider the following code, which i’ve already compiled for my bare-metal MCU and have inspect the generated .asm file:
const std = @import("std");
fn REG(adr: u32) *volatile u32 {
const reg: *volatile u32 = @ptrFromInt(adr);
return reg;
}
fn done() void {
var dummy: u32 = 0xCAFE;
const vp: *volatile u32 = &dummy;
while (vp.* != 0) {}
}
const Counter = struct {
_val: u8 = 0,
fn inc(self: *Counter) void {
comptime self._val += 1;
}
fn get(self: *Counter) u8 {
return self._val;
}
};
fn mkCounter() Counter {
comptime var c: Counter = .{};
return c;
}
export fn main() void {
comptime var ctr = mkCounter();
comptime {
ctr.inc();
ctr.inc();
std.debug.assert(ctr.get() == 2);
}
REG(12345678).* = ctr.get();
done();
}
as you can see, i’ve created a Counter instance which i’ve manipulated at comptime using the (comptime-only) inc method… i then call get when writing the counter’s value to some (phony) memory-mapped address…
[[ as an aside, i can in fact write the _val field at runtime (by design in zig); disciplined use of the Counter methods preserves the semantics i’m looking for ]]
what i want to do, however, is effectively have my comptime var ctr exist at container-level – where in fact zig prevents such declarations…
as an example, i’d like MyMod.zig to expose a single Counter instance to any of its clients; these clients can then call the inc method as often as they wish at comptime… at runtime, however, any client (as well as MyMod itself) can read the finally tally through the get method…
thoughts on how to realize this in zig ???