Further split parsing and execution
This commit is contained in:
parent
d24957b7a0
commit
efb50a325b
1 changed files with 57 additions and 26 deletions
|
@ -7,32 +7,15 @@ pub fn main() !void {
|
||||||
const logging = false;
|
const logging = false;
|
||||||
|
|
||||||
pub fn execute(writer: 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 * 6));
|
const items = comptime parseTemplate(template);
|
||||||
comptime var iter = TokenIter{ .text = template };
|
try executeTemplate(writer, items, args);
|
||||||
inline while (comptime iter.next()) |token| {
|
}
|
||||||
if (logging) @compileLog(token);
|
|
||||||
switch (token) {
|
fn executeTemplate(writer: anytype, comptime items: []const TemplateItem, args: anytype) !void {
|
||||||
|
inline for (items) |it| switch (it) {
|
||||||
.text => |text| try writer.writeAll(text),
|
.text => |text| try writer.writeAll(text),
|
||||||
.open_bracket => {
|
.statement => |stmt| try executeStatement(writer, stmt, args),
|
||||||
const next = comptime iter.peek() orelse @compileError("Unexpected end of template");
|
};
|
||||||
if (next == .open_bracket) {
|
|
||||||
try writer.writeByte('{');
|
|
||||||
_ = comptime iter.next();
|
|
||||||
} else {
|
|
||||||
const result = comptime parseStatement(iter);
|
|
||||||
try executeStatement(writer, result.item, args);
|
|
||||||
iter = result.new_iter;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
.close_bracket => {
|
|
||||||
const next = comptime iter.next() orelse @compileError("Unexpected end of template");
|
|
||||||
if (comptime next == .close_bracket) try writer.writeByte('}') else @compileError("Unpaired close bracket, did you mean \"}}\"?");
|
|
||||||
},
|
|
||||||
.whitespace => |wsp| try writer.writeAll(wsp),
|
|
||||||
.period => try writer.writeByte('.'),
|
|
||||||
.pound => try writer.writeByte('#'),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn executeStatement(writer: anytype, comptime stmt: Statement, args: anytype) !void {
|
fn executeStatement(writer: anytype, comptime stmt: Statement, args: anytype) !void {
|
||||||
|
@ -54,6 +37,49 @@ fn argDeref(writer: anytype, comptime names: []const []const u8, arg: anytype) !
|
||||||
return argDeref(writer, names[1..], @field(arg, names[0]));
|
return argDeref(writer, names[1..], @field(arg, names[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parseTemplate(comptime template: []const u8) []const TemplateItem {
|
||||||
|
comptime {
|
||||||
|
@setEvalBranchQuota(@intCast(u32, template.len * 6));
|
||||||
|
var iter = TokenIter{ .text = template };
|
||||||
|
var items: []const TemplateItem = &.{};
|
||||||
|
var current_text: []const u8 = "";
|
||||||
|
|
||||||
|
while (iter.next()) |token| {
|
||||||
|
if (logging) @compileLog(token);
|
||||||
|
switch (token) {
|
||||||
|
.whitespace, .text => |text| current_text = current_text ++ text,
|
||||||
|
.open_bracket => {
|
||||||
|
const next = iter.peek() orelse @compileError("Unexpected end of template");
|
||||||
|
if (next == .open_bracket) {
|
||||||
|
current_text = current_text ++ "{";
|
||||||
|
_ = iter.next();
|
||||||
|
} else {
|
||||||
|
if (current_text.len != 0) {
|
||||||
|
items = items ++ [_]TemplateItem{.{ .text = current_text }};
|
||||||
|
current_text = "";
|
||||||
|
}
|
||||||
|
const result = parseStatement(iter);
|
||||||
|
iter = result.new_iter;
|
||||||
|
items = items ++ [_]TemplateItem{.{ .statement = result.item }};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.close_bracket => {
|
||||||
|
const next = iter.next() orelse @compileError("Unexpected end of template");
|
||||||
|
if (next == .close_bracket) current_text = current_text ++ "}" else @compileError("Unpaired close bracket, did you mean \"}}\"?");
|
||||||
|
},
|
||||||
|
.period => current_text = current_text ++ ".",
|
||||||
|
.pound => current_text = current_text ++ "#",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_text.len != 0) {
|
||||||
|
items = items ++ [_]TemplateItem{.{ .text = current_text }};
|
||||||
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn parseStatement(comptime tokens: TokenIter) ParseResult(Statement) {
|
fn parseStatement(comptime tokens: TokenIter) ParseResult(Statement) {
|
||||||
comptime {
|
comptime {
|
||||||
var iter = tokens;
|
var iter = tokens;
|
||||||
|
@ -122,6 +148,11 @@ fn ParseResult(comptime T: type) type {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TemplateItem = union(enum) {
|
||||||
|
text: []const u8,
|
||||||
|
statement: Statement,
|
||||||
|
};
|
||||||
|
|
||||||
const Expression = union(enum) {
|
const Expression = union(enum) {
|
||||||
arg_deref: []const []const u8,
|
arg_deref: []const []const u8,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue