Boo

Compilation error -- global var + recursion

Details

  • Type: Bug Bug
  • Status: Resolved Resolved
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: 0.8.2
  • Fix Version/s: None
  • Component/s: Compiler
  • Labels:
    None
  • Number of attachments :
    0

Description

cache = {}

def fib(i as int) as int:
r = cache[i]
if r is null:
if i < 2:
r = 1
else:
r = fib(i-1) + fib(i-2)
cache[i] = r
return r

Boo Compiler version 0.8.2.2960 (CLR v2.0.50727.1433)
fibcache.boo(13,16): BCE0005: Unknown identifier: 'fib'.
fibcache.boo(13,27): BCE0005: Unknown identifier: 'fib'.

Activity

Hide
Avishay Lavie added a comment - - edited

I can confirm this as of r3043. If the whole thing is put into a class, everything works.

Minimal testcase:

globalVar = 42

def recursive() as int:
  return recursive()

>>> BCE0005: Unknown identifier: 'recursive'.

Show
Avishay Lavie added a comment - - edited I can confirm this as of r3043. If the whole thing is put into a class, everything works. Minimal testcase:
globalVar = 42

def recursive() as int:
  return recursive()
>>> BCE0005: Unknown identifier: 'recursive'.
Hide
Avishay Lavie added a comment - - edited

To make sense of this, I see two problems here:

1. In the above testcase, the first line is parsed as an assignment rather than a field declaration and, perhaps consequently, the recursive method definition is parsed as a DeclarationStatement rather than a Method.

2. Methods nested in other methods are transformed into closures inside their parent method, and as a result, they cannot be recursive since they are not part of their own display class.

As a result of these, both members in the above testcase (the "global field" and the "method declaration") are considered global statements rather than module members, and are thus left inside the generated Main() method as part of the IntroduceModuleClasses step. This makes the recursive method a nested method inside Main(), and consequently it fails to invoke itself.

We can fix either of the two problems:

1. We can make sure that method definitions inside a module are parsed as methods regardless of where they appear.

2. We can allow nested methods to call themselves (and other nested methods under the same parent method) by considering method invocations, in addition to references, when computing a closure's display class.

Which (or both) do you think is right?

Show
Avishay Lavie added a comment - - edited To make sense of this, I see two problems here: 1. In the above testcase, the first line is parsed as an assignment rather than a field declaration and, perhaps consequently, the recursive method definition is parsed as a DeclarationStatement rather than a Method. 2. Methods nested in other methods are transformed into closures inside their parent method, and as a result, they cannot be recursive since they are not part of their own display class. As a result of these, both members in the above testcase (the "global field" and the "method declaration") are considered global statements rather than module members, and are thus left inside the generated Main() method as part of the IntroduceModuleClasses step. This makes the recursive method a nested method inside Main(), and consequently it fails to invoke itself. We can fix either of the two problems: 1. We can make sure that method definitions inside a module are parsed as methods regardless of where they appear. 2. We can allow nested methods to call themselves (and other nested methods under the same parent method) by considering method invocations, in addition to references, when computing a closure's display class. Which (or both) do you think is right?
Hide
Avishay Lavie added a comment -

Resolved in r3050 by allowing nested functions to recursively call themselves.

The fact that the testcase is being incorrectly parsed should still be examined, though.

Show
Avishay Lavie added a comment - Resolved in r3050 by allowing nested functions to recursively call themselves. The fact that the testcase is being incorrectly parsed should still be examined, though.

People

Vote (0)
Watch (1)

Dates

  • Created:
    Updated:
    Resolved: