Skip to content

Instantly share code, notes, and snippets.

@MatthiasPortzel
Last active July 27, 2024 18:19
Show Gist options
  • Save MatthiasPortzel/d170000da57c76bfb2ca28d4aa55d13a to your computer and use it in GitHub Desktop.
Save MatthiasPortzel/d170000da57c76bfb2ca28d4aa55d13a to your computer and use it in GitHub Desktop.
const std = @import("std");
// -- Proposed microzig code -- //
const Pin = struct {
number: usize,
fn toggle(self: Pin) void {
std.debug.print("toggling pin {}\n", .{ self.number });
}
};
const PinConfiguration = struct {
const PinConfig = struct {
direction: enum { in, out },
name: []const u8
};
GPIO0: PinConfig,
GPIO1: PinConfig,
};
fn PinsType(pin_config: PinConfiguration) type {
// Placeholder for comptime magic that would create this struct type dynamically
_ = pin_config;
return struct {
led_1: Pin,
led_2: Pin,
};
}
fn createPins(comptime pin_config: PinConfiguration) PinsType(pin_config) {
// Placeholder for a comptime inline for that would do this dynamically
var pins_: PinsType(pin_config) = undefined;
pins_.led_1.number = 1;
pins_.led_2.number = 2;
return pins_;
}
// I think this basically has to be anytype because we could have different `pins` from different configurations with different types
fn applyPins(_pins: anytype) void {
// Placeholder for the MMIO that sets up the pins
_ = _pins;
}
// -- User Code -- //
// In this case, this is guaranteed to be comptime since it's top-level
const pins = createPins(.{
.GPIO0 = .{
.name = "led_1",
.direction = .out,
},
.GPIO1 = .{
.name = "led_2",
.direction = .out,
}
});
// It can be used at comptime
comptime {
// @compileLog(pins.led_2.number);
}
pub fn main() !void {
applyPins(pins);
// It can be optimized at runtime since the pin number here is known at comptime
pins.led_1.toggle();
// It can be used at runtime!
const a: u32 = 5;
const p: Pin = if (a < 5) pins.led_1 else pins.led_2;
p.toggle();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment