Closed Olipro closed 1 year ago
Couple of additional cases that might be related (or not):
self
should never participate in implicit lookupFoo = {"a":123}
Foo.a = function
locals.self = self // Without this line, the current scope is "self-less" and should never work.
b = function
print self.a // should fail
end function
b
end function
Foo.a
The print
should fail because self
would need to be referenced using outer.self.a
or, of course by setting locals.self = outer.self
Foo = {"a":123}
Foo.a = function
locals.self = self
b = function
print locals.hasIndex("self") // should be false
end function
b
end function
Foo.a
0
should be printed. I also noticed while testing that there seems to be a tree inside locals
where you can walk each depth which I imagine is what makes this happen. Essentially, each scope is disconnected and has its own independent tables. A shame since your way would make the language much better.
Very helpful thank you.
I absolutely loathe that I have to report this, because frankly, the way Greybel does it should be the way MiniScript does. In fact, keeping this behaviour through some sort of flag or setting for anyone who's just writing Greybel-specific code wouldn't be a bad thing at all.
But probably people might be confused then why it works in greybel and not in MiniScript/GreyScript so probably best to remove the capability.
The "fix" should be available as soon https://github.com/ayecue/greybel-vs/pull/102 is merged.
self should never participate in implicit lookup
Interestingly when I tested that code in the online MiniScript editor it just crashes with a timeout. Anyway with https://github.com/ayecue/greybel-vs/pull/102 merged it will throw unknown path.
Function has implicit self where none should exist
Interesting I wasn't aware of that. With https://github.com/ayecue/greybel-vs/pull/102 merged it should be fixed though. I also added test cases now for this specific case checking globals, locals, outer, self and super.
I'll give an update once it's merged.
The fixes addressing these issues should be merged now. Please check if it works for you as well.
Broke a few things that were supposed to be broken so I'm calling it goooooood!
Dang, gotta reopen it - this started failing:
TEST_SETUP function()
globals.mockGlobals = MiniMock.build({})
toMock.forEach function(key)
globals[key] = mockGlobals.define(key, 1) // This line
end function
globals.mockRouter = MiniMock.build({})
mockRouter.define("firewall_rules", 0)
mockRouter.define("local_ip", 0)
mockRouter.define("devices_lan_ip", 0)
mockRouter.define("device_ports", 1)
mockRouter.define("used_ports", 0)
end function
Runtime error: Unknown path globals.
Globals should always be in scope :)
This seems to be specifically related to using globals
with the []
operator. if I print globals
within the same scope, it outputs the map just fine.
I have currently worked around this by doing glbl = globals
and then assigning through the freshly-minted local.
I've implemented some optimizations when it comes to globals, outer, locals and self lookups. The interpreter usually pre builds certain parts that are not dynamic but it seems like I forgot to test certain cases such as globals["test"]
. I have a fix in the pipeline. Hopefully that will resolve the issue.
Okay fix should be available in a bit.
I absolutely loathe that I have to report this, because frankly, the way Greybel does it should be the way MiniScript does. In fact, keeping this behaviour through some sort of flag or setting for anyone who's just writing Greybel-specific code wouldn't be a bad thing at all.
Given:
An error should be thrown when the inner-most function attempts to print
foo.bar
.In order for the code to run correctly, it would need to look like this:
In essence, at any given scope level, a scope's
outer
is always that of the parent scope'slocals
and never any higher. Exposure to child scope(s) requires explicitly creating an entry in the current scope'slocals
.Special caveat
If, instead of
locals.foo = foo
you were to writefoo = foo
, MiniScript will issue a deprecation warning, but nonetheless it will behave as if you wrotelocals.foo = outer.foo
- more precisely, it will do a walk to find the rhs operand, then evaluate the lhs and, sincelocals
lacks the keyfoo
, put it there. This also means thatfoo = foo; foo = foo
would be the equivalent oflocals.foo = outer.foo; locals.foo = locals.foo