Hey so this is my first language where I don't have a gc, before this I have used rust (which i know also not have a gc but hey we ball) so I don't know how to free stuffs okay? so basically I'm building an interpreted language, and for the BinaryExpression parser I want to make it so that the lhs expression keep holding a reference to itself. now when de-initializing the parser I am recursively freeing every single element of that Expression struct BUT I'M STILL GETTING A GAZZILION OF MEMORY LEAKS AND DOUBLE FREES AND WHAT NOT can someone help me?
This is how I'm creating a binary Expression
fn createBinaryExpression(self: *Parser, comptime precedentFn: fn (*Parser) anyerror!ParserTypes.Expression, comptime tokens: []const LexerTypes.TokenType) !ParserTypes.Expression {
var lhs_ptr = try self.allocator.create(ParserTypes.Expression);
errdefer self.allocator.destroy(lhs_ptr);
lhs_ptr.* = try precedentFn(self);
while (self.matchTokens(tokens)) {
self.currentIndex += 1;
const operator = self.tokens.items[self.currentIndex].tokenType;
self.currentIndex += 1;
const rhs_ptr = try self.allocator.create(ParserTypes.Expression);
errdefer self.allocator.destroy(rhs_ptr);
rhs_ptr.* = try precedentFn(self);
const binary_expr = try self.allocator.create(ParserTypes.Expression);
errdefer self.allocator.destroy(binary_expr);
const binaryExprType = try self.allocator.create(ParserTypes.BinaryExpressionType);
errdefer self.allocator.destroy(binaryExprType);
binaryExprType.* = .{
.left = lhs_ptr,
.right = rhs_ptr,
.operator = operator,
};
binary_expr.* = .{
.BinaryExpression = binaryExprType,
};
lhs_ptr = binary_expr;
}
return lhs_ptr.*;
}