Add slice builtin
This commit is contained in:
parent
0f5751e7ed
commit
1269aeeac1
2 changed files with 44 additions and 4 deletions
|
@ -8,11 +8,13 @@ pub fn main() !void {
|
|||
@embedFile("./test.tmp.html"),
|
||||
.{
|
||||
.community = .{ .name = "<abcd>" },
|
||||
.foo = [_][]const u8{ "5", "4", "3", "2", "1" },
|
||||
.baz = [_][]const []const u8{
|
||||
.foo = &[_][]const u8{ "5", "4", "3", "2", "1" },
|
||||
.baz = &[_][]const []const u8{
|
||||
&.{ "5", "4", "3", "2", "1" },
|
||||
&.{ "5", "4", "3", "2", "1" },
|
||||
},
|
||||
.start = 1,
|
||||
.end = 3,
|
||||
.bar = .{ .x = "x" },
|
||||
.qux = false,
|
||||
.quxx = true,
|
||||
|
@ -236,7 +238,7 @@ fn deref(arg: anytype, comptime names: []const DerefDecl) DerefError!Deref(@Type
|
|||
}
|
||||
}
|
||||
|
||||
const ExpressionError = DerefError;
|
||||
const ExpressionError = error{IndexOutOfBounds} || DerefError;
|
||||
|
||||
fn EvaluateExpression(
|
||||
comptime expression: Expression,
|
||||
|
@ -251,6 +253,7 @@ fn EvaluateExpression(
|
|||
.equals => bool,
|
||||
.builtin => |call| switch (call.*) {
|
||||
.isTag => bool,
|
||||
.slice => |sl| []const std.meta.Elem(EvaluateExpression(sl.iterable, Args, Captures, Context)),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -280,6 +283,15 @@ fn evaluateExpression(
|
|||
const val = try evaluateExpression(hdr.expression, args, captures, context);
|
||||
return std.meta.isTag(val, hdr.tag);
|
||||
},
|
||||
.slice => |sl| {
|
||||
const iterable = try evaluateExpression(sl.iterable, args, captures, context);
|
||||
const start = try evaluateExpression(sl.start, args, captures, context);
|
||||
const end = try evaluateExpression(sl.end, args, captures, context);
|
||||
|
||||
if (comptime std.meta.trait.is(.Array)(@TypeOf(iterable))) @compileError("Cannot slice an array, pass a slice or pointer to array instead");
|
||||
if (start > iterable.len or end > iterable.len) return error.IndexOutOfBounds;
|
||||
return iterable[start..end];
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -635,7 +647,7 @@ fn parseBuiltin(comptime tokens: ControlTokenIter) ParseResult(ControlTokenIter,
|
|||
const call = switch (builtin) {
|
||||
.isTag => blk: {
|
||||
const expr = parseExpression(iter);
|
||||
iter = expr.new_iter;
|
||||
iter = skipWhitespace(expr.new_iter);
|
||||
expectToken(iter.next(), .comma);
|
||||
iter = skipWhitespace(iter);
|
||||
const tag = iter.next();
|
||||
|
@ -647,6 +659,26 @@ fn parseBuiltin(comptime tokens: ControlTokenIter) ParseResult(ControlTokenIter,
|
|||
},
|
||||
};
|
||||
},
|
||||
.slice => blk: {
|
||||
const expr = parseExpression(iter);
|
||||
iter = skipWhitespace(expr.new_iter);
|
||||
expectToken(iter.next(), .comma);
|
||||
iter = skipWhitespace(iter);
|
||||
const start = parseExpression(iter);
|
||||
iter = skipWhitespace(start.new_iter);
|
||||
expectToken(iter.next(), .comma);
|
||||
iter = skipWhitespace(iter);
|
||||
const end = parseExpression(iter);
|
||||
iter = skipWhitespace(end.new_iter);
|
||||
|
||||
break :blk .{
|
||||
.slice = .{
|
||||
.iterable = expr.item,
|
||||
.start = start.item,
|
||||
.end = end.item,
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
iter = skipWhitespace(iter);
|
||||
expectToken(iter.next(), .close_paren);
|
||||
|
@ -1165,6 +1197,7 @@ const EndKeyword = enum {
|
|||
|
||||
const Builtin = enum {
|
||||
isTag,
|
||||
slice,
|
||||
};
|
||||
|
||||
const BuiltinCall = union(Builtin) {
|
||||
|
@ -1172,6 +1205,11 @@ const BuiltinCall = union(Builtin) {
|
|||
tag: []const u8,
|
||||
expression: Expression,
|
||||
},
|
||||
slice: struct {
|
||||
iterable: Expression,
|
||||
start: Expression,
|
||||
end: Expression,
|
||||
},
|
||||
};
|
||||
|
||||
const ControlToken = union(enum) {
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
neither
|
||||
{=/if}
|
||||
|
||||
sliced: {#for @slice(.foo, .start, .end) |$s|}{$s}, {/for}
|
||||
|
||||
format: {#format "s" .x}
|
||||
|
||||
{#switch .snap case foo =}
|
||||
|
|
Loading…
Reference in a new issue