using System.Collections; using System.Collections.Generic; using Upsilon.BaseTypes; using Upsilon.Evaluator; using Upsilon.Text; namespace Upsilon.Binder { public class BoundIfStatement : BoundStatement { public BoundIfStatement(BoundExpressionStatement condition, BoundBlockStatement block, TextSpan span): base(span) { Condition = condition; Block = block; } public BoundIfStatement(BoundExpressionStatement condition, BoundBlockStatement block, BoundElseStatement elseStatement, TextSpan span) : base(span) { Condition = condition; Block = block; ElseStatement = elseStatement; } public BoundIfStatement(BoundExpressionStatement condition, BoundBlockStatement block, BoundIfStatement nextElseIf, TextSpan span) : base(span) { Condition = condition; Block = block; NextElseIf = nextElseIf; } public override BoundKind Kind => BoundKind.BoundIfStatement; public override IEnumerable GetChildren() { yield return Condition; yield return Block; if (NextElseIf != null) yield return NextElseIf; if (ElseStatement != null) yield return ElseStatement; } public BoundExpressionStatement Condition { get; } public BoundBlockStatement Block { get; } public BoundIfStatement NextElseIf { get; } public BoundElseStatement ElseStatement { get; } internal override void Evaluate(EvaluationScope scope, Diagnostics diagnostics, ref EvaluationState state) { var condition = Condition.Expression.Evaluate(scope, diagnostics, ref state); if ((ScriptBoolean) condition) { Block.Evaluate(scope, diagnostics, ref state); } else if (NextElseIf != null) { NextElseIf.Evaluate(scope, diagnostics, ref state); } else { ElseStatement?.Evaluate(scope, diagnostics, ref state); } } internal override IEnumerator EvaluateCoroutine(EvaluationScope scope, Diagnostics diagnostics, EvaluationState state) { var condition = Condition.Expression.Evaluate(scope, diagnostics, ref state); if ((ScriptBoolean) condition) { yield return Block.EvaluateCoroutine(scope, diagnostics, state); } if (NextElseIf != null) { yield return NextElseIf.EvaluateCoroutine(scope, diagnostics, state); } if (ElseStatement != null) { yield return ElseStatement.EvaluateCoroutine(scope, diagnostics, state); } } } public class BoundElseStatement : BoundStatement { public BoundBlockStatement Block { get; } public BoundElseStatement(BoundBlockStatement block, TextSpan span) : base(span) { Block = block; } public override BoundKind Kind => BoundKind.BoundElseStatement; public override IEnumerable GetChildren() { yield return Block; } internal override void Evaluate(EvaluationScope scope, Diagnostics diagnostics, ref EvaluationState state) { Block.Evaluate(scope, diagnostics, ref state); } internal override IEnumerator EvaluateCoroutine(EvaluationScope scope, Diagnostics diagnostics, EvaluationState state) { return Block.EvaluateCoroutine(scope, diagnostics, state); } } }