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 },
|
.{ .name = "zdt_prov", .module = mod },
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
.use_llvm = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
// This declares intent for the executable to be installed into the
|
// 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| {
|
.tag => if (self.tag) |t| {
|
||||||
allocator.free(t.name);
|
allocator.free(t.name);
|
||||||
allocator.free(t.args);
|
allocator.free(t.args);
|
||||||
|
allocator.free(t.raw);
|
||||||
},
|
},
|
||||||
.if_block => if (self.@"if") |ib| {
|
.if_block => if (self.@"if") |ib| {
|
||||||
allocator.free(ib.condition);
|
allocator.free(ib.condition);
|
||||||
|
|
@ -245,6 +246,8 @@ pub const Node = struct {
|
||||||
const false_copy = ib.false_body;
|
const false_copy = ib.false_body;
|
||||||
for (false_copy) |n| n.deinit(allocator);
|
for (false_copy) |n| n.deinit(allocator);
|
||||||
allocator.free(ib.false_body);
|
allocator.free(ib.false_body);
|
||||||
|
allocator.free(ib.raw_open);
|
||||||
|
allocator.free(ib.raw_close);
|
||||||
},
|
},
|
||||||
.for_block => if (self.@"for") |fb| {
|
.for_block => if (self.@"for") |fb| {
|
||||||
allocator.free(fb.loop_var);
|
allocator.free(fb.loop_var);
|
||||||
|
|
@ -255,7 +258,10 @@ pub const Node = struct {
|
||||||
const empty_copy = fb.empty_body;
|
const empty_copy = fb.empty_body;
|
||||||
for (empty_copy) |n| n.deinit(allocator);
|
for (empty_copy) |n| n.deinit(allocator);
|
||||||
allocator.free(fb.empty_body);
|
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| {
|
.with_block => if (self.with) |w| {
|
||||||
for (w.assignments) |a| {
|
for (w.assignments) |a| {
|
||||||
allocator.free(a.key);
|
allocator.free(a.key);
|
||||||
|
|
@ -265,13 +271,20 @@ pub const Node = struct {
|
||||||
const body_copy = w.body;
|
const body_copy = w.body;
|
||||||
for (body_copy) |n| n.deinit(allocator);
|
for (body_copy) |n| n.deinit(allocator);
|
||||||
allocator.free(w.body);
|
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| {
|
.block => if (self.block) |b| {
|
||||||
allocator.free(b.name);
|
allocator.free(b.name);
|
||||||
const body_copy = b.body;
|
const body_copy = b.body;
|
||||||
for (body_copy) |n| n.deinit(allocator);
|
for (body_copy) |n| n.deinit(allocator);
|
||||||
allocator.free(b.body);
|
allocator.free(b.body);
|
||||||
|
allocator.free(b.raw_open);
|
||||||
|
allocator.free(b.raw_close);
|
||||||
},
|
},
|
||||||
|
.super => {},
|
||||||
.filter_block => if (self.filter_block) |fb| {
|
.filter_block => if (self.filter_block) |fb| {
|
||||||
allocator.free(fb.filters);
|
allocator.free(fb.filters);
|
||||||
const body_copy = fb.body;
|
const body_copy = fb.body;
|
||||||
|
|
@ -282,16 +295,16 @@ pub const Node = struct {
|
||||||
const body_copy = ae.body;
|
const body_copy = ae.body;
|
||||||
for (body_copy) |n| n.deinit(allocator);
|
for (body_copy) |n| n.deinit(allocator);
|
||||||
allocator.free(ae.body);
|
allocator.free(ae.body);
|
||||||
|
allocator.free(ae.raw_open);
|
||||||
|
allocator.free(ae.raw_close);
|
||||||
},
|
},
|
||||||
.spaceless => if (self.spaceless) |sl| {
|
.spaceless => if (self.spaceless) |sl| {
|
||||||
const body_copy = sl.body;
|
const body_copy = sl.body;
|
||||||
for (body_copy) |n| n.deinit(allocator);
|
for (body_copy) |n| n.deinit(allocator);
|
||||||
allocator.free(sl.body);
|
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| {
|
.url => if (self.url) |u| {
|
||||||
allocator.free(u.name);
|
allocator.free(u.name);
|
||||||
for (u.args) |a| allocator.free(a);
|
for (u.args) |a| allocator.free(a);
|
||||||
|
|
@ -318,6 +331,8 @@ pub const Node = struct {
|
||||||
.debug => {},
|
.debug => {},
|
||||||
.partialdef => if (self.partialdef) |pd| {
|
.partialdef => if (self.partialdef) |pd| {
|
||||||
allocator.free(pd.name);
|
allocator.free(pd.name);
|
||||||
|
allocator.free(pd.raw_open);
|
||||||
|
allocator.free(pd.raw_close);
|
||||||
for (pd.body) |n| n.deinit(allocator);
|
for (pd.body) |n| n.deinit(allocator);
|
||||||
allocator.free(pd.body);
|
allocator.free(pd.body);
|
||||||
},
|
},
|
||||||
|
|
@ -344,6 +359,344 @@ pub const Node = struct {
|
||||||
.templatetag => {},
|
.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 {
|
pub const Parser = struct {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue