I have written a small compiler for a simple stack machine. It can assemble and handle scope/functions through a number of virtual machine hacks only. That is I have it define scope and in scope variable definitions in the bytecode itself.
Can I get some pointers on how I should be handling scope.
The problems I face are mainly, how do I let it know when to and when not to overwrite a variable outside with a variable inside, and similar. The bytecode is mutable and I would prefer to change it.
Other problems include how to retain variables outside after returning. So that a variable still has its value. I can push it to stack, but I could have a lot of variables.
I think there is some compiler work done to check these things, but I can't think of what would need to be done to do it.
One way would be to rename variables at compile time to ensure there is no masking. So:
{
declare foo;
foo = assignment;
{
declare foo;
foo = another_assignment;
another_use = foo;
}
use = foo;
}
Is equivalent to:
{
declare foo_0;
foo_0 = assignment;
{
declare foo_1;
foo_1 = another_assignment;
another_use = foo_1;
}
use = foo_0;
}
While compiling, you maintain one 'rename-stack' per variable. And:
Whenever you see a declaration, you generate a new name and push it to the corresponding variable's rename-stack.
When you see an assignment/usage, you replace the name with whatever is on the top of the stack.
When you leave a scope, you pop it off the stack.