Add loop index capture support
This commit is contained in:
parent
f2a23db588
commit
73ba42d2d5
2 changed files with 18 additions and 26 deletions
|
@ -82,13 +82,15 @@ fn executeStatement(
|
|||
const iterable = try evaluateExpression(loop.header.iterable, args, captures, context);
|
||||
const subtemplate = loop.subtemplate;
|
||||
//std.log.debug("{any}", .{subtemplate});
|
||||
for (iterable) |v| {
|
||||
for (iterable) |v, i| {
|
||||
const with_item_capture = addCapture(captures, loop.header.item_capture, v);
|
||||
const with_idx_capture = if (comptime loop.header.idx_capture) |name| addCapture(with_item_capture, name, i) else with_item_capture;
|
||||
try executeTemplate(
|
||||
writer,
|
||||
templates,
|
||||
subtemplate,
|
||||
args,
|
||||
addCapture(captures, loop.header.capture, v),
|
||||
with_idx_capture,
|
||||
context,
|
||||
);
|
||||
}
|
||||
|
@ -227,7 +229,7 @@ fn EvaluateExpression(
|
|||
const T = EvaluateExpression(expr.container, Args, Captures, Context);
|
||||
for (@typeInfo(T).Struct.fields) |f| {
|
||||
if (std.mem.eql(u8, expr.field, f.name)) return f.field_type;
|
||||
}
|
||||
} else @compileError("Field " ++ expr.field ++ " does not exist on type " ++ @typeName(T));
|
||||
},
|
||||
.equals => bool,
|
||||
.builtin => |call| switch (call.*) {
|
||||
|
@ -875,32 +877,21 @@ fn endControlBlock(comptime tokens: ControlTokenIter) ControlTokenIter {
|
|||
fn parseForHeader(comptime tokens: ControlTokenIter) ParseResult(ControlTokenIter, ForHeader) {
|
||||
comptime {
|
||||
const iterable = parseExpression(tokens);
|
||||
var iter = iterable.new_iter;
|
||||
var iter = skipWhitespace(iterable.new_iter);
|
||||
|
||||
iter = skipWhitespace(iter);
|
||||
{
|
||||
const token = iter.next() orelse @compileError("Unexpected end of template");
|
||||
if (token != .pipe) @compileError("Unexpected token");
|
||||
}
|
||||
{
|
||||
const token = iter.next() orelse @compileError("Unexpected end of template");
|
||||
if (token != .dollar) @compileError("Unexpected token");
|
||||
}
|
||||
const capture = blk: {
|
||||
const token = iter.next() orelse @compileError("Unexpected end of template");
|
||||
if (token != .text) @compileError("Unexpected token");
|
||||
break :blk token.text;
|
||||
const captures = tryParseCapture(iter) orelse {
|
||||
@compileLog(iter.row);
|
||||
@compileError("Expected capture");
|
||||
};
|
||||
{
|
||||
const token = iter.next() orelse @compileError("Unexpected end of template");
|
||||
if (token != .pipe) @compileError("Unexpected token");
|
||||
}
|
||||
|
||||
if (captures.item.len == 0 or captures.item.len > 2) @compileError("Expected 1 or 2 captures");
|
||||
|
||||
return .{
|
||||
.new_iter = iter,
|
||||
.new_iter = captures.new_iter,
|
||||
.item = .{
|
||||
.iterable = iterable.item,
|
||||
.capture = capture,
|
||||
.item_capture = captures.item[0],
|
||||
.idx_capture = if (captures.item.len == 2) captures.item[1] else null,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -908,9 +899,8 @@ fn parseForHeader(comptime tokens: ControlTokenIter) ParseResult(ControlTokenIte
|
|||
|
||||
fn tryParseCapture(comptime tokens: ControlTokenIter) ?ParseResult(ControlTokenIter, []const []const u8) {
|
||||
comptime {
|
||||
var iter = tokens;
|
||||
var iter = skipWhitespace(tokens);
|
||||
|
||||
iter = skipWhitespace(iter);
|
||||
if ((iter.next() orelse return null) != .pipe) return null;
|
||||
var captures: []const []const u8 = &.{};
|
||||
while (true) {
|
||||
|
@ -1115,7 +1105,8 @@ const For = struct {
|
|||
|
||||
const ForHeader = struct {
|
||||
iterable: Expression,
|
||||
capture: []const u8,
|
||||
item_capture: []const u8,
|
||||
idx_capture: ?[]const u8,
|
||||
};
|
||||
|
||||
const If = struct {
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
{$b}:
|
||||
{= /for =}
|
||||
{= /for}
|
||||
{#for .baz |$f, $i| =}{$i}{/for}
|
||||
{#if .quxx == .quxx2}eql{#else}neq{/if}
|
||||
{#if .quxx == .qux}eql{#else}neq{/if}
|
||||
{#if @isTag(.snap, foo)}foo{/if}
|
||||
|
|
Loading…
Reference in a new issue