update: add clone function
This commit is contained in:
parent
a55831d0ce
commit
cba0c8d749
2 changed files with 358 additions and 4 deletions
|
|
@ -81,6 +81,7 @@ pub fn build(b: *std.Build) void {
|
|||
.{ .name = "zdt_prov", .module = mod },
|
||||
},
|
||||
}),
|
||||
.use_llvm = true,
|
||||
});
|
||||
|
||||
// This declares intent for the executable to be installed into the
|
||||
|
|
|
|||
361
src/parser.zig
361
src/parser.zig
|
|
@ -236,6 +236,7 @@ pub const Node = struct {
|
|||
.tag => if (self.tag) |t| {
|
||||
allocator.free(t.name);
|
||||
allocator.free(t.args);
|
||||
allocator.free(t.raw);
|
||||
},
|
||||
.if_block => if (self.@"if") |ib| {
|
||||
allocator.free(ib.condition);
|
||||
|
|
@ -245,6 +246,8 @@ pub const Node = struct {
|
|||
const false_copy = ib.false_body;
|
||||
for (false_copy) |n| n.deinit(allocator);
|
||||
allocator.free(ib.false_body);
|
||||
allocator.free(ib.raw_open);
|
||||
allocator.free(ib.raw_close);
|
||||
},
|
||||
.for_block => if (self.@"for") |fb| {
|
||||
allocator.free(fb.loop_var);
|
||||
|
|
@ -255,7 +258,10 @@ pub const Node = struct {
|
|||
const empty_copy = fb.empty_body;
|
||||
for (empty_copy) |n| n.deinit(allocator);
|
||||
allocator.free(fb.empty_body);
|
||||
allocator.free(fb.raw_open);
|
||||
allocator.free(fb.raw_close);
|
||||
},
|
||||
.include => if (self.include) |inc| allocator.free(inc.template_name),
|
||||
.with_block => if (self.with) |w| {
|
||||
for (w.assignments) |a| {
|
||||
allocator.free(a.key);
|
||||
|
|
@ -265,13 +271,20 @@ pub const Node = struct {
|
|||
const body_copy = w.body;
|
||||
for (body_copy) |n| n.deinit(allocator);
|
||||
allocator.free(w.body);
|
||||
allocator.free(w.raw_open);
|
||||
allocator.free(w.raw_close);
|
||||
},
|
||||
.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);
|
||||
const body_copy = b.body;
|
||||
for (body_copy) |n| n.deinit(allocator);
|
||||
allocator.free(b.body);
|
||||
allocator.free(b.raw_open);
|
||||
allocator.free(b.raw_close);
|
||||
},
|
||||
.super => {},
|
||||
.filter_block => if (self.filter_block) |fb| {
|
||||
allocator.free(fb.filters);
|
||||
const body_copy = fb.body;
|
||||
|
|
@ -282,16 +295,16 @@ pub const Node = struct {
|
|||
const body_copy = ae.body;
|
||||
for (body_copy) |n| n.deinit(allocator);
|
||||
allocator.free(ae.body);
|
||||
allocator.free(ae.raw_open);
|
||||
allocator.free(ae.raw_close);
|
||||
},
|
||||
.spaceless => if (self.spaceless) |sl| {
|
||||
const body_copy = sl.body;
|
||||
for (body_copy) |n| n.deinit(allocator);
|
||||
allocator.free(sl.body);
|
||||
allocator.free(sl.raw_open);
|
||||
allocator.free(sl.raw_close);
|
||||
},
|
||||
.include => if (self.include) |inc| allocator.free(inc.template_name),
|
||||
.now => if (self.now) |n| allocator.free(n.format),
|
||||
.extends => if (self.extends) |e| allocator.free(e.parent_name),
|
||||
.super => {},
|
||||
.url => if (self.url) |u| {
|
||||
allocator.free(u.name);
|
||||
for (u.args) |a| allocator.free(a);
|
||||
|
|
@ -318,6 +331,8 @@ pub const Node = struct {
|
|||
.debug => {},
|
||||
.partialdef => if (self.partialdef) |pd| {
|
||||
allocator.free(pd.name);
|
||||
allocator.free(pd.raw_open);
|
||||
allocator.free(pd.raw_close);
|
||||
for (pd.body) |n| n.deinit(allocator);
|
||||
allocator.free(pd.body);
|
||||
},
|
||||
|
|
@ -344,6 +359,344 @@ pub const Node = struct {
|
|||
.templatetag => {},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clone(self: Node, allocator: std.mem.Allocator) !Node {
|
||||
switch (self.type) {
|
||||
.text => {
|
||||
return Node{
|
||||
.type = .text,
|
||||
.text = .{ .content = try allocator.dupe(u8, self.text.?.content) },
|
||||
};
|
||||
},
|
||||
|
||||
.variable => {
|
||||
const filters_copy = try allocator.alloc(Filter, self.variable.?.filters.len);
|
||||
errdefer allocator.free(filters_copy);
|
||||
|
||||
for (self.variable.?.filters, 0..) |f, i| {
|
||||
filters_copy[i] = .{
|
||||
.name = try allocator.dupe(u8, f.name),
|
||||
.arg = if (f.arg) |a| try allocator.dupe(u8, a) else null,
|
||||
};
|
||||
}
|
||||
|
||||
return Node{
|
||||
.type = .variable,
|
||||
.variable = .{
|
||||
.expr = try allocator.dupe(u8, self.variable.?.expr),
|
||||
.filters = filters_copy,
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
.if_block => {
|
||||
const true_body_copy = try allocator.alloc(Node, self.@"if".?.true_body.len);
|
||||
errdefer allocator.free(true_body_copy);
|
||||
|
||||
for (self.@"if".?.true_body, 0..) |child, j| {
|
||||
true_body_copy[j] = try child.clone(allocator);
|
||||
}
|
||||
|
||||
const false_body_copy = try allocator.alloc(Node, self.@"if".?.false_body.len);
|
||||
errdefer allocator.free(false_body_copy);
|
||||
|
||||
for (self.@"if".?.false_body, 0..) |child, j| {
|
||||
false_body_copy[j] = try child.clone(allocator);
|
||||
}
|
||||
|
||||
return Node{
|
||||
.type = .if_block,
|
||||
.@"if" = .{
|
||||
.condition = try allocator.dupe(u8, self.@"if".?.condition),
|
||||
.true_body = true_body_copy,
|
||||
.false_body = false_body_copy,
|
||||
.raw_open = try allocator.dupe(u8, self.@"if".?.raw_open),
|
||||
.raw_close = try allocator.dupe(u8, self.@"if".?.raw_close),
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
.for_block => {
|
||||
const body_copy = try allocator.alloc(Node, self.@"for".?.body.len);
|
||||
errdefer allocator.free(body_copy);
|
||||
|
||||
for (self.@"for".?.body, 0..) |child, j| {
|
||||
body_copy[j] = try child.clone(allocator);
|
||||
}
|
||||
|
||||
const empty_body_copy = try allocator.alloc(Node, self.@"for".?.empty_body.len);
|
||||
errdefer allocator.free(empty_body_copy);
|
||||
|
||||
for (self.@"for".?.empty_body, 0..) |child, j| {
|
||||
empty_body_copy[j] = try child.clone(allocator);
|
||||
}
|
||||
|
||||
return Node{
|
||||
.type = .for_block,
|
||||
.@"for" = .{
|
||||
.loop_var = try allocator.dupe(u8, self.@"for".?.loop_var),
|
||||
.iterable = try allocator.dupe(u8, self.@"for".?.iterable),
|
||||
.body = body_copy,
|
||||
.empty_body = empty_body_copy,
|
||||
.raw_open = try allocator.dupe(u8, self.@"for".?.raw_open),
|
||||
.raw_close = try allocator.dupe(u8, self.@"for".?.raw_close),
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
.block => {
|
||||
const body_copy = try allocator.alloc(Node, self.block.?.body.len);
|
||||
errdefer allocator.free(body_copy);
|
||||
|
||||
for (self.block.?.body, 0..) |child, j| {
|
||||
body_copy[j] = try child.clone(allocator);
|
||||
}
|
||||
|
||||
return Node{
|
||||
.type = .block,
|
||||
.block = .{
|
||||
.name = try allocator.dupe(u8, self.block.?.name),
|
||||
.body = body_copy,
|
||||
.raw_open = try allocator.dupe(u8, self.block.?.raw_open),
|
||||
.raw_close = try allocator.dupe(u8, self.block.?.raw_close),
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
.extends => {
|
||||
return Node{
|
||||
.type = .extends,
|
||||
.extends = .{
|
||||
.parent_name = try allocator.dupe(u8, self.extends.?.parent_name),
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
.super => {
|
||||
return Node{
|
||||
.type = .super,
|
||||
};
|
||||
},
|
||||
.tag => {
|
||||
return Node{
|
||||
.type = .tag,
|
||||
.tag = .{
|
||||
.name = try allocator.dupe(u8, self.tag.?.name),
|
||||
.args = try allocator.dupe(u8, self.tag.?.args),
|
||||
.raw = try allocator.dupe(u8, self.tag.?.raw),
|
||||
},
|
||||
};
|
||||
},
|
||||
.include => {
|
||||
return Node{
|
||||
.type = .include,
|
||||
.include = .{
|
||||
.template_name = try allocator.dupe(u8, self.include.?.template_name),
|
||||
},
|
||||
};
|
||||
},
|
||||
.with_block => {
|
||||
const body_copy = try allocator.alloc(Node, self.block.?.body.len);
|
||||
errdefer allocator.free(body_copy);
|
||||
|
||||
for (self.block.?.body, 0..) |child, j| {
|
||||
body_copy[j] = try child.clone(allocator);
|
||||
}
|
||||
|
||||
const assignments_copy = try allocator.alloc(Assignment, self.with.?.assignments.len);
|
||||
errdefer allocator.free(assignments_copy);
|
||||
|
||||
for (self.with.?.assignments, 0..) |f, i| {
|
||||
assignments_copy[i] = .{
|
||||
.key = try allocator.dupe(u8, f.key),
|
||||
.value_expr = try allocator.dupe(u8, f.value_expr),
|
||||
.is_literal = f.is_literal,
|
||||
};
|
||||
}
|
||||
|
||||
return Node{
|
||||
.type = .with_block,
|
||||
.with = .{
|
||||
.assignments = assignments_copy,
|
||||
.body = body_copy,
|
||||
.raw_open = try allocator.dupe(u8, self.with.?.raw_open),
|
||||
.raw_close = try allocator.dupe(u8, self.with.?.raw_close),
|
||||
},
|
||||
};
|
||||
},
|
||||
.now => {
|
||||
return Node{ .type = .now, .now = .{ .format = try allocator.dupe(u8, self.now.?.format) } };
|
||||
},
|
||||
.filter_block => {
|
||||
const body_copy = try allocator.alloc(Node, self.filter_block.?.body.len);
|
||||
errdefer allocator.free(body_copy);
|
||||
|
||||
for (self.filter_block.?.body, 0..) |child, j| {
|
||||
body_copy[j] = try child.clone(allocator);
|
||||
}
|
||||
|
||||
return Node{
|
||||
.type = .filter_block,
|
||||
.filter_block = .{
|
||||
.filters = try allocator.dupe(u8, self.filter_block.?.filters),
|
||||
.body = body_copy,
|
||||
.raw_open = try allocator.dupe(u8, self.filter_block.?.raw_open),
|
||||
.raw_close = try allocator.dupe(u8, self.filter_block.?.raw_close),
|
||||
},
|
||||
};
|
||||
},
|
||||
.autoescape => {
|
||||
const body_copy = try allocator.alloc(Node, self.autoescape.?.body.len);
|
||||
errdefer allocator.free(body_copy);
|
||||
|
||||
for (self.autoescape.?.body, 0..) |child, j| {
|
||||
body_copy[j] = try child.clone(allocator);
|
||||
}
|
||||
|
||||
return Node{
|
||||
.type = .autoescape,
|
||||
.autoescape = .{
|
||||
.body = body_copy,
|
||||
.raw_open = try allocator.dupe(u8, self.autoescape.?.raw_open),
|
||||
.raw_close = try allocator.dupe(u8, self.autoescape.?.raw_close),
|
||||
.enabled = self.autoescape.?.enabled,
|
||||
},
|
||||
};
|
||||
},
|
||||
.spaceless => {
|
||||
const body_copy = try allocator.alloc(Node, self.spaceless.?.body.len);
|
||||
errdefer allocator.free(body_copy);
|
||||
|
||||
for (self.spaceless.?.body, 0..) |child, j| {
|
||||
body_copy[j] = try child.clone(allocator);
|
||||
}
|
||||
|
||||
return Node{
|
||||
.type = .spaceless,
|
||||
.spaceless = .{
|
||||
.body = body_copy,
|
||||
.raw_open = try allocator.dupe(u8, self.spaceless.?.raw_open),
|
||||
.raw_close = try allocator.dupe(u8, self.spaceless.?.raw_close),
|
||||
},
|
||||
};
|
||||
},
|
||||
.url => {
|
||||
const args_copy = try allocator.alloc([]const u8, self.url.?.args.len);
|
||||
errdefer allocator.free(args_copy);
|
||||
|
||||
for (self.url.?.args, 0..) |f, i| {
|
||||
args_copy[i] = try allocator.dupe(u8, f);
|
||||
}
|
||||
|
||||
return Node{ .type = .url, .url = .{
|
||||
.name = try allocator.dupe(u8, self.url.?.name),
|
||||
.args = args_copy,
|
||||
} };
|
||||
},
|
||||
.cycle => {
|
||||
const values_copy = try allocator.alloc([]const u8, self.cycle.?.values.len);
|
||||
errdefer allocator.free(values_copy);
|
||||
|
||||
for (self.cycle.?.values, 0..) |f, i| {
|
||||
values_copy[i] = try allocator.dupe(u8, f);
|
||||
}
|
||||
|
||||
return Node{ .type = .cycle, .cycle = .{ .values = values_copy } };
|
||||
},
|
||||
.firstof => {
|
||||
const values_copy = try allocator.alloc([]const u8, self.firstof.?.values.len);
|
||||
errdefer allocator.free(values_copy);
|
||||
|
||||
for (self.firstof.?.values, 0..) |f, i| {
|
||||
values_copy[i] = try allocator.dupe(u8, f);
|
||||
}
|
||||
|
||||
return Node{ .type = .firstof, .firstof = .{ .values = values_copy } };
|
||||
},
|
||||
.load => {
|
||||
const libraries_copy = try allocator.alloc([]const u8, self.load.?.libraries.len);
|
||||
errdefer allocator.free(libraries_copy);
|
||||
|
||||
for (self.load.?.libraries, 0..) |f, i| {
|
||||
libraries_copy[i] = try allocator.dupe(u8, f);
|
||||
}
|
||||
|
||||
return Node{ .type = .load, .load = .{ .libraries = libraries_copy } };
|
||||
},
|
||||
.csrf_token => {
|
||||
return Node{
|
||||
.type = .csrf_token,
|
||||
};
|
||||
},
|
||||
.lorem => {
|
||||
return Node{
|
||||
.type = .lorem,
|
||||
.lorem = .{
|
||||
.count = if (self.lorem.?.count) |c| try allocator.dupe(u8, c) else null,
|
||||
.method = if (self.lorem.?.method) |m| try allocator.dupe(u8, m) else null,
|
||||
.format = if (self.lorem.?.format) |f| try allocator.dupe(u8, f) else null,
|
||||
},
|
||||
};
|
||||
},
|
||||
.debug => {
|
||||
return Node{ .type = .debug };
|
||||
},
|
||||
.partialdef => {
|
||||
const body_copy = try allocator.alloc(Node, self.partialdef.?.body.len);
|
||||
errdefer allocator.free(body_copy);
|
||||
|
||||
for (self.partialdef.?.body, 0..) |child, j| {
|
||||
body_copy[j] = try child.clone(allocator);
|
||||
}
|
||||
|
||||
return Node{ .type = .partialdef, .partialdef = .{
|
||||
.name = try allocator.dupe(u8, self.partialdef.?.name),
|
||||
.body = body_copy,
|
||||
.raw_open = try allocator.dupe(u8, self.partialdef.?.raw_open),
|
||||
.raw_close = try allocator.dupe(u8, self.partialdef.?.raw_close),
|
||||
} };
|
||||
},
|
||||
.partial => {
|
||||
return Node{ .type = .partial, .partial = .{
|
||||
.name = try allocator.dupe(u8, self.partial.?.name),
|
||||
} };
|
||||
},
|
||||
.querystring => {
|
||||
const modifications = try allocator.alloc([]const u8, self.querystring.?.modifications.len);
|
||||
errdefer allocator.free(modifications);
|
||||
|
||||
for (self.querystring.?.modifications, 0..) |f, i| {
|
||||
modifications[i] = try allocator.dupe(u8, f);
|
||||
}
|
||||
|
||||
return Node{ .type = .querystring, .querystring = .{
|
||||
.modifications = modifications,
|
||||
} };
|
||||
},
|
||||
.regroup => {
|
||||
return Node{ .type = .regroup, .regroup = .{
|
||||
.source = try allocator.dupe(u8, self.regroup.?.source),
|
||||
.by = try allocator.dupe(u8, self.regroup.?.by),
|
||||
.as_var = try allocator.dupe(u8, self.regroup.?.as_var),
|
||||
} };
|
||||
},
|
||||
.resetcycle => {
|
||||
return Node{ .type = .resetcycle, .resetcycle = .{
|
||||
.cycle_name = if (self.resetcycle.?.cycle_name) |n| try allocator.dupe(u8, n) else null,
|
||||
} };
|
||||
},
|
||||
.widthratio => {
|
||||
return Node{ .type = .widthratio, .widthratio = .{
|
||||
.value = try allocator.dupe(u8, self.widthratio.?.value),
|
||||
.max_value = try allocator.dupe(u8, self.widthratio.?.max_value),
|
||||
.divisor = if (self.widthratio.?.divisor) |d| try allocator.dupe(u8, d) else null,
|
||||
} };
|
||||
},
|
||||
.templatetag => {
|
||||
return Node{ .type = .templatetag, .templatetag = .{ .kind = self.templatetag.?.kind } };
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub const Parser = struct {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue