update: add extends,block and super into parser
This commit is contained in:
parent
3019009325
commit
261c02f59b
3 changed files with 551 additions and 285 deletions
132
src/parser.zig
132
src/parser.zig
|
|
@ -9,15 +9,26 @@ pub const NodeType = enum {
|
|||
include,
|
||||
with_block,
|
||||
now,
|
||||
// extends, // <--- novo
|
||||
// block, // <--- novo
|
||||
// super, // <--- novo (para {{ block.super }})
|
||||
extends, // <--- novo
|
||||
block, // <--- novo
|
||||
super, // <--- novo (para {{ block.super }})
|
||||
};
|
||||
|
||||
pub const NowNode = struct {
|
||||
format: []const u8,
|
||||
};
|
||||
|
||||
pub const ExtendsNode = struct {
|
||||
parent_name: []const u8,
|
||||
};
|
||||
|
||||
pub const BlockNode = struct {
|
||||
name: []const u8,
|
||||
body: []Node,
|
||||
raw_open: []const u8,
|
||||
raw_close: []const u8,
|
||||
};
|
||||
|
||||
pub const Assignment = struct {
|
||||
key: []const u8,
|
||||
value_expr: []const u8,
|
||||
|
|
@ -76,6 +87,9 @@ pub const Node = struct {
|
|||
include: ?IncludeNode = null,
|
||||
with: ?WithNode = null,
|
||||
now: ?NowNode = null,
|
||||
extends: ?ExtendsNode = null,
|
||||
block: ?BlockNode = null,
|
||||
super: bool = false, // para {{ block.super }}
|
||||
|
||||
pub fn deinit(self: Node, allocator: std.mem.Allocator) void {
|
||||
switch (self.type) {
|
||||
|
|
@ -119,6 +133,16 @@ pub const Node = struct {
|
|||
.now => if (self.now) |n| {
|
||||
allocator.free(n.format);
|
||||
},
|
||||
.extends => if (self.extends) |e| {
|
||||
allocator.free(e.parent_name);
|
||||
},
|
||||
.block => if (self.block) |b| {
|
||||
allocator.free(b.name);
|
||||
for (b.body) |n| n.deinit(allocator);
|
||||
allocator.free(b.body);
|
||||
// raw_open e raw_close são slices originais — não free
|
||||
},
|
||||
.super => {},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -218,6 +242,70 @@ pub const Parser = struct {
|
|||
return try list.toOwnedSlice(allocator);
|
||||
}
|
||||
|
||||
fn parseBlockBlock(self: *Parser, allocator: std.mem.Allocator, name: []const u8, raw_open: []const u8) !Node {
|
||||
var body = std.ArrayList(Node){};
|
||||
defer body.deinit(allocator);
|
||||
|
||||
var depth: usize = 1;
|
||||
|
||||
while (self.pos < self.template.len and depth > 0) {
|
||||
if (try self.parseText(allocator)) |node| {
|
||||
try body.append(allocator, node);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (try self.parseVariable(allocator)) |node| {
|
||||
if (node.variable) |v| {
|
||||
if (std.mem.eql(u8, v.content, "block.super")) {
|
||||
try body.append(allocator, Node{ .type = .super, .super = true });
|
||||
allocator.free(v.content);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
try body.append(allocator, node);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (try self.parseTag(allocator)) |tag_node| {
|
||||
const tag_name = tag_node.tag.?.name;
|
||||
|
||||
if (std.mem.eql(u8, tag_name, "block")) {
|
||||
depth += 1;
|
||||
try body.append(allocator, tag_node);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (std.mem.eql(u8, tag_name, "endblock")) {
|
||||
depth -= 1;
|
||||
const raw_close = tag_node.tag.?.raw;
|
||||
|
||||
allocator.free(tag_node.tag.?.name);
|
||||
allocator.free(tag_node.tag.?.args);
|
||||
|
||||
if (depth == 0) {
|
||||
return Node{
|
||||
.type = .block,
|
||||
.block = .{
|
||||
.name = name,
|
||||
.body = try body.toOwnedSlice(allocator),
|
||||
.raw_open = raw_open,
|
||||
.raw_close = raw_close,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
try body.append(allocator, tag_node);
|
||||
continue;
|
||||
}
|
||||
|
||||
try body.append(allocator, tag_node);
|
||||
} else {
|
||||
self.advance(1);
|
||||
}
|
||||
}
|
||||
|
||||
return error.UnclosedBlock;
|
||||
}
|
||||
fn parseWithBlock(self: *Parser, allocator: std.mem.Allocator, assignments: []const Assignment, raw_open: []const u8) !Node {
|
||||
std.debug.print("Vou verificar se sou bloco with\n", .{});
|
||||
var body = std.ArrayList(Node){};
|
||||
|
|
@ -627,6 +715,44 @@ pub const Parser = struct {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (std.mem.eql(u8, tag_name, "extends")) {
|
||||
const parent = std.mem.trim(u8, node.tag.?.args, " \t\"");
|
||||
|
||||
const duped = try allocator.dupe(u8, parent);
|
||||
|
||||
allocator.free(node.tag.?.name);
|
||||
allocator.free(node.tag.?.args);
|
||||
|
||||
std.debug.print("3.0 - na real sou um extends\n", .{});
|
||||
std.debug.print("===================================\n", .{});
|
||||
try list.append(allocator, Node{
|
||||
.type = .extends,
|
||||
.extends = .{ .parent_name = duped },
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
if (std.mem.eql(u8, tag_name, "block")) {
|
||||
const block_name_raw = node.tag.?.args;
|
||||
const raw_open = node.tag.?.raw;
|
||||
|
||||
const block_name = std.mem.trim(u8, block_name_raw, " \t\r\n");
|
||||
|
||||
// DUPE O NOME ANTES DE LIBERAR A TAG
|
||||
const duped_name = try allocator.dupe(u8, block_name);
|
||||
|
||||
// Agora libera a tag open
|
||||
allocator.free(node.tag.?.name);
|
||||
allocator.free(node.tag.?.args);
|
||||
|
||||
std.debug.print("3.0 - na real sou um block\n", .{});
|
||||
std.debug.print("===================================\n", .{});
|
||||
|
||||
const block_node = try self.parseBlockBlock(allocator, duped_name, raw_open);
|
||||
try list.append(allocator, block_node);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (std.mem.eql(u8, tag_name, "now")) {
|
||||
const args = node.tag.?.args;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue