Upsilon/Upsilon/Binder/BoundStatements/BoundTableAssigmentStatemen...

62 lines
2.2 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using Upsilon.BaseTypes;
using Upsilon.BaseTypes.ScriptTypeInterfaces;
using Upsilon.Evaluator;
using Upsilon.Text;
namespace Upsilon.Binder
{
public class BoundTableAssigmentStatement : BoundStatement
{
public BoundExpression TableIndexExpression { get; }
public BoundExpression Value { get; }
public BoundTableAssigmentStatement(BoundExpression tableIndexExpression, BoundExpression value,
TextSpan span) : base(span)
{
TableIndexExpression = tableIndexExpression;
Value = value;
}
public override BoundKind Kind => BoundKind.BoundTableAssigmentStatement;
public override IEnumerable<BoundNode> GetChildren()
{
yield return TableIndexExpression;
yield return Value;
}
internal override void Evaluate(EvaluationScope scope, Diagnostics diagnostics, ref EvaluationState state)
{
ScriptType table;
ScriptType index;
if (TableIndexExpression.Kind == BoundKind.BoundIndexExpression)
{
var indexExpression = (BoundIndexExpression)TableIndexExpression;
table = indexExpression.Identifier.Evaluate(scope, diagnostics, ref state);
index = indexExpression.Index.Evaluate(scope, diagnostics, ref state);
}
else
{
var fullStopIndexExpression = (BoundFullStopIndexExpression) TableIndexExpression;
table = fullStopIndexExpression.Expression.Evaluate(scope, diagnostics, ref state);
index = fullStopIndexExpression.Index.ToScriptType();
}
var value = Value.Evaluate(scope, diagnostics, ref state);
if (!(table is IIndexable indexable))
{
throw new Exception("Cant assign to that");
}
indexable.Set(diagnostics, Span, index.ToString().ToScriptType(), value);
}
internal override IEnumerator EvaluateCoroutine(EvaluationScope scope, Diagnostics diagnostics, EvaluationState state)
{
Evaluate(scope, diagnostics, ref state);
yield break;
}
}
}