authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2023-06-15 18:54:07 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2023-06-15 18:54:07 -07:00
log82747c72ddaa89c023e454dd4a4cecd4773d5433
treedbe0380f180473831c0e203404e11caddf0989da
parent08ae93da6fde7392d66bac2c34c4a4f530fe7696

allow passing plain strings as args to blocks and functions


2 files changed, 39 insertions(+), 17 deletions(-)

src/astgen.zig+20-12
......@@ -35,7 +35,7 @@ pub const Replacement = struct {
3535pub const Block = struct {
3636 name: Type,
3737 func: ?string,
38 args: []const []const string,
38 args: []const Arg,
3939 body: Body,
4040 bttm: Body,
4141
......@@ -53,7 +53,12 @@ pub const Body = []const Value;
5353pub const Fn = struct {
5454 name: string,
5555 raw: bool,
56 args: []const []const string,
56 args: []const Arg,
57};
58
59pub const Arg = union(enum) {
60 lookup: []const string,
61 plain: string,
5762};
5863
5964//
......@@ -93,6 +98,7 @@ const Parser = struct {
9398 }
9499
95100 fn tryEatSymbol(comptime self: *Parser, comptime needle: string) bool {
101 if (self.index >= self.tokens.len) return false;
96102 switch (self.tokens[self.index].data) {
97103 .symbol => |sym| {
98104 if (std.mem.eql(u8, sym, needle)) {
......@@ -194,23 +200,25 @@ const Parser = struct {
194200 return Value{ .element = self.doElement() };
195201 }
196202
197 pub fn doArgs(comptime self: *Parser) []const []const string {
198 var ret: []const []const string = &.{};
199 var temp: []const string = &.{self.eat(.word)};
203 pub fn doArgs(comptime self: *Parser) []const Arg {
204 var ret: []const Arg = &.{};
205 var temp: []const string = &.{};
200206 while (!self.tryEatSymbol("}")) {
207 if (self.nextIs(.string)) {
208 ret = ret ++ &[_]Arg{.{ .plain = self.eat(.string) }};
209 continue;
210 }
211 if (temp.len == 0 and self.nextIs(.word)) {
212 temp = temp ++ &[_]string{self.eat(.word)};
213 }
201214 if (self.tryEatSymbol(".")) {
202215 temp = temp ++ &[_]string{self.eat(.word)};
203216 } else {
204 ret = ret ++ &[_][]const string{temp};
217 ret = ret ++ &[_]Arg{.{ .lookup = temp }};
205218 temp = &.{};
206 if (comptime self.nextIs(.string)) {
207 ret = ret ++ &[_][]const string{&.{self.eat(.string)}};
208 } else {
209 temp = &.{self.eat(.word)};
210 }
211219 }
212220 }
213 if (temp.len > 0) ret = ret ++ &[_][]const string{temp};
221 if (temp.len > 0) ret = ret ++ &[_]Arg{.{ .lookup = temp }};
214222 return ret;
215223 }
216224
src/lib.zig+19-5
......@@ -127,7 +127,7 @@ inline fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.V
127127 .block => |v| {
128128 const body = astgen.Value{ .body = v.body };
129129 const bottom = astgen.Value{ .body = v.bttm };
130 const x = if (comptime std.mem.eql(u8, v.args[0][0], "this")) search(v.args[0][1..], data) else search(v.args[0], ctx);
130 const x = resolveArg(v.args[0], data, ctx);
131131 const T = @TypeOf(x);
132132 const TI = @typeInfo(T);
133133 switch (v.name) {
......@@ -167,7 +167,7 @@ inline fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.V
167167 },
168168 .ifequal => {
169169 comptime assertEqual(v.args.len, 2);
170 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);
170 const y = resolveArg(v.args[1], data, ctx);
171171 if (@typeInfo(@TypeOf(x)) == .Enum and comptime std.meta.trait.isZigString(@TypeOf(y))) {
172172 return try doif(alloc, writer, body, bottom, data, ctx, opts, std.mem.eql(u8, @tagName(x), y));
173173 }
......@@ -175,7 +175,7 @@ inline fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.V
175175 },
176176 .ifnotequal => {
177177 comptime assertEqual(v.args.len, 2);
178 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);
178 const y = resolveArg(v.args[1], data, ctx);
179179 if (@typeInfo(@TypeOf(x)) == .Enum and comptime std.meta.trait.isZigString(@TypeOf(y))) {
180180 return try doif(alloc, writer, body, bottom, data, ctx, opts, std.mem.eql(u8, @tagName(x), y));
181181 }
......@@ -201,7 +201,7 @@ inline fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.V
201201 args.@"1" = list.writer();
202202 inline for (v.args, 0..) |arg, i| {
203203 const field_name = comptime std.fmt.comptimePrint("{d}", .{i + 2});
204 @field(args, field_name) = if (comptime std.mem.eql(u8, arg[0], "this")) search(arg[1..], data) else search(arg, ctx);
204 @field(args, field_name) = resolveArg(arg, data, ctx);
205205 }
206206 const repvalue = astgen.Value{ .replacement = .{ .arms = &.{"this"}, .raw = v.raw } };
207207 try @call(.auto, func, args);
......@@ -223,7 +223,7 @@ inline fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.V
223223 };
224224 inline for (v.args, 0..) |arg, i| {
225225 const field_name = comptime std.fmt.comptimePrint("{d}", .{i});
226 @field(args[3], field_name) = if (comptime std.mem.eql(u8, arg[0], "this")) search(arg[1..], data) else search(arg, ctx);
226 @field(args[3], field_name) = resolveArg(arg, data, ctx);
227227 }
228228 const repvalue = astgen.Value{ .replacement = .{ .arms = &.{"this"}, .raw = v.raw } };
229229 try @call(.auto, func, args);
......@@ -248,6 +248,20 @@ pub const DoOptions = struct {
248248 flag1: bool,
249249};
250250
251fn resolveArg(comptime arg: astgen.Arg, data: anytype, ctx: anytype) ResolveArg(arg, @TypeOf(data), @TypeOf(ctx)) {
252 return switch (arg) {
253 .plain => |av| av[1 .. av.len - 1],
254 .lookup => |av| if (comptime std.mem.eql(u8, av[0], "this")) search(av[1..], data) else search(av, ctx),
255 };
256}
257
258fn ResolveArg(comptime arg: astgen.Arg, comptime This: type, comptime Ctx: type) type {
259 return switch (arg) {
260 .plain => string,
261 .lookup => |av| if (comptime std.mem.eql(u8, av[0], "this")) FieldSearch(This, av[1..]) else FieldSearch(Ctx, av),
262 };
263}
264
251265fn search(comptime args: []const string, ctx: anytype) FieldSearch(@TypeOf(ctx), args) {
252266 if (args.len == 0) return ctx;
253267 if (args[0][0] == '"') return std.mem.trim(u8, args[0], "\"");