Bind whether a variable symbol is a creation statement or just changing the variable
This commit is contained in:
parent
07a71129a2
commit
a9f4ef1b65
|
@ -283,7 +283,7 @@ namespace Upsilon.Binder
|
||||||
_diagnostics.LogUnknownVariable(e.Identifier.Span, name);
|
_diagnostics.LogUnknownVariable(e.Identifier.Span, name);
|
||||||
return new BoundLiteralExpression(new ScriptNull(), e.Span);
|
return new BoundLiteralExpression(new ScriptNull(), e.Span);
|
||||||
}
|
}
|
||||||
var boundVariable = new BoundVariableSymbol(variable, e.Identifier.Span);
|
var boundVariable = new BoundVariableSymbol(variable, false, e.Identifier.Span);
|
||||||
return new BoundVariableExpression(boundVariable, e.Span);
|
return new BoundVariableExpression(boundVariable, e.Span);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,10 +293,11 @@ namespace Upsilon.Binder
|
||||||
return new BoundExpressionStatement(exp, s.Span);
|
return new BoundExpressionStatement(exp, s.Span);
|
||||||
}
|
}
|
||||||
|
|
||||||
private VariableSymbol TryBindVariable(string name, bool isLocal, BoundExpression assignment, string[] commentData)
|
private (VariableSymbol Symbol, bool IsCreation) TryBindVariable(string name, bool isLocal, BoundExpression assignment, string[] commentData)
|
||||||
{
|
{
|
||||||
if (name == "_")
|
if (name == "_")
|
||||||
return null;
|
return (null, false);
|
||||||
|
var isCreation = false;
|
||||||
if (!Scope.TryGetVariable(name, !isLocal, out var variable))
|
if (!Scope.TryGetVariable(name, !isLocal, out var variable))
|
||||||
{
|
{
|
||||||
if (assignment.Type == Type.Table)
|
if (assignment.Type == Type.Table)
|
||||||
|
@ -323,6 +324,8 @@ namespace Upsilon.Binder
|
||||||
Scope.DefineLocalVariable(variable);
|
Scope.DefineLocalVariable(variable);
|
||||||
else
|
else
|
||||||
Scope.AssignToNearest(variable);
|
Scope.AssignToNearest(variable);
|
||||||
|
|
||||||
|
isCreation = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -347,11 +350,11 @@ namespace Upsilon.Binder
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_diagnostics.LogCannotConvert(assignment.Type, variable.Type, assignment.Span);
|
_diagnostics.LogCannotConvert(assignment.Type, variable.Type, assignment.Span);
|
||||||
return null;
|
return (null, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return variable;
|
return (variable, isCreation);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BoundStatement BindAssignmentStatement(AssignmentStatementSyntax e)
|
private BoundStatement BindAssignmentStatement(AssignmentStatementSyntax e)
|
||||||
|
@ -363,14 +366,15 @@ namespace Upsilon.Binder
|
||||||
var boundExpression = BindExpression(e.Expression);
|
var boundExpression = BindExpression(e.Expression);
|
||||||
|
|
||||||
var isLocal = e.LocalToken != null;
|
var isLocal = e.LocalToken != null;
|
||||||
var boundVariable = TryBindVariable(name, isLocal, boundExpression, e.CommentData);
|
var (symbol, isCreation) = TryBindVariable(name, isLocal, boundExpression, e.CommentData);
|
||||||
if (boundVariable != null)
|
if (symbol != null)
|
||||||
{
|
{
|
||||||
if (boundVariable.Type == Type.Unknown)
|
if (symbol.Type == Type.Unknown)
|
||||||
{
|
{
|
||||||
_diagnostics.LogUnknownVariableType(boundVariable.Name, variableExpression.Span);
|
_diagnostics.LogUnknownVariableType(symbol.Name, variableExpression.Span);
|
||||||
}
|
}
|
||||||
var variable = new BoundVariableSymbol(boundVariable, variableExpression.Span);
|
|
||||||
|
var variable = new BoundVariableSymbol(symbol, isCreation, variableExpression.Span);
|
||||||
return new BoundVariableAssignment(variable, boundExpression, isLocal, e.Span);
|
return new BoundVariableAssignment(variable, boundExpression, isLocal, e.Span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -387,11 +391,11 @@ namespace Upsilon.Binder
|
||||||
foreach (var identifierToken in s.Identifiers)
|
foreach (var identifierToken in s.Identifiers)
|
||||||
{
|
{
|
||||||
var boundVariable = TryBindVariable(identifierToken.Name, isLocal, assignment, null);
|
var boundVariable = TryBindVariable(identifierToken.Name, isLocal, assignment, null);
|
||||||
if (boundVariable.Type == Type.Unknown)
|
if (boundVariable.Symbol.Type == Type.Unknown)
|
||||||
{
|
{
|
||||||
_diagnostics.LogUnknownVariableType(boundVariable.Name, identifierToken.Span);
|
_diagnostics.LogUnknownVariableType(boundVariable.Symbol.Name, identifierToken.Span);
|
||||||
}
|
}
|
||||||
ls.Add(boundVariable);
|
ls.Add(boundVariable.Symbol);
|
||||||
}
|
}
|
||||||
return new BoundMultiAssignmentStatement(ls.ToImmutableArray(), assignment, s.Span);
|
return new BoundMultiAssignmentStatement(ls.ToImmutableArray(), assignment, s.Span);
|
||||||
}
|
}
|
||||||
|
@ -461,7 +465,7 @@ namespace Upsilon.Binder
|
||||||
{
|
{
|
||||||
variableSymbol = new FunctionParameterSymbol(variable.IdentifierName.Name, Type.Unknown);
|
variableSymbol = new FunctionParameterSymbol(variable.IdentifierName.Name, Type.Unknown);
|
||||||
}
|
}
|
||||||
parameters.Add(new BoundVariableSymbol(variableSymbol, identifierToken.Span));
|
parameters.Add(new BoundVariableSymbol(variableSymbol, true, identifierToken.Span));
|
||||||
innerScope.DefineLocalVariable(variableSymbol);
|
innerScope.DefineLocalVariable(variableSymbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,13 +7,15 @@ namespace Upsilon.Binder
|
||||||
{
|
{
|
||||||
public class BoundVariableSymbol : BoundExpression
|
public class BoundVariableSymbol : BoundExpression
|
||||||
{
|
{
|
||||||
public BoundVariableSymbol(VariableSymbol variableSymbol, TextSpan span) : base(span)
|
public BoundVariableSymbol(VariableSymbol variableSymbol, bool isCreation, TextSpan span) : base(span)
|
||||||
{
|
{
|
||||||
VariableSymbol = variableSymbol;
|
VariableSymbol = variableSymbol;
|
||||||
|
IsCreation = isCreation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public VariableSymbol VariableSymbol { get; }
|
public VariableSymbol VariableSymbol { get; }
|
||||||
|
|
||||||
|
public bool IsCreation { get; }
|
||||||
public override BoundKind Kind => BoundKind.BoundVariableSymbol;
|
public override BoundKind Kind => BoundKind.BoundVariableSymbol;
|
||||||
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
|
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue