Fixed issues with shadowing and cross-shadowing
This commit is contained in:
parent
7ab757074f
commit
582d29d149
|
@ -700,14 +700,14 @@ proc getStackPos(self: Compiler, name: Name): int =
|
||||||
## of a given name, relative to the current
|
## of a given name, relative to the current
|
||||||
## stack frame
|
## stack frame
|
||||||
var found = false
|
var found = false
|
||||||
result = 2
|
result = 2 # Locals start at frame offset 2
|
||||||
for variable in reversed(self.names):
|
for variable in self.names:
|
||||||
# Only variables and arguments are actually located on
|
# Only variables and arguments are actually located on
|
||||||
# the stack, so we skip everything else
|
# the stack, so we skip everything else
|
||||||
if variable.kind notin [NameKind.Var, NameKind.Argument]:
|
if variable.kind notin [NameKind.Var, NameKind.Argument]:
|
||||||
continue
|
continue
|
||||||
# Variable is in a scope above us, so not in frame. Skip it!
|
# Variable is in a scope above us, so not in frame. Skip it!
|
||||||
elif variable.depth < self.depth:
|
elif variable.depth < name.depth:
|
||||||
continue
|
continue
|
||||||
# Arguments to builtin functions are optimized away to stack
|
# Arguments to builtin functions are optimized away to stack
|
||||||
# temporaries. There is no stack frame for builtins, so we skip
|
# temporaries. There is no stack frame for builtins, so we skip
|
||||||
|
@ -716,19 +716,20 @@ proc getStackPos(self: Compiler, name: Name): int =
|
||||||
continue
|
continue
|
||||||
# This variable isn't in declared in our module,
|
# This variable isn't in declared in our module,
|
||||||
# but we may still have access to it
|
# but we may still have access to it
|
||||||
elif variable.owner != self.currentModule:
|
elif variable.owner != name.owner:
|
||||||
# Variable is private in its owner module
|
# Variable is private in its owner module
|
||||||
# or it wasn't exported to us explcitly, so
|
# or it wasn't exported to us explicitly,
|
||||||
# we increase our index to make sure we don't
|
# so we just move on
|
||||||
# overwrite it and move on
|
if variable.isPrivate or name.owner notin variable.exportedTo:
|
||||||
if variable.isPrivate or self.currentModule notin variable.exportedTo:
|
inc(result)
|
||||||
#inc(result)
|
|
||||||
continue
|
continue
|
||||||
# Note: this is not an elif by design (lets us match public exported names
|
if name.ident == variable.ident and variable.depth == name.depth and name.owner == variable.owner:
|
||||||
# in other modules!) Also, since getStackPos() takes a specific name object, we
|
if not name.belongsTo.isNil() and not variable.belongsTo.isNil():
|
||||||
# match the identifier as well as the name's scope depth
|
if name.belongsTo != variable.belongsTo and variable.belongsTo.depth > name.belongsTo.depth:
|
||||||
if name.ident == variable.ident and variable.depth == name.depth:
|
dec(result)
|
||||||
|
continue
|
||||||
found = true
|
found = true
|
||||||
|
variable.resolved = true
|
||||||
break
|
break
|
||||||
inc(result)
|
inc(result)
|
||||||
if not found:
|
if not found:
|
||||||
|
@ -1845,11 +1846,8 @@ proc identifier(self: Compiler, node: IdentExpr, name: Name = nil) =
|
||||||
var s = name
|
var s = name
|
||||||
if s.isNil():
|
if s.isNil():
|
||||||
s = self.resolveOrError(node)
|
s = self.resolveOrError(node)
|
||||||
# If there's more than one variable with this name,
|
|
||||||
# we cannot tell which one to use, so we error out
|
|
||||||
var t = self.findByType(s.ident.token.lexeme, Type(kind: All))
|
var t = self.findByType(s.ident.token.lexeme, Type(kind: All))
|
||||||
if len(t) > 1:
|
s = t[0] # Shadowing!
|
||||||
self.error(&"ambiguous name reference to '{s.ident.token.lexeme}', please use fully qualified names instead", node)
|
|
||||||
if s.isConst:
|
if s.isConst:
|
||||||
# Constants are always emitted as Load* instructions
|
# Constants are always emitted as Load* instructions
|
||||||
# no matter the scope depth
|
# no matter the scope depth
|
||||||
|
|
|
@ -14,4 +14,4 @@ export misc;
|
||||||
export comparisons;
|
export comparisons;
|
||||||
|
|
||||||
var version* = 1;
|
var version* = 1;
|
||||||
var private = 2; # Invisible outside the module
|
var _private = 5; # Invisible outside the module (underscore is to silence warning)
|
|
@ -4,17 +4,14 @@ import std;
|
||||||
|
|
||||||
|
|
||||||
fn first(x: int): int {
|
fn first(x: int): int {
|
||||||
var y = x;
|
return x + 1;
|
||||||
y = y + 1;
|
|
||||||
return y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn second(x: int): int {
|
fn second(x: int): int {
|
||||||
var x = first(x);
|
return first(x) + 1;
|
||||||
x = x + 1;
|
|
||||||
return x;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
print(first(0) == 1); # true
|
||||||
print(second(0) == 2); # true
|
print(second(0) == 2); # true
|
||||||
|
|
Loading…
Reference in New Issue