From a9f4ef1b65e2ae81527d15ed16f712e3b42708a4 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Sun, 2 Dec 2018 17:26:23 +0100 Subject: [PATCH] Bind whether a variable symbol is a creation statement or just changing the variable --- Upsilon/Binder/Binder.cs | 32 +++++++++++++++------------ Upsilon/Binder/BoundVariableSymbol.cs | 4 +++- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/Upsilon/Binder/Binder.cs b/Upsilon/Binder/Binder.cs index ae97fb1..7ad3ca8 100644 --- a/Upsilon/Binder/Binder.cs +++ b/Upsilon/Binder/Binder.cs @@ -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); } diff --git a/Upsilon/Binder/BoundVariableSymbol.cs b/Upsilon/Binder/BoundVariableSymbol.cs index 32b0bde..7bda29d 100644 --- a/Upsilon/Binder/BoundVariableSymbol.cs +++ b/Upsilon/Binder/BoundVariableSymbol.cs @@ -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 GetNodeAtPosition(int characterPosition) {