I'm building a toy compiler from a C like language to a stack machine and I'm at the point where I need to figure out what to do with functions and block local variables. Thinking through it abstractly it looks like I have two options at opposite ends of the spectrum: 1) Preprocess and preallocate stack space for each variable, 2) Add special instructions to the VM to walk the stack.
Pre-process and preallocate stack space for each variable
This has the advantage of giving me all the addresses for the variables ahead of time so I don't have to be very clever or add any extra instructions to the VM for walking the stack. The downside is that it is potentially very wasteful because conditional code that never executes but declares a whole bunch of variables will take up a lot of unnecessary space. For example,
a : t1 = value;
if (test) {
b : t2; c : t3; d : t4; ...;
}
In the above code even if test
is always false I will still allocate space for all those variables within the conditional branch.
Add special instructions to the VM to walk the stack
The other approach I could come up with was to generate code for each variable declaration and then add some special VM instructions to figure out the address of those variables at runtime. This solves the problem of wasted stack space but then adds a computational overhead that I can potentially solve by some caching methods.
So what's the correct approach and is there another approach I didn't think of that is better?