Add equals operator to template engine
This commit is contained in:
parent
aee81e27b6
commit
4e3450de4e
2 changed files with 50 additions and 9 deletions
|
@ -15,6 +15,7 @@ pub fn main() !void {
|
|||
.bar = .{ .x = "x" },
|
||||
.qux = false,
|
||||
.quxx = true,
|
||||
.quxx2 = true,
|
||||
.maybe_foo = @as(?[]const u8, "foo"),
|
||||
.maybe_bar = @as(?[]const u8, null),
|
||||
.x = "y",
|
||||
|
@ -168,6 +169,7 @@ fn EvaluateExpression(
|
|||
.arg_deref => |names| Deref(Args, names),
|
||||
.capture_deref => |names| Deref(Captures, names),
|
||||
.context_deref => |names| Deref(Context, names),
|
||||
.equals => bool,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -181,6 +183,16 @@ fn evaluateExpression(
|
|||
.arg_deref => |names| deref(args, names),
|
||||
.capture_deref => |names| deref(captures, names),
|
||||
.context_deref => |names| deref(context, names),
|
||||
.equals => |eql| {
|
||||
const lhs = evaluateExpression(eql.lhs, args, captures, context);
|
||||
const rhs = evaluateExpression(eql.rhs, args, captures, context);
|
||||
const T = @TypeOf(lhs, rhs);
|
||||
if (comptime std.meta.trait.isZigString(T)) {
|
||||
return std.mem.eql(u8, lhs, rhs);
|
||||
} else if (comptime std.meta.trait.isContainer(T) and @hasDecl(T, "eql")) {
|
||||
return T.eql(lhs, rhs);
|
||||
} else return lhs == rhs;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -400,29 +412,50 @@ fn parseExpression(comptime tokens: ControlTokenIter) ParseResult(ControlTokenIt
|
|||
comptime {
|
||||
var iter = tokens;
|
||||
|
||||
var expr: Expression = while (iter.next()) |token| switch (token) {
|
||||
var last_valid_iter: ?ControlTokenIter = null;
|
||||
var expr: ?Expression = null;
|
||||
while (iter.next()) |token| switch (token) {
|
||||
.whitespace => {},
|
||||
.period => {
|
||||
const names = parseDeref(iter);
|
||||
iter = names.new_iter;
|
||||
break .{ .arg_deref = names.item };
|
||||
expr = .{ .arg_deref = names.item };
|
||||
last_valid_iter = iter;
|
||||
},
|
||||
.dollar => {
|
||||
const names = parseDeref(iter);
|
||||
iter = names.new_iter;
|
||||
break .{ .capture_deref = names.item };
|
||||
expr = .{ .capture_deref = names.item };
|
||||
last_valid_iter = iter;
|
||||
},
|
||||
.percent => {
|
||||
const names = parseDeref(iter);
|
||||
iter = names.new_iter;
|
||||
break .{ .context_deref = names.item };
|
||||
expr = .{ .context_deref = names.item };
|
||||
last_valid_iter = iter;
|
||||
},
|
||||
else => @compileError("TODO"),
|
||||
.equals => {
|
||||
const next = iter.next() orelse break;
|
||||
if (next == .equals) {
|
||||
const lhs = expr orelse break;
|
||||
const rhs = parseExpression(iter);
|
||||
iter = rhs.new_iter;
|
||||
|
||||
expr = .{
|
||||
.equals = &.{
|
||||
.lhs = lhs,
|
||||
.rhs = rhs.item,
|
||||
},
|
||||
};
|
||||
last_valid_iter = iter;
|
||||
} else break;
|
||||
},
|
||||
else => break,
|
||||
};
|
||||
|
||||
return .{
|
||||
.new_iter = iter,
|
||||
.item = expr,
|
||||
.new_iter = last_valid_iter orelse @compileError("Invalid Expression"),
|
||||
.item = expr orelse @compileError("Invalid Expression"),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -518,7 +551,7 @@ fn parseControlBlock(comptime tokens: ControlTokenIter) ParseResult(ControlToken
|
|||
},
|
||||
else => {
|
||||
@compileLog(iter.row);
|
||||
@compileError("TODO" ++ @tagName(token));
|
||||
@compileError("TODO " ++ @tagName(token) ++ " " ++ token.text);
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -702,10 +735,16 @@ const TemplateItem = union(enum) {
|
|||
statement: Statement,
|
||||
};
|
||||
|
||||
const EqualsExpr = struct {
|
||||
lhs: Expression,
|
||||
rhs: Expression,
|
||||
};
|
||||
|
||||
const Expression = union(enum) {
|
||||
arg_deref: []const []const u8,
|
||||
capture_deref: []const []const u8,
|
||||
context_deref: []const []const u8,
|
||||
equals: *const EqualsExpr,
|
||||
};
|
||||
|
||||
const For = struct {
|
||||
|
@ -830,7 +869,7 @@ const ControlTokenIter = struct {
|
|||
},
|
||||
else => {
|
||||
var idx: usize = 0;
|
||||
while (idx < remaining.len and std.mem.indexOfScalar(u8, "{}.#|$/=@ \t\n\r", remaining[idx]) == null) : (idx += 1) {}
|
||||
while (idx < remaining.len and std.mem.indexOfScalar(u8, "{}.#|$/=@,% \t\n\r", remaining[idx]) == null) : (idx += 1) {}
|
||||
|
||||
self.start += idx - 1;
|
||||
return .{ .text = remaining[0..idx] };
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
{$b}:
|
||||
{= /for =}
|
||||
{= /for}
|
||||
{#if .quxx == .quxx2}eql{#else}neq{/if}
|
||||
{#if .quxx == .qux}eql{#else}neq{/if}
|
||||
{#if .qux=}
|
||||
qux
|
||||
{=#elif .quxx=}
|
||||
|
|
Loading…
Reference in a new issue