Upsilon/Upsilon/Binder/BoundStatements/BoundMultiAssignmentStateme...

63 lines
2.2 KiB
C#

using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using Upsilon.BaseTypes.Number;
using Upsilon.BaseTypes.ScriptTypeInterfaces;
using Upsilon.Binder.VariableSymbols;
using Upsilon.Evaluator;
using Upsilon.Text;
namespace Upsilon.Binder
{
public class BoundMultiAssignmentStatement : BoundStatement
{
public ImmutableArray<VariableSymbol> Variables { get; }
public BoundExpression Assignment { get; }
public BoundMultiAssignmentStatement(ImmutableArray<VariableSymbol> variables, BoundExpression assignment,
TextSpan span) : base(span)
{
Variables = variables;
Assignment = assignment;
}
public override BoundKind Kind => BoundKind.BoundMultiAssignmentStatement;
public override IEnumerable<BoundNode> GetChildren()
{
yield return Assignment;
}
internal override void Evaluate(EvaluationScope scope, Diagnostics diagnostics, ref EvaluationState state)
{
var val = Assignment.Evaluate(scope, diagnostics, ref state);
if (val is IIndexable table)
{
for (var i = 0; i < Variables.Length; i++)
{
var variableSymbol = Variables[i];
if (variableSymbol == null)
continue;
if (variableSymbol.Name == "_")
continue;
var value = table.Get(diagnostics, Span, new ScriptNumberLong(i + 1), scope);
if (variableSymbol.Local)
scope.CreateLocal(variableSymbol, value);
else
scope.AssignToNearest(variableSymbol, value);
}
}
else
{
diagnostics.LogError($"Can't assign type '{val.Type}' to multiple variables.", Span);
}
}
internal override IEnumerator EvaluateCoroutine(EvaluationScope scope, Diagnostics diagnostics, EvaluationState state)
{
Evaluate(scope, diagnostics, ref state);
yield break;
}
}
}