I am implementing a programming language, for fun, in C. I have most of the parsing code done and also the AST ready. I once did write a runtime for this language some time ago, but I had some trouble with the garbage collector. I then realized i needed to study a little more and that my previous AST walker implementation was really poor.
Now I'm restarting it, and I choosed to compile the AST to bytecode and then run it on a pretty basic stack-based VM. I have looked at others languages compilers and VMs and I learned a lot, but my research wasn't still enough to answer me somethings.
When compiling, should I maintain an array for each type of "basic" constants like strings, numbers, booleans, etc... And then compile that to bytecode as well, or a single array of constants but already wrapped by a custom struct? And if I do this, how should I pass this objects to the VM? Compile it's address in memory as void *
or create the VM's own reference to this array of objects and pass the indices as an instruction argument? Also, should the Garbage Collector know about this objects immediately or just when they get pushed to the stack? It seems wrong to me the later approach because if I have a big program, it would allocate a very large amount of memory before even executing anything. However, that's the way I saw some languages implementations doing it.
To sum up, should I compile "raw" values, or keep a reference to language Objects through the Compiling-Executing process?