82 lines
2.6 KiB
C#
82 lines
2.6 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using Upsilon.BaseTypes;
|
|
using Upsilon.Evaluator;
|
|
using Upsilon.Text;
|
|
|
|
namespace Upsilon.Binder
|
|
{
|
|
internal class BoundWhileStatement : BoundStatement
|
|
{
|
|
public BoundExpression Condition { get; }
|
|
public BoundStatement Block { get; }
|
|
|
|
public BoundWhileStatement(BoundExpression condition, BoundStatement block, TextSpan eSpan)
|
|
:base(eSpan)
|
|
{
|
|
Condition = condition;
|
|
Block = block;
|
|
}
|
|
|
|
public override BoundKind Kind => BoundKind.BoundWhileStatement;
|
|
|
|
public override IEnumerable<BoundNode> GetChildren()
|
|
{
|
|
yield return Condition;
|
|
yield return Block;
|
|
}
|
|
|
|
internal override void Evaluate(EvaluationScope outerScope, Diagnostics diagnostics, ref EvaluationState outerState)
|
|
{
|
|
var innerScope = new EvaluationScope(outerScope);
|
|
var innerState = new EvaluationState()
|
|
{
|
|
Script = outerState.Script
|
|
};
|
|
|
|
|
|
while ((ScriptBoolean) Condition.Evaluate(innerScope, diagnostics, ref innerState))
|
|
{
|
|
Block.Evaluate(innerScope, diagnostics, ref innerState);
|
|
if (innerState.HasBroken || innerState.Returned)
|
|
{
|
|
if (innerState.Returned)
|
|
{
|
|
outerState.Returned = true;
|
|
outerState.ReturnValue = innerState.ReturnValue;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
internal override IEnumerator EvaluateCoroutine(EvaluationScope outerScope, Diagnostics diagnostics, EvaluationState outerState)
|
|
{
|
|
var innerScope = new EvaluationScope(outerScope);
|
|
var innerState = new EvaluationState()
|
|
{
|
|
Script = outerState.Script
|
|
};
|
|
|
|
|
|
while ((ScriptBoolean) Condition.Evaluate(innerScope, diagnostics, ref innerState))
|
|
{
|
|
var coroutine = Block.EvaluateCoroutine(innerScope, diagnostics, innerState);
|
|
while (coroutine.MoveNext())
|
|
{
|
|
yield return coroutine.Current;
|
|
}
|
|
if (innerState.HasBroken || innerState.Returned)
|
|
{
|
|
if (innerState.Returned)
|
|
{
|
|
outerState.Returned = true;
|
|
outerState.ReturnValue = innerState.ReturnValue;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |