Parable was always intended to have a garbage collector. My first incarnation was very simple: for any named item, assume any stored values were references to other things. Recurse through these, adding on, until all potential references were found, then release everything else.
This worked, but wasn't good. It left lots of junk in memory, and was just good enough to reduce the manual memory management headaches a bit.
With the addition of type tracking within Parable I made some adaptions to this code, discarding values that could reliably be noted as not pointers. Now it just keeps strings, comments, pointers, and function calls. I also expanded the number of things scanned to include pointers on the stack and functions whose names were removed.
This is better: the collector can now reclaim significantly more junk and be much more reliable at identifying garbage. But it still had a problem: recursion.
Since the reference scanner is recursive, with a large enough data set I have been running into call stack issues. It's become bad enough that a collection was frequently crashing the Parable VM. And so I set out to fix this.
I split the reference scanner into two functions. The first scans a slice, grabbing pointers. The second calls this repeatedly (applying to the returned results), until no new pointers are found. It's a little less conceptually elegant, but actually cuts down on some repeated code in the old function, and more importantly it is able to run without crashing on my tests.
It's not perfect. I need to implement something very exhaustive and repeatedly testable to ensure.that it is fully working and not missing anything. But it's definitely an improvement over what was in place previously.