Issue Details (XML | Word | Printable)

Key: BOO-1085
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Avishay Lavie
Reporter: Mike Krell
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
Boo

Compilation error -- global var + recursion

Created: 20/Sep/08 11:44 AM   Updated: 17/Oct/08 09:07 PM   Resolved: 17/Oct/08 09:07 PM
Return to search
Component/s: Compiler
Affects Version/s: 0.8.2
Fix Version/s: None

Time Tracking:
Not Specified


 Description  « Hide

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'.



Avishay Lavie added a comment - 04/Oct/08 05:30 AM - 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'.


Avishay Lavie added a comment - 17/Oct/08 01:23 PM - 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?


Avishay Lavie added a comment - 17/Oct/08 09:07 PM

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.