hi,

recently on #parrot there was a short discussion on symbol handling
w.r.t. nested scopes.

During that discussion, I understood that when looking for a symbol in
a PAST::Block node, it will look in that block, and, if not found, in
any :outer blocks.
To give an example:

function foo {
   var a;

   {
      a = 42; # this a is declared in this block's outer scope, namely
the scope block of function foo.
   }
}

When looking at the actual implementation of the symbol() method on
PAST::Block (which does symbol storing and retrieving),
there is no proof of such behavior. In fact, I spent a few hours
figuring why nested blocks didn't work in my private language project.

So, my question now is, what should symbol() be doing? Should it stay
as-is, or am I missing a point somewhere?
If the current implementation is correct, then when looking for a
symbol "inside-out" (scope-wise) should be implemented as a while
loop, something I had understood to be implemented in PAST. This could
look like this:

$scope := 'package'         # default scope is package
$index := [EMAIL PROTECTED];    # find number of blocks on "scope stack"
while $index != 0 {
  $index := $index - 1;
  if @?BLOCK[$index].symbol($name) {  # look for symbol in "innermost" scope
    $scope := 'lexical';               # if found, scope is lexical.
  }
}
kjs


PS: For reference, I included the implementation of the symbol method,
found in compilers/pct/src/PAST/Node.pir:

.sub 'symbol' :method
    .param string name
    .param pmc attr            :slurpy :named
    .local pmc symtable
    symtable = self['symtable']
    unless null symtable goto have_symtable
    symtable = new 'Hash'
    self['symtable'] = symtable
  have_symtable:
    if attr goto set_symbol
  get_symbol:
    $P0 = symtable[name]
    if null $P0 goto set_symbol
    .return ($P0)
  set_symbol:
    symtable[name] = attr
    .return (attr)
.end

Reply via email to