1

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.

Chase
  • 1,419
  • 12
  • 17
  • Are you talking about closures? –  Oct 03 '12 at 14:07
  • Sorta, but no. Basically how to generate bytecode to handle variables with scope, or rather examples there of (which might be more helpful). – Chase Oct 03 '12 at 14:18

1 Answers1

2

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:

  1. Whenever you see a declaration, you generate a new name and push it to the corresponding variable's rename-stack.

  2. When you see an assignment/usage, you replace the name with whatever is on the top of the stack.

  3. When you leave a scope, you pop it off the stack.

ArjunShankar
  • 23,020
  • 5
  • 61
  • 83
  • Thanks, that's actually very helpful. I didn't think of keeping a separate rename stack for each variable. I was trying to do it on a scope basis. this way is much more elegant. Thank you! – Chase Oct 03 '12 at 17:16
  • How would I go about handling recursive statements then? That's a question that has been bugging me a bit. – Chase Oct 04 '12 at 16:26
  • 1
    Masking due to scope can be handled in the way I explained, *at compile time*, i.e. by renaming to avoid masking. On the other hand, recursive calls (and even regular calls) should be handled *at run time*. i.e. in the call stack. Its really a different problem altogether. Except that there is a stack involved there too ;) – ArjunShankar Oct 04 '12 at 16:42