authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2023-05-20 10:52:49 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2023-05-20 10:52:49 -07:00
log7062632e64ba10c8d18c53586b02eb015fe43ba9
treeb784b2c53a38786f1aec75382ea39139146e3d17
parent6eac31e028be7d8972590ca342e33bda882f813c

put Ctx inside DoOptions


1 files changed, 44 insertions(+), 36 deletions(-)

src/lib.zig+44-36
......@@ -22,7 +22,8 @@ pub fn parse(comptime input: string) astgen.Value {
2222
2323pub fn compile(comptime Ctx: type, alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, data: anytype) !void {
2424 try writer.writeAll("<!DOCTYPE html>\n");
25 try do(Ctx, alloc, writer, value, data, data, .{
25 try do(alloc, writer, value, data, data, .{
26 .Ctx = Ctx,
2627 .indent = 0,
2728 .flag1 = false,
2829 });
......@@ -31,10 +32,10 @@ pub fn compile(comptime Ctx: type, alloc: std.mem.Allocator, writer: anytype, co
3132
3233pub const Writer = std.ArrayList(u8).Writer;
3334
34inline fn do(comptime Ctx: type, alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype, opts: DoOptions) anyerror!void {
35inline fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype, comptime opts: DoOptions) anyerror!void {
3536 switch (comptime value) {
3637 .element => |v| {
37 const hastext = for (v.children) |x| {
38 const hastext = comptime for (v.children) |x| {
3839 switch (x) {
3940 .string, .replacement, .function => break true,
4041 .element, .attr, .block, .body => {},
......@@ -50,7 +51,7 @@ inline fn do(comptime Ctx: type, alloc: std.mem.Allocator, writer: anytype, comp
5051 .string => try writer.print(" {s}=\"{}\"", .{ it.key, std.zig.fmtEscapes(it.value.string[1 .. it.value.string.len - 1]) }),
5152 .body => {
5253 try writer.print(" {s}=\"", .{it.key});
53 try do(Ctx, alloc, writer, astgen.Value{ .body = it.value.body }, data, ctx, opts);
54 try do(alloc, writer, astgen.Value{ .body = it.value.body }, data, ctx, opts);
5455 try writer.print("\"", .{});
5556 },
5657 }
......@@ -67,7 +68,8 @@ inline fn do(comptime Ctx: type, alloc: std.mem.Allocator, writer: anytype, comp
6768
6869 if (!hastext) try writer.writeAll("\n");
6970 inline for (v.children) |it| {
70 try do(Ctx, alloc, writer, it, data, ctx, .{
71 try do(alloc, writer, it, data, ctx, .{
72 .Ctx = opts.Ctx,
7173 .indent = opts.indent + 1,
7274 .flag1 = !hastext,
7375 });
......@@ -117,25 +119,25 @@ inline fn do(comptime Ctx: type, alloc: std.mem.Allocator, writer: anytype, comp
117119 switch (v.name) {
118120 .each => {
119121 comptime assertEqual(v.args.len, 1);
120 for (x) |item| try do(Ctx, alloc, writer, body, item, ctx, opts);
122 for (x) |item| try do(alloc, writer, body, item, ctx, opts);
121123 },
122124 .@"if" => {
123125 comptime assertEqual(v.args.len, 1);
124126 if (comptime std.meta.trait.isIndexable(T)) {
125 try doif(Ctx, alloc, writer, body, bottom, data, ctx, opts, x.len > 0);
127 try doif(alloc, writer, body, bottom, data, ctx, opts, x.len > 0);
126128 return;
127129 }
128130 switch (comptime TI) {
129 .Bool => try doif(Ctx, alloc, writer, body, bottom, data, ctx, opts, x),
130 .Optional => try docap(Ctx, alloc, writer, body, bottom, data, ctx, opts, x),
131 .Bool => try doif(alloc, writer, body, bottom, data, ctx, opts, x),
132 .Optional => try docap(alloc, writer, body, bottom, data, ctx, opts, x),
131133 else => @compileError(std.fmt.comptimePrint("pek: unable to use '{s}' in an #if block", .{@typeName(T)})),
132134 }
133135 },
134136 .ifnot => {
135137 comptime assertEqual(v.args.len, 1);
136138 switch (comptime TI) {
137 .Bool => try doif(Ctx, alloc, writer, body, bottom, data, ctx, opts, !x),
138 .Optional => try docap(Ctx, alloc, writer, body, bottom, data, ctx, opts, !x),
139 .Bool => try doif(alloc, writer, body, bottom, data, ctx, opts, !x),
140 .Optional => try docap(alloc, writer, body, bottom, data, ctx, opts, !x),
139141 else => @compileError(std.fmt.comptimePrint("pek: unable to use '{s}' in an #ifnot block", .{@typeName(T)})),
140142 }
141143 },
......@@ -143,31 +145,31 @@ inline fn do(comptime Ctx: type, alloc: std.mem.Allocator, writer: anytype, comp
143145 comptime assertEqual(v.args.len, 2);
144146 const y = if (comptime std.mem.eql(u8, v.args[1][0], "this")) search(v.args[1][1..], data) else search(v.args[1], ctx);
145147 if (@typeInfo(@TypeOf(x)) == .Enum and comptime std.meta.trait.isZigString(@TypeOf(y))) {
146 return try doif(Ctx, alloc, writer, body, bottom, data, ctx, opts, std.mem.eql(u8, @tagName(x), y));
148 return try doif(alloc, writer, body, bottom, data, ctx, opts, std.mem.eql(u8, @tagName(x), y));
147149 }
148 try doif(Ctx, alloc, writer, body, bottom, data, ctx, opts, x == y);
150 try doif(alloc, writer, body, bottom, data, ctx, opts, x == y);
149151 },
150152 .ifnotequal => {
151153 comptime assertEqual(v.args.len, 2);
152154 const y = if (comptime std.mem.eql(u8, v.args[1][0], "this")) search(v.args[1][1..], data) else search(v.args[1], ctx);
153155 if (@typeInfo(@TypeOf(x)) == .Enum and comptime std.meta.trait.isZigString(@TypeOf(y))) {
154 return try doif(Ctx, alloc, writer, body, bottom, data, ctx, opts, std.mem.eql(u8, @tagName(x), y));
156 return try doif(alloc, writer, body, bottom, data, ctx, opts, std.mem.eql(u8, @tagName(x), y));
155157 }
156 try doif(Ctx, alloc, writer, body, bottom, data, ctx, opts, x != y);
158 try doif(alloc, writer, body, bottom, data, ctx, opts, x != y);
157159 },
158160 }
159161 },
160162 .body => |v| {
161163 inline for (v) |val| {
162 try do(Ctx, alloc, writer, val, data, ctx, opts);
164 try do(alloc, writer, val, data, ctx, opts);
163165 }
164166 },
165167 .function => |v| {
166168 var arena = std.heap.ArenaAllocator.init(alloc);
167169 defer arena.deinit();
168170
169 if (!v.raw and @hasDecl(Ctx, "pek_" ++ v.name)) {
170 const func = @field(Ctx, "pek_" ++ v.name);
171 if (!v.raw and @hasDecl(opts.Ctx, "pek_" ++ v.name)) {
172 const func = @field(opts.Ctx, "pek_" ++ v.name);
171173 var list = std.ArrayList(u8).init(arena.allocator());
172174 errdefer list.deinit();
173175 var args: std.meta.ArgsTuple(@TypeOf(func)) = undefined;
......@@ -179,30 +181,35 @@ inline fn do(comptime Ctx: type, alloc: std.mem.Allocator, writer: anytype, comp
179181 }
180182 const repvalue = astgen.Value{ .replacement = .{ .arms = &.{"this"}, .raw = v.raw } };
181183 try @call(.auto, func, args);
182 try do(Ctx, alloc, writer, repvalue, try list.toOwnedSlice(), ctx, opts);
184 try do(alloc, writer, repvalue, try list.toOwnedSlice(), ctx, opts);
183185 return;
184186 }
185 if (v.raw and @hasDecl(Ctx, "pek__" ++ v.name)) {
186 const func = @field(Ctx, "pek__" ++ v.name);
187 if (v.raw and @hasDecl(opts.Ctx, "pek__" ++ v.name)) {
188 const func = @field(opts.Ctx, "pek__" ++ v.name);
187189 var list = std.ArrayList(u8).init(arena.allocator());
188190 errdefer list.deinit();
189 var args: std.meta.ArgsTuple(@TypeOf(func)) = undefined;
190 args.@"0" = alloc;
191 args.@"1" = list.writer();
192 args[2] = opts;
191 const AT = std.meta.ArgsTuple(@TypeOf(func));
192 const ATT = std.meta.fieldInfo(AT, .@"3").type;
193 var tupargs = @as(ATT, undefined);
194 var args = .{
195 alloc,
196 list.writer(),
197 opts,
198 tupargs,
199 };
193200 inline for (v.args, 0..) |arg, i| {
194 const field_name = comptime std.fmt.comptimePrint("{d}", .{i + 3});
195 @field(args, field_name) = if (comptime std.mem.eql(u8, arg[0], "this")) search(arg[1..], data) else search(arg, ctx);
201 const field_name = comptime std.fmt.comptimePrint("{d}", .{i});
202 @field(args[3], field_name) = if (comptime std.mem.eql(u8, arg[0], "this")) search(arg[1..], data) else search(arg, ctx);
196203 }
197204 const repvalue = astgen.Value{ .replacement = .{ .arms = &.{"this"}, .raw = v.raw } };
198205 try @call(.auto, func, args);
199 try do(Ctx, alloc, writer, repvalue, try list.toOwnedSlice(), ctx, opts);
206 try do(alloc, writer, repvalue, try list.toOwnedSlice(), ctx, opts);
200207 return;
201208 }
202 if (v.raw and @hasDecl(Ctx, "pek_" ++ v.name)) {
209 if (v.raw and @hasDecl(opts.Ctx, "pek_" ++ v.name)) {
203210 @compileError("pek: attempted to call safe custom function: '" ++ v.name ++ "' but did not use '{" ++ v.name ++ "}'");
204211 }
205 if (!v.raw and @hasDecl(Ctx, "pek__" ++ v.name)) {
212 if (!v.raw and @hasDecl(opts.Ctx, "pek__" ++ v.name)) {
206213 @compileError("pek: attempted to call raw custom function: '_" ++ v.name ++ "' but did not use '{#" ++ v.name ++ "}'");
207214 }
208215 @compileError("pek: unknown custom function: " ++ v.name);
......@@ -212,6 +219,7 @@ inline fn do(comptime Ctx: type, alloc: std.mem.Allocator, writer: anytype, comp
212219}
213220
214221pub const DoOptions = struct {
222 Ctx: type,
215223 indent: usize,
216224 flag1: bool,
217225};
......@@ -328,18 +336,18 @@ fn contains(haystack: []const string, needle: string) bool {
328336 return false;
329337}
330338
331fn doif(comptime Ctx: type, alloc: std.mem.Allocator, writer: anytype, comptime top: astgen.Value, comptime bottom: astgen.Value, data: anytype, ctx: anytype, opts: DoOptions, flag2: bool) anyerror!void {
339fn doif(alloc: std.mem.Allocator, writer: anytype, comptime top: astgen.Value, comptime bottom: astgen.Value, data: anytype, ctx: anytype, comptime opts: DoOptions, flag2: bool) anyerror!void {
332340 if (flag2) {
333 try do(Ctx, alloc, writer, top, data, ctx, opts);
341 try do(alloc, writer, top, data, ctx, opts);
334342 } else {
335 try do(Ctx, alloc, writer, bottom, data, ctx, opts);
343 try do(alloc, writer, bottom, data, ctx, opts);
336344 }
337345}
338346
339fn docap(comptime Ctx: type, alloc: std.mem.Allocator, writer: anytype, comptime top: astgen.Value, comptime bottom: astgen.Value, data: anytype, ctx: anytype, opts: DoOptions, flag2: anytype) anyerror!void {
347fn docap(alloc: std.mem.Allocator, writer: anytype, comptime top: astgen.Value, comptime bottom: astgen.Value, data: anytype, ctx: anytype, comptime opts: DoOptions, flag2: anytype) anyerror!void {
340348 if (flag2) |_| {
341 try do(Ctx, alloc, writer, top, data, ctx, opts);
349 try do(alloc, writer, top, data, ctx, opts);
342350 } else {
343 try do(Ctx, alloc, writer, bottom, data, ctx, opts);
351 try do(alloc, writer, bottom, data, ctx, opts);
344352 }
345353}