authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2021-08-08 21:35:35 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2021-08-08 21:35:35 -07:00
log10eb03e0c2a8597754a05f56c6b511f97c714a6a
treece40f581d6dc4b2c2743397753d7d421a9d40240
parent97dee90956930f7c9e8dbe652c36e543c416e3a3

add support for `<else>` statements in `#if` and `#ifnot`


2 files changed, 25 insertions(+), 10 deletions(-)

src/astgen.zig+14-1
......@@ -31,6 +31,7 @@ pub const Block = struct {
3131 name: Type,
3232 args: []const []const string,
3333 body: []const Value,
34 bttm: []const Value,
3435
3536 pub const Type = enum {
3637 each,
......@@ -134,8 +135,19 @@ const Parser = struct {
134135 if (std.meta.stringToEnum(Block.Type, w)) |name| {
135136 const args = self.doArgs();
136137 var children: []const Value = &.{};
138 var bottom: []const Value = &.{};
139 var top = true;
137140 while (!self.tryEatSymbol("/")) {
138 children = children ++ &[_]Value{self.doValue()};
141 if (self.tryEatSymbol("<")) {
142 std.debug.assert(std.mem.eql(u8, "else", self.eat(.word)));
143 self.eatSymbol(">");
144 top = false;
145 }
146 if (top) {
147 children = children ++ &[_]Value{self.doValue()};
148 } else {
149 bottom = bottom ++ &[_]Value{self.doValue()};
150 }
139151 }
140152 std.debug.assert(std.mem.eql(u8, @tagName(name), self.eat(.word)));
141153 self.eatSymbol("/");
......@@ -143,6 +155,7 @@ const Parser = struct {
143155 .name = name,
144156 .args = args,
145157 .body = children,
158 .bttm = bottom,
146159 } };
147160 }
148161 return Value{ .function = .{
src/lib.zig+11-9
......@@ -14,7 +14,7 @@ const tokenize = @import("./tokenize.zig");
1414const astgen = @import("./astgen.zig");
1515
1616pub fn parse(comptime input: []const u8) astgen.Value {
17 return astgen.Value{ .element = astgen.do(tokenize.do(input, &.{ '[', '=', ']', '(', ')', '{', '}', '#', '/', '.' })) };
17 return astgen.Value{ .element = astgen.do(tokenize.do(input, &.{ '[', '=', ']', '(', ')', '{', '}', '#', '/', '.', '<', '>' })) };
1818}
1919
2020pub fn compile(writer: anytype, comptime value: astgen.Value, data: anytype) !void {
......@@ -83,20 +83,22 @@ fn do(writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype
8383 .@"if" => {
8484 comptime assertEqual(v.args.len, 1);
8585 const x = search(v.args[0], data);
86 switch (@typeInfo(@TypeOf(x))) {
87 .Bool => if (x) try do(writer, body, data, ctx, indent, flag1),
88 .Optional => if (x) |_| try do(writer, body, data, ctx, indent, flag1),
86 const content = switch (@typeInfo(@TypeOf(x))) {
87 .Bool => if (x) v.body else v.bttm,
88 .Optional => if (x) |_| v.body else v.bttm,
8989 else => unreachable,
90 }
90 };
91 try do(writer, body, content, ctx, indent, flag1);
9192 },
9293 .ifnot => {
9394 comptime assertEqual(v.args.len, 1);
9495 const x = search(v.args[0], data);
95 switch (@typeInfo(@TypeOf(x))) {
96 .Bool => if (x) {} else try do(writer, body, data, ctx, indent, flag1),
97 .Optional => if (x) |_| {} else try do(writer, body, data, ctx, indent, flag1),
96 const content = switch (@typeInfo(@TypeOf(x))) {
97 .Bool => if (x) v.bttm else v.body,
98 .Optional => if (x) |_| v.bttm else v.body,
9899 else => unreachable,
99 }
100 };
101 try do(writer, body, content, ctx, indent, flag1);
100102 },
101103 .ifequal => {
102104 comptime assertEqual(v.args.len, 2);