| ... | @@ -17,14 +17,14 @@ pub fn parse(comptime input: []const u8) astgen.Value { | ... | @@ -17,14 +17,14 @@ pub 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, &.{ '[', '=', ']', '(', ')', '{', '}', '#', '/', '.', '<', '>' })) }; |
| 18 | } | 18 | } |
| 19 | | 19 | |
| 20 | pub fn compile(writer: anytype, comptime value: astgen.Value, data: anytype) !void { | 20 | pub fn compile(alloc: *std.mem.Allocator, writer: anytype, comptime value: astgen.Value, data: anytype) !void { |
| 21 | try writer.writeAll("<!DOCTYPE html>\n"); | 21 | try writer.writeAll("<!DOCTYPE html>\n"); |
| 22 | try do(writer, value, data, data, 0, false); | 22 | try do(alloc, writer, value, data, data, 0, false); |
| 23 | try writer.writeAll("\n"); | 23 | try writer.writeAll("\n"); |
| 24 | } | 24 | } |
| 25 | | 25 | |
| 26 | fn do(writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype, indent: usize, flag1: bool) anyerror!void { | 26 | fn do(alloc: *std.mem.Allocator, writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype, indent: usize, flag1: bool) anyerror!void { |
| 27 | switch (value) { | 27 | switch (comptime value) { |
| 28 | .element => |v| { | 28 | .element => |v| { |
| 29 | const hastext = for (v.children) |x| { | 29 | const hastext = for (v.children) |x| { |
| 30 | if (x == .string or x == .replacement) break true; | 30 | if (x == .string or x == .replacement) break true; |
| ... | @@ -56,7 +56,7 @@ fn do(writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype | ... | @@ -56,7 +56,7 @@ fn do(writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype |
| 56 | | 56 | |
| 57 | if (!hastext) try writer.writeAll("\n"); | 57 | if (!hastext) try writer.writeAll("\n"); |
| 58 | inline for (v.children) |it| { | 58 | inline for (v.children) |it| { |
| 59 | try do(writer, it, data, ctx, indent + 1, !hastext); | 59 | try do(alloc, writer, it, data, ctx, indent + 1, !hastext); |
| 60 | } | 60 | } |
| 61 | if (!hastext) for (range(indent)) |_| try writer.writeAll(" "); | 61 | if (!hastext) for (range(indent)) |_| try writer.writeAll(" "); |
| 62 | try writer.print("</{s}>", .{v.name}); | 62 | try writer.print("</{s}>", .{v.name}); |
| ... | @@ -97,39 +97,37 @@ fn do(writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype | ... | @@ -97,39 +97,37 @@ fn do(writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype |
| 97 | switch (v.name) { | 97 | switch (v.name) { |
| 98 | .each => { | 98 | .each => { |
| 99 | comptime assertEqual(v.args.len, 1); | 99 | comptime assertEqual(v.args.len, 1); |
| 100 | for (x) |item| try do(writer, body, item, ctx, indent, flag1); | 100 | for (x) |item| try do(alloc, writer, body, item, ctx, indent, flag1); |
| 101 | }, | 101 | }, |
| 102 | .@"if" => { | 102 | .@"if" => { |
| 103 | comptime assertEqual(v.args.len, 1); | 103 | comptime assertEqual(v.args.len, 1); |
| 104 | switch (TI) { | 104 | switch (comptime TI) { |
| 105 | .Bool => try doif(writer, body, bottom, data, ctx, indent, flag1, x, true), | 105 | .Bool => try doif(alloc, writer, body, bottom, data, ctx, indent, flag1, x), |
| 106 | .Optional => try docap(writer, body, bottom, data, ctx, indent, flag1, x, true), | 106 | .Optional => try docap(alloc, writer, body, bottom, data, ctx, indent, flag1, x), |
| 107 | else => unreachable, | | |
| 108 | } | 107 | } |
| 109 | }, | 108 | }, |
| 110 | .ifnot => { | 109 | .ifnot => { |
| 111 | comptime assertEqual(v.args.len, 1); | 110 | comptime assertEqual(v.args.len, 1); |
| 112 | switch (TI) { | 111 | switch (comptime TI) { |
| 113 | .Bool => try doif(writer, body, bottom, data, ctx, indent, flag1, x, false), | 112 | .Bool => try doif(alloc, writer, body, bottom, data, ctx, indent, flag1, !x), |
| 114 | .Optional => try docap(writer, body, bottom, data, ctx, indent, flag1, x, false), | 113 | .Optional => try docap(alloc, writer, body, bottom, data, ctx, indent, flag1, !x), |
| 115 | else => unreachable, | | |
| 116 | } | 114 | } |
| 117 | }, | 115 | }, |
| 118 | .ifequal => { | 116 | .ifequal => { |
| 119 | comptime assertEqual(v.args.len, 2); | 117 | comptime assertEqual(v.args.len, 2); |
| 120 | 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); | 118 | 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); |
| 121 | try doif(writer, body, bottom, data, ctx, indent, flag1, x == y, true); | 119 | try doif(alloc, writer, body, bottom, data, ctx, indent, flag1, x == y); |
| 122 | }, | 120 | }, |
| 123 | .ifnotequal => { | 121 | .ifnotequal => { |
| 124 | comptime assertEqual(v.args.len, 2); | 122 | comptime assertEqual(v.args.len, 2); |
| 125 | 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); | 123 | 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); |
| 126 | try doif(writer, body, bottom, data, ctx, indent, flag1, x != y, true); | 124 | try doif(alloc, writer, body, bottom, data, ctx, indent, flag1, x != y); |
| 127 | }, | 125 | }, |
| 128 | } | 126 | } |
| 129 | }, | 127 | }, |
| 130 | .body => |v| { | 128 | .body => |v| { |
| 131 | inline for (v) |val| { | 129 | inline for (v) |val| { |
| 132 | try do(writer, val, data, ctx, indent, flag1); | 130 | try do(alloc, writer, val, data, ctx, indent, flag1); |
| 133 | } | 131 | } |
| 134 | }, | 132 | }, |
| 135 | else => unreachable, | 133 | else => unreachable, |
| ... | @@ -199,18 +197,18 @@ fn contains(haystack: []const []const u8, needle: []const u8) bool { | ... | @@ -199,18 +197,18 @@ fn contains(haystack: []const []const u8, needle: []const u8) bool { |
| 199 | return false; | 197 | return false; |
| 200 | } | 198 | } |
| 201 | | 199 | |
| 202 | fn doif(writer: anytype, comptime top: astgen.Value, comptime bottom: astgen.Value, data: anytype, ctx: anytype, indent: usize, flag1: bool, flag2: bool, flag3: bool) anyerror!void { | 200 | fn 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 { |
| 203 | if (flag2 == flag3) { | 201 | if (flag2) { |
| 204 | try do(writer, top, data, ctx, indent, flag1); | 202 | try do(alloc, writer, top, data, ctx, indent, flag1); |
| 205 | } else { | 203 | } else { |
| 206 | try do(writer, bottom, data, ctx, indent, flag1); | 204 | try do(alloc, writer, bottom, data, ctx, indent, flag1); |
| 207 | } | 205 | } |
| 208 | } | 206 | } |
| 209 | | 207 | |
| 210 | fn docap(writer: anytype, comptime top: astgen.Value, comptime bottom: astgen.Value, data: anytype, ctx: anytype, indent: usize, flag1: bool, flag2: bool, flag3: bool) anyerror!void { | 208 | fn docap(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 { |
| 211 | if (flag2 == flag3) { | 209 | if (flag2) |_| { |
| 212 | try do(writer, top, data, ctx, indent, flag1); | 210 | try do(alloc, writer, top, data, ctx, indent, flag1); |
| 213 | } else { | 211 | } else { |
| 214 | try do(writer, bottom, data, ctx, indent, flag1); | 212 | try do(alloc, writer, bottom, data, ctx, indent, flag1); |
| 215 | } | 213 | } |
| 216 | } | 214 | } |