feat: implicitly declare nonlocal names as globals for forward references

Add support for forward references to top-level variables by implicitly
declaring unresolved capitalized names as globals during compilation.
If a real definition is not found later, a compile-time error is raised.
This enables mutual recursion at the top level and fixes issues #101 and #106.

Introduce an `UNDEFINED` singleton value to mark implicitly declared globals
that have not yet been explicitly defined. Update `wrenDeclareGlobal` to add
such entries, and modify `wrenDefineGlobal` to check for and replace undefined
placeholders. Adjust the symbol table API to allow duplicate additions for
implicit declarations. Add test cases for mutual recursion, forward references
in functions and methods, and undefined variable errors.
This commit is contained in:
Bob Nystrom
2015-01-15 07:08:25 +00:00
parent 533644c1f6
commit 72291f8b74
14 changed files with 152 additions and 53 deletions
+10
View File
@@ -0,0 +1,10 @@
class Foo {
static bar { new Bar }
}
class Bar {
static foo { new Foo }
}
IO.print(Foo.bar) // expect: instance of Bar
IO.print(Bar.foo) // expect: instance of Foo
+3
View File
@@ -0,0 +1,3 @@
IO.print(Foo) // expect: null
var Foo = "value"
IO.print(Foo) // expect: value
+7
View File
@@ -0,0 +1,7 @@
var fn = new Fn {
IO.print(Foo)
IO.print(Bar)
}
// expect error line 7
// expect error line 7
@@ -1,5 +1,4 @@
var Global = "global"
// TODO: Forward reference to global declared after use.
new Fn {
IO.print(Global) // expect: global
@@ -0,0 +1,7 @@
var f = new Fn {
IO.print(Global)
}
var Global = "global"
f.call // expect: global
@@ -1,5 +1,4 @@
var Global = "global"
// TODO: Forward reference to global declared after use.
class Foo {
method {
@@ -0,0 +1,14 @@
class Foo {
method {
IO.print(Global)
}
static classMethod {
IO.print(Global)
}
}
var Global = "global"
(new Foo).method // expect: global
Foo.classMethod // expect: global