update: if and for nodes
This commit is contained in:
parent
256898cb41
commit
13ad344005
1 changed files with 57 additions and 4 deletions
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue