Appearance
| 1 | namespace Syntax.Process is | |
| 2 | ||
| 3 | // Scans a nested named function's body for a reference to the | |
| 4 | // function's own name, so declare-members can tell whether the | |
| 5 | // literal recurses before it builds the closure - the closure's | |
| 6 | // recursion is fixed at construction, and a delegate is only | |
| 7 | // available to one that does not recurse. | |
| 8 | // | |
| 9 | // Nested literals are walked rather than skipped: a lambda written | |
| 10 | // inside the function can call it, and that reference is served the | |
| 11 | // same way. | |
| 12 | // | |
| 13 | // The test is the written name, so a reference the name is shadowed | |
| 14 | // at reports a recursion that is not one. The cost of that is a | |
| 15 | // frame the closure did not need, never a wrong answer, and scoping | |
| 16 | // is not resolved yet at the point the question is asked. | |
| 17 | class NAME_REFERENCE_SCANNER: Visitor is | |
| 18 | _name: string | |
| 19 | _found: bool | |
| 20 | ||
| 21 | init() is | |
| 22 | super.init() | |
| 23 | ||
| 24 | _name = "" | |
| 25 | si | |
| 26 | ||
| 27 | body_references(body: Trees.Bodies.Body?, name: string) -> bool is | |
| 28 | _name = name | |
| 29 | _found = false | |
| 30 | ||
| 31 | if body? then | |
| 32 | body.walk(self) | |
| 33 | fi | |
| 34 | ||
| 35 | return _found | |
| 36 | si | |
| 37 | ||
| 38 | pre(identifier: Trees.Expressions.IDENTIFIER) -> bool is | |
| 39 | if identifier.identifier.name =~ _name then | |
| 40 | _found = true | |
| 41 | fi | |
| 42 | ||
| 43 | return false | |
| 44 | si | |
| 45 | si | |
| 46 | si |