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 iterable = try evaluateExpression(loop.header.iterable, args, captures, context);
|
||||||
const subtemplate = loop.subtemplate;
|
const subtemplate = loop.subtemplate;
|
||||||
//std.log.debug("{any}", .{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(
|
try executeTemplate(
|
||||||
writer,
|
writer,
|
||||||
templates,
|
templates,
|
||||||
subtemplate,
|
subtemplate,
|
||||||
args,
|
args,
|
||||||
addCapture(captures, loop.header.capture, v),
|
with_idx_capture,
|
||||||
context,
|
context,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -227,7 +229,7 @@ fn EvaluateExpression(
|
||||||
const T = EvaluateExpression(expr.container, Args, Captures, Context);
|
const T = EvaluateExpression(expr.container, Args, Captures, Context);
|
||||||
for (@typeInfo(T).Struct.fields) |f| {
|
for (@typeInfo(T).Struct.fields) |f| {
|
||||||
if (std.mem.eql(u8, expr.field, f.name)) return f.field_type;
|
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,
|
.equals => bool,
|
||||||
.builtin => |call| switch (call.*) {
|
.builtin => |call| switch (call.*) {
|
||||||
|
@ -875,32 +877,21 @@ fn endControlBlock(comptime tokens: ControlTokenIter) ControlTokenIter {
|
||||||
fn parseForHeader(comptime tokens: ControlTokenIter) ParseResult(ControlTokenIter, ForHeader) {
|
fn parseForHeader(comptime tokens: ControlTokenIter) ParseResult(ControlTokenIter, ForHeader) {
|
||||||
comptime {
|
comptime {
|
||||||
const iterable = parseExpression(tokens);
|
const iterable = parseExpression(tokens);
|
||||||
var iter = iterable.new_iter;
|
var iter = skipWhitespace(iterable.new_iter);
|
||||||
|
|
||||||
iter = skipWhitespace(iter);
|
const captures = tryParseCapture(iter) orelse {
|
||||||
{
|
@compileLog(iter.row);
|
||||||
const token = iter.next() orelse @compileError("Unexpected end of template");
|
@compileError("Expected capture");
|
||||||
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 token = iter.next() orelse @compileError("Unexpected end of template");
|
if (captures.item.len == 0 or captures.item.len > 2) @compileError("Expected 1 or 2 captures");
|
||||||
if (token != .pipe) @compileError("Unexpected token");
|
|
||||||
}
|
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.new_iter = iter,
|
.new_iter = captures.new_iter,
|
||||||
.item = .{
|
.item = .{
|
||||||
.iterable = iterable.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) {
|
fn tryParseCapture(comptime tokens: ControlTokenIter) ?ParseResult(ControlTokenIter, []const []const u8) {
|
||||||
comptime {
|
comptime {
|
||||||
var iter = tokens;
|
var iter = skipWhitespace(tokens);
|
||||||
|
|
||||||
iter = skipWhitespace(iter);
|
|
||||||
if ((iter.next() orelse return null) != .pipe) return null;
|
if ((iter.next() orelse return null) != .pipe) return null;
|
||||||
var captures: []const []const u8 = &.{};
|
var captures: []const []const u8 = &.{};
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -1115,7 +1105,8 @@ const For = struct {
|
||||||
|
|
||||||
const ForHeader = struct {
|
const ForHeader = struct {
|
||||||
iterable: Expression,
|
iterable: Expression,
|
||||||
capture: []const u8,
|
item_capture: []const u8,
|
||||||
|
idx_capture: ?[]const u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
const If = struct {
|
const If = struct {
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
{$b}:
|
{$b}:
|
||||||
{= /for =}
|
{= /for =}
|
||||||
{= /for}
|
{= /for}
|
||||||
|
{#for .baz |$f, $i| =}{$i}{/for}
|
||||||
{#if .quxx == .quxx2}eql{#else}neq{/if}
|
{#if .quxx == .quxx2}eql{#else}neq{/if}
|
||||||
{#if .quxx == .qux}eql{#else}neq{/if}
|
{#if .quxx == .qux}eql{#else}neq{/if}
|
||||||
{#if @isTag(.snap, foo)}foo{/if}
|
{#if @isTag(.snap, foo)}foo{/if}
|
||||||
|
|
Loading…
Reference in a new issue