mirror of
https://github.com/ziex-dev/ziex.git
synced 2026-07-22 11:39:34 -06:00
149 lines
5.1 KiB
Zig
149 lines
5.1 KiB
Zig
const std = @import("std");
|
|
|
|
pub fn calcExprSource(allocator: std.mem.Allocator) ![]const u8 {
|
|
var out: std.ArrayList(u8) = .empty;
|
|
defer out.deinit(allocator);
|
|
const w = out.writer(allocator);
|
|
|
|
try w.writeAll(
|
|
\\pub const CalcExpr = struct {
|
|
\\ const Self = @This();
|
|
\\ pub const Unit = enum {
|
|
\\ px,
|
|
\\ em,
|
|
\\ rem,
|
|
\\ percent,
|
|
\\ pub fn toString(self: Unit) []const u8 {
|
|
\\ return switch (self) {
|
|
\\ .percent => "%",
|
|
\\ else => @tagName(self),
|
|
\\ };
|
|
\\ }
|
|
\\ };
|
|
\\
|
|
\\ pub const Op = enum {
|
|
\\ add,
|
|
\\ sub,
|
|
\\ mul,
|
|
\\ div,
|
|
\\ pub fn toString(self: Op) []const u8 {
|
|
\\ return switch (self) {
|
|
\\ .add => "+",
|
|
\\ .sub => "-",
|
|
\\ .mul => "*",
|
|
\\ .div => "/",
|
|
\\ };
|
|
\\ }
|
|
\\ };
|
|
\\
|
|
\\ buf: [64]u8 = undefined,
|
|
\\ len: u8 = 0,
|
|
\\
|
|
\\ fn init(t: []const u8) Self {
|
|
\\ var self: Self = undefined;
|
|
\\ if (t.len > self.buf.len) @panic("calc expression too complex");
|
|
\\ std.mem.copyForwards(u8, self.buf[0..t.len], t);
|
|
\\ self.len = @intCast(t.len);
|
|
\\ return self;
|
|
\\ }
|
|
\\
|
|
\\ fn text(self: Self) []const u8 {
|
|
\\ return self.buf[0..self.len];
|
|
\\ }
|
|
\\
|
|
\\ fn leaf(value: []const u8) Self {
|
|
\\ return Self.init(value);
|
|
\\ }
|
|
\\
|
|
\\ fn unitLeaf(unit: Unit, value: f32) Self {
|
|
\\ var temp: [64]u8 = undefined;
|
|
\\ const written = std.fmt.bufPrint(&temp, "{d}{s}", .{ value, unit.toString() }) catch @panic("calc expression too complex");
|
|
\\ return Self.leaf(written);
|
|
\\ }
|
|
\\
|
|
\\ fn numberLeaf(value: f32) Self {
|
|
\\ var temp: [64]u8 = undefined;
|
|
\\ const written = std.fmt.bufPrint(&temp, "{d}", .{value}) catch @panic("calc expression too complex");
|
|
\\ return Self.leaf(written);
|
|
\\ }
|
|
\\
|
|
\\ fn rawLeaf(value: []const u8) Self {
|
|
\\ return Self.leaf(value);
|
|
\\ }
|
|
\\
|
|
\\ pub fn px(value: f32) Self {
|
|
\\ return Self.unitLeaf(.px, value);
|
|
\\ }
|
|
\\
|
|
\\ pub fn em(value: f32) Self {
|
|
\\ return Self.unitLeaf(.em, value);
|
|
\\ }
|
|
\\
|
|
\\ pub fn rem(value: f32) Self {
|
|
\\ return Self.unitLeaf(.rem, value);
|
|
\\ }
|
|
\\
|
|
\\ pub fn percent(value: f32) Self {
|
|
\\ return Self.unitLeaf(.percent, value);
|
|
\\ }
|
|
\\
|
|
\\ pub fn raw(value: []const u8) Self {
|
|
\\ return Self.rawLeaf(value);
|
|
\\ }
|
|
\\
|
|
\\ pub fn number(value: f32) Self {
|
|
\\ return Self.numberLeaf(value);
|
|
\\ }
|
|
\\
|
|
\\ fn combine(self: Self, other: Self, op: Op) Self {
|
|
\\ var temp: [128]u8 = undefined;
|
|
\\ const lhs = self.text();
|
|
\\ const rhs = other.text();
|
|
\\ const op_text = op.toString();
|
|
\\ const needed = lhs.len + rhs.len + op_text.len + 4;
|
|
\\ if (needed > temp.len) @panic("calc expression too complex");
|
|
\\
|
|
\\ var i: usize = 0;
|
|
\\ temp[i] = '(';
|
|
\\ i += 1;
|
|
\\ std.mem.copyForwards(u8, temp[i..][0..lhs.len], lhs);
|
|
\\ i += lhs.len;
|
|
\\ temp[i] = ' ';
|
|
\\ i += 1;
|
|
\\ std.mem.copyForwards(u8, temp[i..][0..op_text.len], op_text);
|
|
\\ i += op_text.len;
|
|
\\ temp[i] = ' ';
|
|
\\ i += 1;
|
|
\\ std.mem.copyForwards(u8, temp[i..][0..rhs.len], rhs);
|
|
\\ i += rhs.len;
|
|
\\ temp[i] = ')';
|
|
\\ i += 1;
|
|
\\
|
|
\\ return Self.init(temp[0..i]);
|
|
\\ }
|
|
\\
|
|
\\ pub fn add(self: Self, other: Self) Self {
|
|
\\ return self.combine(other, .add);
|
|
\\ }
|
|
\\
|
|
\\ pub fn sub(self: Self, other: Self) Self {
|
|
\\ return self.combine(other, .sub);
|
|
\\ }
|
|
\\
|
|
\\ pub fn mul(self: Self, factor: f32) Self {
|
|
\\ return self.combine(Self.numberLeaf(factor), .mul);
|
|
\\ }
|
|
\\
|
|
\\ pub fn div(self: Self, factor: f32) Self {
|
|
\\ return self.combine(Self.numberLeaf(factor), .div);
|
|
\\ }
|
|
\\
|
|
\\ pub fn format(self: Self, w: *std.io.Writer) std.io.Writer.Error!void {
|
|
\\ try w.writeAll(self.text());
|
|
\\ }
|
|
\\};
|
|
);
|
|
|
|
return try out.toOwnedSlice(allocator);
|
|
}
|