const std = @import("std");
const Pkg = struct {
name: []const u8,
path: []const u8,
dependencies: []const *Pkg = &.{},
};
const build_pkgs = &.{
Pkg{
.name = "zap",
.path = "deps/zap/src/main.zig",
},
Pkg{
.name = "clap",
.path = "deps/clap/src/main.zig",
},
};
const c = @cImport({
@cInclude("stdio.h");
@cInclude("stdlib.h");
});
pub extern "C" fn c_malloc(size: usize) ?*anyopaque;
pub extern "C" fn c_free(ptr: ?*anyopaque) void;
export fn zig_add(a: i32, b: i32) i32 {
return a + b;
}
export fn zig_process(data: [*]const u8, len: usize) i32 {
var sum: i32 = 0;
for (0..len) |i| {
sum += data[i];
}
return sum;
}
const Frame = @Frame(asyncTask);
fn asyncTask(id: u32, delay_ms: u32) u32 {
std.time.sleep(delay_ms * std.time.ns_per_ms);
std.debug.print("Task {} completed\n", .{id});
return id * 10;
}
fn asyncExample() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
var frame1 = try allocator.create(Frame);
defer allocator.destroy(frame1);
var frame2 = try allocator.create(Frame);
defer allocator.destroy(frame2);
frame1.* = async asyncTask(1, 100);
frame2.* = async asyncTask(2, 50);
const result1 = await frame1;
const result2 = await frame2;
std.debug.print("Results: {}, {}\n", .{ result1, result2 });
}
fn StateMachine(comptime State: type, comptime Event: type, comptime transitions: anytype) type {
return struct {
state: State,
pub fn init(initial: State) @This() {
return .{ .state = initial };
}
pub fn handle(self: *@This(), event: Event) ?State {
inline for (transitions) |t| {
if (self.state == t.from and event == t.event) {
self.state = t.to;
return t.to;
}
}
return null;
}
};
}
const TrafficLightState = enum { red, yellow, green };
const LightEvent = enum { timer, emergency };
const TrafficLight = StateMachine(TrafficLightState, LightEvent, &.{
.{ .from = .red, .event = .timer, .to = .green },
.{ .from = .green, .event = .timer, .to = .yellow },
.{ .from = .yellow, .event = .timer, .to = .red },
.{ .from = .green, .event = .emergency, .to = .red },
.{ .from = .yellow, .event = .emergency, .to = .red },
});
fn RingBuffer(comptime T: type, comptime capacity: usize) type {
return struct {
buffer: [capacity]T = undefined,
head: usize = 0,
tail: usize = 0,
count: usize = 0,
const Self = @This();
pub fn push(self: *Self, item: T) !void {
if (self.count >= capacity) return error.Full;
self.buffer[self.tail] = item;
self.tail = (self.tail + 1) % capacity;
self.count += 1;
}
pub fn pop(self: *Self) ?T {
if (self.count == 0) return null;
const item = self.buffer[self.head];
self.head = (self.head + 1) % capacity;
self.count -= 1;
return item;
}
pub fn isEmpty(self: *const Self) bool {
return self.count == 0;
}
pub fn isFull(self: *const Self) bool {
return self.count == capacity;
}
};
}
const BitSet = struct {
bits: u64,
pub fn init() BitSet {
return .{ .bits = 0 };
}
pub fn set(self: *BitSet, bit: u6) void {
self.bits |= @as(u64, 1) << bit;
}
pub fn clear(self: *BitSet, bit: u6) void {
self.bits &= ~(@as(u64, 1) << bit);
}
pub fn isSet(self: *const BitSet, bit: u6) bool {
return (self.bits >> bit) & 1 == 1;
}
pub fn toggle(self: *BitSet, bit: u6) void {
self.bits ^= @as(u64, 1) << bit;
}
};
fn vectorAdd(a: [4]f32, b: [4]f32) [4]f32 {
const va: @Vector(4, f32) = a;
const vb: @Vector(4, f32) = b;
const result = va + vb;
return @bitCast([4]f32, result);
}
const Serializer = struct {
buffer: []u8,
pos: usize,
pub fn init(buf: []u8) Serializer {
return .{ .buffer = buf, .pos = 0 };
}
pub fn writeInt(self: *Serializer, value: u32) !void {
if (self.pos + 4 > self.buffer.len) return error.NoSpace;
std.mem.writeIntBig(u32, self.buffer[self.pos..][0..4], value);
self.pos += 4;
}
pub fn writeBytes(self: *Serializer, bytes: []const u8) !void {
if (self.pos + bytes.len > self.buffer.len) return error.NoSpace;
@memcpy(self.buffer[self.pos..][0..bytes.len], bytes);
self.pos += bytes.len;
}
pub fn getWritten(self: *const Serializer) []const u8 {
return self.buffer[0..self.pos];
}
};
const Deserializer = struct {
buffer: []const u8,
pos: usize,
pub fn init(buf: []const u8) Deserializer {
return .{ .buffer = buf, .pos = 0 };
}
pub fn readInt(self: *Deserializer) !u32 {
if (self.pos + 4 > self.buffer.len) return error.Underflow;
const value = std.mem.readIntBig(u32, self.buffer[self.pos..][0..4]);
self.pos += 4;
return value;
}
pub fn readBytes(self: *Deserializer, len: usize) ![]const u8 {
if (self.pos + len > self.buffer.len) return error.Underflow;
const result = self.buffer[self.pos..][0..len];
self.pos += len;
return result;
}
};
fn validateStruct(comptime T: type) void {
const info = @typeInfo(T);
if (info != .Struct) {
@compileError("Expected struct type");
}
inline for (info.Struct.fields) |field| {
if (field.type == []const u8) {
@compileLog("Field", field.name, "is a string");
}
}
}
const TestStruct = struct {
name: []const u8,
count: u32,
};
comptime {
validateStruct(TestStruct);
}
fn Lazy(comptime T: type, comptime initFn: fn () T) type {
return struct {
var value: ?T = null;
var mutex = std.Thread.Mutex{};
pub fn get() *T {
if (value == null) {
mutex.lock();
defer mutex.unlock();
if (value == null) {
value = initFn();
}
}
return &value.?;
}
};
}
const Command = union(enum) {
add: struct { x: i32, y: i32 },
sub: struct { x: i32, y: i32 },
mul: struct { x: i32, y: i32 },
pub fn execute(self: Command) i32 {
return switch (self) {
.add => |args| args.x + args.y,
.sub => |args| args.x - args.y,
.mul => |args| args.x * args.y,
};
}
};
test "ring buffer" {
var buf = RingBuffer(u32, 4){};
try buf.push(1);
try buf.push(2);
try buf.push(3);
std.testing.expectEqual(@as(u32, 1), buf.pop().?);
try buf.push(4);
try buf.push(5);
std.testing.expect(buf.isFull());
std.testing.expectEqual(@as(u32, 2), buf.pop().?);
}
test "bit set" {
var bs = BitSet.init();
bs.set(5);
std.testing.expect(bs.isSet(5));
bs.toggle(5);
std.testing.expect(!bs.isSet(5));
}
test "command pattern" {
const cmd = Command{ .add = .{ .x = 10, .y = 20 } };
std.testing.expectEqual(@as(i32, 30), cmd.execute());
}
pub fn main() !void {
var light = TrafficLight.init(.red);
_ = light.handle(.timer);
std.debug.print("Light state: {}\n", .{light.state});
var ring = RingBuffer(u32, 8){};
try ring.push(100);
try ring.push(200);
while (ring.pop()) |val| {
std.debug.print("Ring value: {}\n", .{val});
}
var buf: [100]u8 = undefined;
var ser = Serializer.init(&buf);
try ser.writeInt(0x12345678);
try ser.writeBytes("hello");
var deser = Deserializer.init(ser.getWritten());
const int_val = try deser.readInt();
const bytes = try deser.readBytes(5);
std.debug.print("Deserialized: {x}, {s}\n", .{ int_val, bytes });
const commands = &[_]Command{
.{ .add = .{ .x = 1, .y = 2 } },
.{ .sub = .{ .x = 10, .y = 3 } },
.{ .mul = .{ .x = 4, .y = 5 } },
};
for (commands) |cmd| {
std.debug.print("Result: {}\n", .{cmd.execute()});
}
const ptr = c_malloc(100);
if (ptr) |p| {
std.debug.print("Allocated {} bytes via C\n", .{@as(usize, 100)});
c_free(p);
}
asyncExample() catch |err| {
std.debug.print("Async error: {}\n", .{err});
};
}