Compare commits
No commits in common. "8c0548fc741522016fb7953dbfc7994a230593fd" and "9dabc237e0cf6e08c97d40fe037a32149bf77710" have entirely different histories.
8c0548fc74
...
9dabc237e0
3 changed files with 18 additions and 71 deletions
|
@ -227,7 +227,7 @@ pub const Response = struct {
|
||||||
defer stream.close();
|
defer stream.close();
|
||||||
|
|
||||||
const writer = stream.writer();
|
const writer = stream.writer();
|
||||||
try @import("template").execute(writer, .{}, templ, data);
|
try @import("template").execute(writer, templ, data);
|
||||||
|
|
||||||
try stream.finish();
|
try stream.finish();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,42 +1,36 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
try execute(
|
try execute(std.io.getStdOut().writer(), @embedFile("./test.tmp.html"), .{
|
||||||
std.io.getStdOut().writer(),
|
|
||||||
.{ .test_tmpl = "{.x}" },
|
|
||||||
@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" },
|
||||||
},
|
},
|
||||||
.bar = .{ .x = "x" },
|
|
||||||
.qux = false,
|
.qux = false,
|
||||||
.quxx = true,
|
.quxx = true,
|
||||||
},
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute(writer: anytype, comptime other_templates: anytype, comptime template: []const u8, args: anytype) !void {
|
pub fn execute(writer: anytype, comptime template: []const u8, args: anytype) !void {
|
||||||
@setEvalBranchQuota(@intCast(u32, template.len * 8));
|
@setEvalBranchQuota(@intCast(u32, template.len * 8));
|
||||||
|
|
||||||
const tokens = comptime parseTemplateTokens(ControlTokenIter{ .text = template });
|
const tokens = comptime parseTemplateTokens(ControlTokenIter{ .text = template });
|
||||||
const tmpl = comptime parseTemplate(tokens, 0, .root);
|
const tmpl = comptime parseTemplate(tokens, 0, .root);
|
||||||
try executeTemplate(writer, other_templates, tmpl.items, args, .{});
|
try executeTemplate(writer, tmpl.items, args, .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn executeTemplate(writer: anytype, comptime templates: anytype, comptime items: []const TemplateItem, args: anytype, captures: anytype) !void {
|
fn executeTemplate(writer: anytype, comptime items: []const TemplateItem, args: anytype, captures: anytype) !void {
|
||||||
inline for (items) |it| {
|
inline for (items) |it| {
|
||||||
switch (it) {
|
switch (it) {
|
||||||
.text => |text| try writer.writeAll(text),
|
.text => |text| try writer.writeAll(text),
|
||||||
.statement => |stmt| try executeStatement(writer, templates, stmt, args, captures),
|
.statement => |stmt| try executeStatement(writer, stmt, args, captures),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn executeStatement(writer: anytype, comptime templates: anytype, comptime stmt: Statement, args: anytype, captures: anytype) !void {
|
fn executeStatement(writer: anytype, comptime stmt: Statement, args: anytype, captures: anytype) !void {
|
||||||
switch (stmt) {
|
switch (stmt) {
|
||||||
.expression => |expr| {
|
.expression => |expr| {
|
||||||
const val = evaluateExpression(expr, args, captures);
|
const val = evaluateExpression(expr, args, captures);
|
||||||
|
@ -49,7 +43,6 @@ fn executeStatement(writer: anytype, comptime templates: anytype, comptime stmt:
|
||||||
for (iterable) |v| {
|
for (iterable) |v| {
|
||||||
try executeTemplate(
|
try executeTemplate(
|
||||||
writer,
|
writer,
|
||||||
templates,
|
|
||||||
subtemplate,
|
subtemplate,
|
||||||
args,
|
args,
|
||||||
addCapture(captures, loop.header.capture, v),
|
addCapture(captures, loop.header.capture, v),
|
||||||
|
@ -60,19 +53,14 @@ fn executeStatement(writer: anytype, comptime templates: anytype, comptime stmt:
|
||||||
const condition = evaluateExpression(if_stmt.header.condition, args, captures);
|
const condition = evaluateExpression(if_stmt.header.condition, args, captures);
|
||||||
const subtemplate = if_stmt.subtemplate;
|
const subtemplate = if_stmt.subtemplate;
|
||||||
if (condition) {
|
if (condition) {
|
||||||
try executeTemplate(writer, templates, subtemplate, args, captures);
|
try executeTemplate(writer, subtemplate, args, captures);
|
||||||
} else {
|
} else {
|
||||||
if (if_stmt.else_branch) |branch| switch (branch) {
|
if (if_stmt.else_branch) |branch| switch (branch) {
|
||||||
.@"else" => |subtmpl| try executeTemplate(writer, templates, subtmpl, args, captures),
|
.@"else" => |subtmpl| try executeTemplate(writer, subtmpl, args, captures),
|
||||||
.elif => |elif| try executeStatement(writer, templates, .{ .@"if" = elif.* }, args, captures),
|
.elif => |elif| try executeStatement(writer, .{ .@"if" = elif.* }, args, captures),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.call_template => |call| {
|
|
||||||
const new_template = @field(templates, call.template_name);
|
|
||||||
try execute(writer, templates, new_template, evaluateExpression(call.args, args, captures));
|
|
||||||
//std.log.debug("calling template {s} with arg {any}", .{ call.template_name, call.args });
|
|
||||||
},
|
|
||||||
//else => @compileError("TODO"),
|
//else => @compileError("TODO"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -263,11 +251,6 @@ fn parseTemplate(
|
||||||
break cb
|
break cb
|
||||||
else
|
else
|
||||||
@compileError("Unexpected #else tag"),
|
@compileError("Unexpected #else tag"),
|
||||||
.call_template => |call| {
|
|
||||||
items = items ++ [_]TemplateItem{.{
|
|
||||||
.statement = .{ .call_template = call },
|
|
||||||
}};
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -394,11 +377,6 @@ fn parseControlBlock(comptime tokens: ControlTokenIter) ParseResult(ControlToken
|
||||||
iter = result.new_iter;
|
iter = result.new_iter;
|
||||||
break .{ .elif_header = result.item };
|
break .{ .elif_header = result.item };
|
||||||
},
|
},
|
||||||
.template => {
|
|
||||||
const result = parseCallTemplate(iter);
|
|
||||||
iter = result.new_iter;
|
|
||||||
break .{ .call_template = result.item };
|
|
||||||
},
|
|
||||||
|
|
||||||
//else => @compileError("TODO"),
|
//else => @compileError("TODO"),
|
||||||
}
|
}
|
||||||
|
@ -551,27 +529,6 @@ fn parseDeref(comptime tokens: ControlTokenIter) ParseResult(ControlTokenIter, [
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseCallTemplate(comptime tokens: ControlTokenIter) ParseResult(ControlTokenIter, CallTemplate) {
|
|
||||||
comptime {
|
|
||||||
var iter = tokens;
|
|
||||||
const template_name = while (iter.next()) |token| switch (token) {
|
|
||||||
.text => |t| break t,
|
|
||||||
.whitespace => {},
|
|
||||||
else => @compileError("Unexpected token"),
|
|
||||||
} else @compileError("Unexpected end of template");
|
|
||||||
|
|
||||||
const args = parseExpression(iter);
|
|
||||||
|
|
||||||
return .{
|
|
||||||
.new_iter = args.new_iter,
|
|
||||||
.item = .{
|
|
||||||
.template_name = template_name,
|
|
||||||
.args = args.item,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ParseResult(comptime It: type, comptime T: type) type {
|
fn ParseResult(comptime It: type, comptime T: type) type {
|
||||||
return struct {
|
return struct {
|
||||||
new_iter: It,
|
new_iter: It,
|
||||||
|
@ -608,11 +565,6 @@ const If = struct {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const CallTemplate = struct {
|
|
||||||
template_name: []const u8,
|
|
||||||
args: Expression,
|
|
||||||
};
|
|
||||||
|
|
||||||
const IfHeader = struct {
|
const IfHeader = struct {
|
||||||
condition: Expression,
|
condition: Expression,
|
||||||
};
|
};
|
||||||
|
@ -621,7 +573,6 @@ const Statement = union(enum) {
|
||||||
expression: Expression,
|
expression: Expression,
|
||||||
@"for": For,
|
@"for": For,
|
||||||
@"if": If,
|
@"if": If,
|
||||||
call_template: CallTemplate,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const ControlBlock = struct {
|
const ControlBlock = struct {
|
||||||
|
@ -633,7 +584,6 @@ const ControlBlock = struct {
|
||||||
end_if: void,
|
end_if: void,
|
||||||
@"else": void,
|
@"else": void,
|
||||||
elif_header: IfHeader,
|
elif_header: IfHeader,
|
||||||
call_template: CallTemplate,
|
|
||||||
};
|
};
|
||||||
block: Data,
|
block: Data,
|
||||||
strip_before: bool,
|
strip_before: bool,
|
||||||
|
@ -645,7 +595,6 @@ const Keyword = enum {
|
||||||
@"if",
|
@"if",
|
||||||
@"else",
|
@"else",
|
||||||
@"elif",
|
@"elif",
|
||||||
@"template",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const EndKeyword = enum {
|
const EndKeyword = enum {
|
||||||
|
|
|
@ -21,8 +21,6 @@
|
||||||
{=#else=}
|
{=#else=}
|
||||||
neither
|
neither
|
||||||
{=/if}
|
{=/if}
|
||||||
|
|
||||||
<template>{#template test_tmpl .bar}</template>
|
|
||||||
</section>
|
</section>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue