authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2022-01-24 20:46:10 -08:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2022-01-24 20:46:10 -08:00
logd387b9f94b384254a1979e74f42554287a7545a2
treec72b7999af33f84c0f3bb8c63b96d3a2ab26e0d4
parentc771db2448322a7d51ebe41cc4d48454f62c475c

add a context param to allow consumer to control where functions are sourced from


1 files changed, 25 insertions(+), 25 deletions(-)

src/lib.zig+25-25
...@@ -19,13 +19,13 @@ pub fn parse(comptime input: []const u8) astgen.Value {...@@ -19,13 +19,13 @@ pub fn parse(comptime input: []const u8) astgen.Value {
19 return astgen.Value{ .element = astgen.do(tokenize.do(input, &.{ '[', '=', ']', '(', ')', '{', '}', '#', '/', '.', '<', '>' })) };19 return astgen.Value{ .element = astgen.do(tokenize.do(input, &.{ '[', '=', ']', '(', ')', '{', '}', '#', '/', '.', '<', '>' })) };
20}20}
2121
22pub fn compile(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, data: anytype) !void {22pub fn compile(comptime Ctx: type, alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, data: anytype) !void {
23 try writer.writeAll("<!DOCTYPE html>\n");23 try writer.writeAll("<!DOCTYPE html>\n");
24 try do(alloc, writer, value, data, data, 0, false);24 try do(Ctx, alloc, writer, value, data, data, 0, false);
25 try writer.writeAll("\n");25 try writer.writeAll("\n");
26}26}
2727
28fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype, indent: usize, flag1: bool) anyerror!void {28fn do(comptime Ctx: type, alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype, indent: usize, flag1: bool) anyerror!void {
29 switch (comptime value) {29 switch (comptime value) {
30 .element => |v| {30 .element => |v| {
31 const hastext = for (v.children) |x| {31 const hastext = for (v.children) |x| {
...@@ -41,7 +41,7 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d...@@ -41,7 +41,7 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d
41 .string => try writer.print(" {s}=\"{}\"", .{ it.key, std.zig.fmtEscapes(it.value.string[1 .. it.value.string.len - 1]) }),41 .string => try writer.print(" {s}=\"{}\"", .{ it.key, std.zig.fmtEscapes(it.value.string[1 .. it.value.string.len - 1]) }),
42 .body => {42 .body => {
43 try writer.print(" {s}=\"", .{it.key});43 try writer.print(" {s}=\"", .{it.key});
44 try do(alloc, writer, astgen.Value{ .body = it.value.body }, data, ctx, indent, flag1);44 try do(Ctx, alloc, writer, astgen.Value{ .body = it.value.body }, data, ctx, indent, flag1);
45 try writer.print("\"", .{});45 try writer.print("\"", .{});
46 },46 },
47 }47 }
...@@ -58,7 +58,7 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d...@@ -58,7 +58,7 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d
5858
59 if (!hastext) try writer.writeAll("\n");59 if (!hastext) try writer.writeAll("\n");
60 inline for (v.children) |it| {60 inline for (v.children) |it| {
61 try do(alloc, writer, it, data, ctx, indent + 1, !hastext);61 try do(Ctx, alloc, writer, it, data, ctx, indent + 1, !hastext);
62 }62 }
63 if (!hastext) for (range(indent)) |_| try writer.writeAll(" ");63 if (!hastext) for (range(indent)) |_| try writer.writeAll(" ");
64 try writer.print("</{s}>", .{v.name});64 try writer.print("</{s}>", .{v.name});
...@@ -106,25 +106,25 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d...@@ -106,25 +106,25 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d
106 switch (v.name) {106 switch (v.name) {
107 .each => {107 .each => {
108 comptime assertEqual(v.args.len, 1);108 comptime assertEqual(v.args.len, 1);
109 for (x) |item| try do(alloc, writer, body, item, ctx, indent, flag1);109 for (x) |item| try do(Ctx, alloc, writer, body, item, ctx, indent, flag1);
110 },110 },
111 .@"if" => {111 .@"if" => {
112 comptime assertEqual(v.args.len, 1);112 comptime assertEqual(v.args.len, 1);
113 if (comptime std.meta.trait.isIndexable(T)) {113 if (comptime std.meta.trait.isIndexable(T)) {
114 try doif(alloc, writer, body, bottom, data, ctx, indent, flag1, x.len > 0);114 try doif(Ctx, alloc, writer, body, bottom, data, ctx, indent, flag1, x.len > 0);
115 return;115 return;
116 }116 }
117 switch (comptime TI) {117 switch (comptime TI) {
118 .Bool => try doif(alloc, writer, body, bottom, data, ctx, indent, flag1, x),118 .Bool => try doif(Ctx, alloc, writer, body, bottom, data, ctx, indent, flag1, x),
119 .Optional => try docap(alloc, writer, body, bottom, data, ctx, indent, flag1, x),119 .Optional => try docap(Ctx, alloc, writer, body, bottom, data, ctx, indent, flag1, x),
120 else => @compileError(comptime std.fmt.comptimePrint("pek: unable to use '{s}' in an #if block", .{@typeName(T)})),120 else => @compileError(comptime std.fmt.comptimePrint("pek: unable to use '{s}' in an #if block", .{@typeName(T)})),
121 }121 }
122 },122 },
123 .ifnot => {123 .ifnot => {
124 comptime assertEqual(v.args.len, 1);124 comptime assertEqual(v.args.len, 1);
125 switch (comptime TI) {125 switch (comptime TI) {
126 .Bool => try doif(alloc, writer, body, bottom, data, ctx, indent, flag1, !x),126 .Bool => try doif(Ctx, alloc, writer, body, bottom, data, ctx, indent, flag1, !x),
127 .Optional => try docap(alloc, writer, body, bottom, data, ctx, indent, flag1, !x),127 .Optional => try docap(Ctx, alloc, writer, body, bottom, data, ctx, indent, flag1, !x),
128 else => @compileError(comptime std.fmt.comptimePrint("pek: unable to use '{s}' in an #ifnot block", .{@typeName(T)})),128 else => @compileError(comptime std.fmt.comptimePrint("pek: unable to use '{s}' in an #ifnot block", .{@typeName(T)})),
129 }129 }
130 },130 },
...@@ -132,31 +132,31 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d...@@ -132,31 +132,31 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d
132 comptime assertEqual(v.args.len, 2);132 comptime assertEqual(v.args.len, 2);
133 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);133 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);
134 if (@typeInfo(@TypeOf(x)) == .Enum and comptime std.meta.trait.isZigString(@TypeOf(y))) {134 if (@typeInfo(@TypeOf(x)) == .Enum and comptime std.meta.trait.isZigString(@TypeOf(y))) {
135 return try doif(alloc, writer, body, bottom, data, ctx, indent, flag1, std.mem.eql(u8, @tagName(x), y));135 return try doif(Ctx, alloc, writer, body, bottom, data, ctx, indent, flag1, std.mem.eql(u8, @tagName(x), y));
136 }136 }
137 try doif(alloc, writer, body, bottom, data, ctx, indent, flag1, x == y);137 try doif(Ctx, alloc, writer, body, bottom, data, ctx, indent, flag1, x == y);
138 },138 },
139 .ifnotequal => {139 .ifnotequal => {
140 comptime assertEqual(v.args.len, 2);140 comptime assertEqual(v.args.len, 2);
141 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);141 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);
142 if (@typeInfo(@TypeOf(x)) == .Enum and comptime std.meta.trait.isZigString(@TypeOf(y))) {142 if (@typeInfo(@TypeOf(x)) == .Enum and comptime std.meta.trait.isZigString(@TypeOf(y))) {
143 return try doif(alloc, writer, body, bottom, data, ctx, indent, flag1, std.mem.eql(u8, @tagName(x), y));143 return try doif(Ctx, alloc, writer, body, bottom, data, ctx, indent, flag1, std.mem.eql(u8, @tagName(x), y));
144 }144 }
145 try doif(alloc, writer, body, bottom, data, ctx, indent, flag1, x != y);145 try doif(Ctx, alloc, writer, body, bottom, data, ctx, indent, flag1, x != y);
146 },146 },
147 }147 }
148 },148 },
149 .body => |v| {149 .body => |v| {
150 inline for (v) |val| {150 inline for (v) |val| {
151 try do(alloc, writer, val, data, ctx, indent, flag1);151 try do(Ctx, alloc, writer, val, data, ctx, indent, flag1);
152 }152 }
153 },153 },
154 .function => |v| {154 .function => |v| {
155 var arena = std.heap.ArenaAllocator.init(alloc);155 var arena = std.heap.ArenaAllocator.init(alloc);
156 defer arena.deinit();156 defer arena.deinit();
157157
158 if (@hasDecl(root, "pek_" ++ v.name)) {158 if (@hasDecl(Ctx, "pek_" ++ v.name)) {
159 const func = @field(root, "pek_" ++ v.name);159 const func = @field(Ctx, "pek_" ++ v.name);
160 var list = std.ArrayList(u8).init(arena.allocator());160 var list = std.ArrayList(u8).init(arena.allocator());
161 errdefer list.deinit();161 errdefer list.deinit();
162 var args: FnArgsTuple(func) = undefined;162 var args: FnArgsTuple(func) = undefined;
...@@ -168,7 +168,7 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d...@@ -168,7 +168,7 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d
168 }168 }
169 const repvalue = astgen.Value{ .replacement = &.{"this"} };169 const repvalue = astgen.Value{ .replacement = &.{"this"} };
170 try @call(.{}, func, args);170 try @call(.{}, func, args);
171 try do(alloc, writer, repvalue, list.toOwnedSlice(), ctx, indent, flag1);171 try do(Ctx, alloc, writer, repvalue, list.toOwnedSlice(), ctx, indent, flag1);
172 return;172 return;
173 }173 }
174 @compileError("pek: unknown custom function: " ++ v.name);174 @compileError("pek: unknown custom function: " ++ v.name);
...@@ -255,19 +255,19 @@ fn contains(haystack: []const []const u8, needle: []const u8) bool {...@@ -255,19 +255,19 @@ fn contains(haystack: []const []const u8, needle: []const u8) bool {
255 return false;255 return false;
256}256}
257257
258fn doif(alloc: std.mem.Allocator, writer: anytype, comptime top: astgen.Value, comptime bottom: astgen.Value, data: anytype, ctx: anytype, indent: usize, flag1: bool, flag2: bool) anyerror!void {258fn doif(comptime Ctx: type, alloc: std.mem.Allocator, writer: anytype, comptime top: astgen.Value, comptime bottom: astgen.Value, data: anytype, ctx: anytype, indent: usize, flag1: bool, flag2: bool) anyerror!void {
259 if (flag2) {259 if (flag2) {
260 try do(alloc, writer, top, data, ctx, indent, flag1);260 try do(Ctx, alloc, writer, top, data, ctx, indent, flag1);
261 } else {261 } else {
262 try do(alloc, writer, bottom, data, ctx, indent, flag1);262 try do(Ctx, alloc, writer, bottom, data, ctx, indent, flag1);
263 }263 }
264}264}
265265
266fn docap(alloc: std.mem.Allocator, writer: anytype, comptime top: astgen.Value, comptime bottom: astgen.Value, data: anytype, ctx: anytype, indent: usize, flag1: bool, flag2: anytype) anyerror!void {266fn docap(comptime Ctx: type, alloc: std.mem.Allocator, writer: anytype, comptime top: astgen.Value, comptime bottom: astgen.Value, data: anytype, ctx: anytype, indent: usize, flag1: bool, flag2: anytype) anyerror!void {
267 if (flag2) |_| {267 if (flag2) |_| {
268 try do(alloc, writer, top, data, ctx, indent, flag1);268 try do(Ctx, alloc, writer, top, data, ctx, indent, flag1);
269 } else {269 } else {
270 try do(alloc, writer, bottom, data, ctx, indent, flag1);270 try do(Ctx, alloc, writer, bottom, data, ctx, indent, flag1);
271 }271 }
272}272}
273273