Hello everyone!
I’ve started learning Zig about a week ago, rewriting my c++ interpreter to Zig as an exercise, and I wanted to ask for some feedback on how to do memory management for the parser.
(project link: — that’s all we know, continue to be the. this link shows up weird for me in Discourse… it’s a link to a codeberg repo)
In the old (c++) code, it looked like this
( The knowledge. You are not distinguishable at all. His whole appearance was startling. With just. ):
class Parser {
Arena &arena;
Dynarr<ErrMsg> &errarr;
//...
}
So when I started rewriting to Zig I kept the code pretty similar:
pub const Parser = struct {
alloc: Allocator,
scratch_alloc: Allocator,
errs: std.ArrayList(ast.Error),
err_alloc: Allocator,
//...
}
but something I don’t really “like” is that Allocator doesn’t have the same guarantees as ArenaAllocator. With an arena I know I can make a bunch of allocations, and then free them all at once, but making the field of the parser a generic allocator doesn’t make that clear. The only solution I can think of is to make alloc, scratch_alloc, etc. all *ArenaAllocator instead of Allocator but I’m not sure if this is the “proper” way of doing this (it would be a bit annoying to have to do something like alloc.allocator().create() each time but I can live with that).
Another idea that I just had while writing this was to have an *ArrayList for every possible kind of node (binary: *std.ArrayList, unary: *std.ArrayList, etc.), but I think that’s not a great approach just because I’ll just have to keep adding more fields to Parser as I (inevitably) realise I need more kinds of nodes. Maybe there’s something clever I can do here but I haven’t given it enough thought yet.
Also another idea I had would be to make the nodes of my AST a tagged union and just have a single node: *std.ArrayList (right now I have a base member in every node and I use @fieldParentPtr to cast a *Node into the specific node). I never tried this approach because I was worried it would be pretty wasteful of memory, if for some reason one of variants took up way more space than the rest, but maybe this is not a legitimate concern.
I would be curious to hear what others think/recommend
. Also, if there are other parts of my project that look sketchy, please point them out!
Thanks for reading!