Add loop index capture support

This commit is contained in:
jaina heartles 2022-12-14 02:35:23 -08:00
parent f2a23db588
commit 73ba42d2d5
2 changed files with 18 additions and 26 deletions

View File

@ -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 {

View File

@ -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}