Bind whether a variable symbol is a creation statement or just changing the variable

This commit is contained in:
Deukhoofd 2018-12-02 17:26:23 +01:00
parent 07a71129a2
commit a9f4ef1b65
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
2 changed files with 21 additions and 15 deletions

View File

@ -283,7 +283,7 @@ namespace Upsilon.Binder
_diagnostics.LogUnknownVariable(e.Identifier.Span, name);
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);
}
@ -293,10 +293,11 @@ namespace Upsilon.Binder
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 == "_")
return null;
return (null, false);
var isCreation = false;
if (!Scope.TryGetVariable(name, !isLocal, out var variable))
{
if (assignment.Type == Type.Table)
@ -323,6 +324,8 @@ namespace Upsilon.Binder
Scope.DefineLocalVariable(variable);
else
Scope.AssignToNearest(variable);
isCreation = true;
}
else
{
@ -347,11 +350,11 @@ namespace Upsilon.Binder
else
{
_diagnostics.LogCannotConvert(assignment.Type, variable.Type, assignment.Span);
return null;
return (null, false);
}
}
}
return variable;
return (variable, isCreation);
}
private BoundStatement BindAssignmentStatement(AssignmentStatementSyntax e)
@ -363,14 +366,15 @@ namespace Upsilon.Binder
var boundExpression = BindExpression(e.Expression);
var isLocal = e.LocalToken != null;
var boundVariable = TryBindVariable(name, isLocal, boundExpression, e.CommentData);
if (boundVariable != null)
var (symbol, isCreation) = TryBindVariable(name, isLocal, boundExpression, e.CommentData);
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);
}
}
@ -387,11 +391,11 @@ namespace Upsilon.Binder
foreach (var identifierToken in s.Identifiers)
{
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);
}
@ -461,7 +465,7 @@ namespace Upsilon.Binder
{
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);
}

View File

@ -7,13 +7,15 @@ namespace Upsilon.Binder
{
public class BoundVariableSymbol : BoundExpression
{
public BoundVariableSymbol(VariableSymbol variableSymbol, TextSpan span) : base(span)
public BoundVariableSymbol(VariableSymbol variableSymbol, bool isCreation, TextSpan span) : base(span)
{
VariableSymbol = variableSymbol;
IsCreation = isCreation;
}
public VariableSymbol VariableSymbol { get; }
public bool IsCreation { get; }
public override BoundKind Kind => BoundKind.BoundVariableSymbol;
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{