update: if and for nodes

This commit is contained in:
Lucas F. 2026-01-11 12:55:30 -03:00
parent 256898cb41
commit 13ad344005

View file

@ -65,16 +65,21 @@ pub const Renderer = struct {
}
for (nodes) |node| {
try self.renderNode(alloc, node, writer);
try self.renderNode(alloc, node, writer, null);
}
}
fn renderNode(self: *const Renderer, alloc: Allocator, node: parser.Node, writer: anytype) RenderError!void {
fn renderNode(self: *const Renderer, alloc: Allocator, node: parser.Node, writer: anytype, context: ?*Context) RenderError!void {
switch (node.type) {
.text => try writer.writeAll(node.text.?.content),
.variable => {
const var_name = node.variable.?.expr;
var value: Value = self.context.get(var_name) orelse Value.null;
var value: Value = Value.null;
if (context != null) {
value = context.?.get(var_name) orelse Value.null;
}else{
value = self.context.get(var_name) orelse Value.null;
}
var is_safe = false;
@ -99,7 +104,42 @@ pub const Renderer = struct {
try self.valueToString(alloc, &buf, value);
try writer.writeAll(buf.items);
},
else => unreachable,
.if_block => {
const condition = self.evaluateCondition(node.@"if".?.condition) catch return false;
if (condition) {
for (node.@"if".?.true_body) |child| {
try self.renderNode(alloc, child, writer, null);
}
} else {
for (node.@"if".?.false_body) |child| {
try self.renderNode(alloc, child, writer, null);
}
}
},
.for_block => {
const list_value = self.context.get(node.@"for".?.iterable) orelse Value.null;
const list = switch (list_value) {
.list => |l| l,
else => return,
};
for (list) |item| {
var ctx = Context.init(alloc);
defer ctx.deinit();
try ctx.set(node.@"for".?.loop_var,item);
for (node.@"for".?.body) |child| {
try self.renderNode(alloc, child, writer, &ctx);
}
for (node.@"for".?.empty_body) |child| {
try self.renderNode(alloc, child, writer, &ctx);
}
}
},
else => {},
}
}
@ -116,4 +156,17 @@ pub const Renderer = struct {
.dict => try w.writeAll("{dict}"),
}
}
fn evaluateCondition(self: *const Renderer, expr: []const u8) !bool {
const value = self.context.get(expr) orelse Value.null;
return switch (value) {
.bool => |b| b,
.int => |i| i != 0,
.float => |f| f != 0.0,
.string => |s| s.len > 0,
.list => |l| l.len > 0,
.dict => |d| d.count() > 0,
.null => false,
};
}
};