authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2024-04-10 12:10:57 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2024-04-10 12:10:57 -07:00
logf734eef7d8fc77e3c2b4c3447a8d73b5aedaa283
tree422cb0ef9fa4017ea5ede04ea450214fe5afc7d3
parent115c652942aa7a063335e202613716aee22737a6

allow parentheses values as arguments to custom functions


2 files changed, 33 insertions(+), 15 deletions(-)

src/astgen.zig+6
......@@ -61,6 +61,7 @@ pub const Arg = union(enum) {
6161 lookup: []const string,
6262 plain: string,
6363 int: u64,
64 value: []const Value,
6465};
6566
6667//
......@@ -214,6 +215,11 @@ const Parser = struct {
214215 ret = ret ++ &[_]Arg{.{ .plain = self.eat(.string) }};
215216 continue;
216217 }
218 if (self.tryEatSymbol("(")) {
219 self.index -= 1;
220 ret = ret ++ &[_]Arg{.{ .value = self.doChildren() }};
221 continue;
222 }
217223 if (temp.len == 0 and self.nextIs(.word)) {
218224 const next_word = self.eat(.word);
219225 if (extras.matchesAll(u8, next_word, std.ascii.isDigit)) {
src/lib.zig+27-15
......@@ -94,7 +94,8 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d
9494 }
9595 },
9696 .string => |v| {
97 try writeEscaped(v[1 .. v.len - 1], writer);
97 if (opts.escaped) try writeEscaped(v[1 .. v.len - 1], writer);
98 if (!opts.escaped) try writer.writeAll(v[1 .. v.len - 1]);
9899 },
99100 .replacement => |repl| {
100101 const v = repl.arms;
......@@ -108,7 +109,8 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d
108109 return;
109110 }
110111 const s = std.mem.trim(u8, x, "\n");
111 try writeEscaped(s, writer);
112 if (opts.escaped) try writeEscaped(s, writer);
113 if (!opts.escaped) try writer.writeAll(s);
112114 return;
113115 }
114116 if (TI == .Int or TI == .Float or TI == .ComptimeInt or TI == .ComptimeFloat) {
......@@ -128,7 +130,8 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d
128130 return;
129131 }
130132 const s = std.mem.trim(u8, &x, "\n");
131 try writeEscaped(s, writer);
133 if (opts.escaped) try writeEscaped(s, writer);
134 if (!opts.escaped) try writer.writeAll(s);
132135 return;
133136 }
134137 @compileError(std.fmt.comptimePrint("pek: print {s}: unsupported type: {s}", .{ v, @typeName(TO) }));
......@@ -136,7 +139,7 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d
136139 .block => |v| {
137140 const body = astgen.Value{ .body = v.body };
138141 const bottom = astgen.Value{ .body = v.bttm };
139 const x = resolveArg(v.args[0], data, ctx);
142 const x = try resolveArg(v.args[0], alloc, data, ctx, opts);
140143 const T = @TypeOf(x);
141144 const TI = @typeInfo(T);
142145 switch (v.name) {
......@@ -150,12 +153,12 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d
150153 const x2 = try switch (@typeInfo(@TypeOf(f)).Fn.params.len) {
151154 2 => f(alloc, x),
152155 3 => blk: {
153 const y = resolveArg(v.args[1], data, ctx);
156 const y = try resolveArg(v.args[1], alloc, data, ctx, opts);
154157 break :blk f(alloc, x, y);
155158 },
156159 4 => blk: {
157 const y = resolveArg(v.args[1], data, ctx);
158 const z = resolveArg(v.args[2], data, ctx);
160 const y = try resolveArg(v.args[1], alloc, data, ctx, opts);
161 const z = try resolveArg(v.args[2], alloc, data, ctx, opts);
159162 break :blk f(alloc, x, y, z);
160163 },
161164 else => unreachable, // TODO
......@@ -180,12 +183,12 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d
180183 const x2 = try switch (@typeInfo(@TypeOf(f)).Fn.params.len) {
181184 2 => f(alloc, x),
182185 3 => blk: {
183 const y = resolveArg(v.args[1], data, ctx);
186 const y = try resolveArg(v.args[1], alloc, data, ctx, opts);
184187 break :blk f(alloc, x, y);
185188 },
186189 4 => blk: {
187 const y = resolveArg(v.args[1], data, ctx);
188 const z = resolveArg(v.args[2], data, ctx);
190 const y = try resolveArg(v.args[1], alloc, data, ctx, opts);
191 const z = try resolveArg(v.args[2], alloc, data, ctx, opts);
189192 break :blk f(alloc, x, y, z);
190193 },
191194 else => unreachable, // TODO
......@@ -206,7 +209,7 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d
206209 },
207210 .ifequal => {
208211 comptime assertEqual(v.args.len, 2);
209 const y = resolveArg(v.args[1], data, ctx);
212 const y = try resolveArg(v.args[1], alloc, data, ctx, opts);
210213 if (@typeInfo(@TypeOf(x)) == .Enum and comptime std.meta.trait.isZigString(@TypeOf(y))) {
211214 return try doif(alloc, writer, body, bottom, data, ctx, opts, std.mem.eql(u8, @tagName(x), y));
212215 }
......@@ -217,7 +220,7 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d
217220 },
218221 .ifnotequal => {
219222 comptime assertEqual(v.args.len, 2);
220 const y = resolveArg(v.args[1], data, ctx);
223 const y = try resolveArg(v.args[1], alloc, data, ctx, opts);
221224 if (@typeInfo(@TypeOf(x)) == .Enum and comptime std.meta.trait.isZigString(@TypeOf(y))) {
222225 return try doif(alloc, writer, body, bottom, data, ctx, opts, !std.mem.eql(u8, @tagName(x), y));
223226 }
......@@ -247,7 +250,7 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d
247250 args.@"1" = list.writer();
248251 inline for (v.args, 0..) |arg, i| {
249252 const field_name = comptime std.fmt.comptimePrint("{d}", .{i + 2});
250 @field(args, field_name) = resolveArg(arg, data, ctx);
253 @field(args, field_name) = try resolveArg(arg, alloc, data, ctx, opts);
251254 }
252255 const repvalue = astgen.Value{ .replacement = .{ .arms = &.{"this"}, .raw = v.raw } };
253256 try @call(.auto, func, args);
......@@ -270,7 +273,7 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d
270273 };
271274 inline for (v.args, 0..) |arg, i| {
272275 const field_name = comptime std.fmt.comptimePrint("{d}", .{i});
273 @field(args[3], field_name) = resolveArg(arg, data, ctx);
276 @field(args[3], field_name) = try resolveArg(arg, alloc, data, ctx, opts);
274277 }
275278 const repvalue = astgen.Value{ .replacement = .{ .arms = &.{"this"}, .raw = v.raw } };
276279 try @call(.auto, func, args);
......@@ -293,13 +296,21 @@ pub const DoOptions = struct {
293296 Ctx: type,
294297 indent: usize,
295298 flag1: bool,
299 escaped: bool = true,
296300};
297301
298fn resolveArg(comptime arg: astgen.Arg, data: anytype, ctx: anytype) ResolveArg(arg, @TypeOf(data), @TypeOf(ctx)) {
302fn resolveArg(comptime arg: astgen.Arg, alloc: std.mem.Allocator, data: anytype, ctx: anytype, comptime opts: DoOptions) !ResolveArg(arg, @TypeOf(data), @TypeOf(ctx)) {
299303 return switch (arg) {
300304 .plain => |av| av[1 .. av.len - 1],
301305 .lookup => |av| if (comptime std.mem.eql(u8, av[0], "this")) search(av[1..], data) else search(av, ctx),
302306 .int => |av| av,
307 .value => |av| {
308 var list = std.ArrayList(u8).init(alloc);
309 comptime var newopts = opts;
310 newopts.escaped = false;
311 try do(alloc, list.writer(), astgen.Value{ .body = av }, data, ctx, newopts);
312 return list.items;
313 },
303314 };
304315}
305316
......@@ -308,6 +319,7 @@ fn ResolveArg(comptime arg: astgen.Arg, comptime This: type, comptime Ctx: type)
308319 .plain => string,
309320 .lookup => |av| if (comptime std.mem.eql(u8, av[0], "this")) FieldSearch(This, av[1..]) else FieldSearch(Ctx, av),
310321 .int => u64,
322 .value => string,
311323 };
312324}
313325