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"),
|
@embedFile("./test.tmp.html"),
|
||||||
.{
|
.{
|
||||||
.community = .{ .name = "<abcd>" },
|
.community = .{ .name = "<abcd>" },
|
||||||
.foo = [_][]const u8{ "5", "4", "3", "2", "1" },
|
.foo = &[_][]const u8{ "5", "4", "3", "2", "1" },
|
||||||
.baz = [_][]const []const u8{
|
.baz = &[_][]const []const u8{
|
||||||
&.{ "5", "4", "3", "2", "1" },
|
&.{ "5", "4", "3", "2", "1" },
|
||||||
&.{ "5", "4", "3", "2", "1" },
|
&.{ "5", "4", "3", "2", "1" },
|
||||||
},
|
},
|
||||||
|
.start = 1,
|
||||||
|
.end = 3,
|
||||||
.bar = .{ .x = "x" },
|
.bar = .{ .x = "x" },
|
||||||
.qux = false,
|
.qux = false,
|
||||||
.quxx = true,
|
.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(
|
fn EvaluateExpression(
|
||||||
comptime expression: Expression,
|
comptime expression: Expression,
|
||||||
|
@ -251,6 +253,7 @@ fn EvaluateExpression(
|
||||||
.equals => bool,
|
.equals => bool,
|
||||||
.builtin => |call| switch (call.*) {
|
.builtin => |call| switch (call.*) {
|
||||||
.isTag => bool,
|
.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);
|
const val = try evaluateExpression(hdr.expression, args, captures, context);
|
||||||
return std.meta.isTag(val, hdr.tag);
|
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) {
|
const call = switch (builtin) {
|
||||||
.isTag => blk: {
|
.isTag => blk: {
|
||||||
const expr = parseExpression(iter);
|
const expr = parseExpression(iter);
|
||||||
iter = expr.new_iter;
|
iter = skipWhitespace(expr.new_iter);
|
||||||
expectToken(iter.next(), .comma);
|
expectToken(iter.next(), .comma);
|
||||||
iter = skipWhitespace(iter);
|
iter = skipWhitespace(iter);
|
||||||
const tag = iter.next();
|
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);
|
iter = skipWhitespace(iter);
|
||||||
expectToken(iter.next(), .close_paren);
|
expectToken(iter.next(), .close_paren);
|
||||||
|
@ -1165,6 +1197,7 @@ const EndKeyword = enum {
|
||||||
|
|
||||||
const Builtin = enum {
|
const Builtin = enum {
|
||||||
isTag,
|
isTag,
|
||||||
|
slice,
|
||||||
};
|
};
|
||||||
|
|
||||||
const BuiltinCall = union(Builtin) {
|
const BuiltinCall = union(Builtin) {
|
||||||
|
@ -1172,6 +1205,11 @@ const BuiltinCall = union(Builtin) {
|
||||||
tag: []const u8,
|
tag: []const u8,
|
||||||
expression: Expression,
|
expression: Expression,
|
||||||
},
|
},
|
||||||
|
slice: struct {
|
||||||
|
iterable: Expression,
|
||||||
|
start: Expression,
|
||||||
|
end: Expression,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const ControlToken = union(enum) {
|
const ControlToken = union(enum) {
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
neither
|
neither
|
||||||
{=/if}
|
{=/if}
|
||||||
|
|
||||||
|
sliced: {#for @slice(.foo, .start, .end) |$s|}{$s}, {/for}
|
||||||
|
|
||||||
format: {#format "s" .x}
|
format: {#format "s" .x}
|
||||||
|
|
||||||
{#switch .snap case foo =}
|
{#switch .snap case foo =}
|
||||||
|
|
Loading…
Reference in a new issue