Jsm.ExecutableSegment.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. using OpenVIII.Fields.Scripts.Instructions;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. namespace OpenVIII.Fields.Scripts
  6. {
  7. public static partial class Jsm
  8. {
  9. #region Classes
  10. public class ExecutableSegment : Segment, IJsmInstruction, IEnumerable<IJsmInstruction>
  11. {
  12. #region Constructors
  13. public ExecutableSegment(int from, int to)
  14. : base(from, to)
  15. {
  16. }
  17. #endregion Constructors
  18. #region Methods
  19. public IEnumerator<IJsmInstruction> GetEnumerator() => _list.GetEnumerator();
  20. IEnumerator IEnumerable.GetEnumerator() => _list.GetEnumerator();
  21. public virtual IScriptExecutor GetExecuter() => GetExecuter(_list);
  22. internal static IScriptExecutor GetExecuter(IEnumerable<IJsmInstruction> instructions) => new Executor(instructions);
  23. #endregion Methods
  24. #region Classes
  25. private sealed class Executor : IScriptExecutor, IEnumerable<IJsmInstruction>
  26. {
  27. #region Fields
  28. private readonly IEnumerable<IJsmInstruction> _list;
  29. #endregion Fields
  30. #region Constructors
  31. public Executor(IEnumerable<IJsmInstruction> list) => _list = list;
  32. #endregion Constructors
  33. #region Methods
  34. public IEnumerable<IAwaitable> Execute(IServices services)
  35. {
  36. foreach (var instr in _list)
  37. {
  38. if (instr is JsmInstruction singleInstruction)
  39. {
  40. yield return singleInstruction.Execute(services);
  41. }
  42. else if (instr is ExecutableSegment segment)
  43. {
  44. // TODO: Change recursion to the loop
  45. var nested = segment.GetExecuter();
  46. foreach (var result in nested.Execute(services))
  47. yield return result;
  48. }
  49. else
  50. {
  51. throw new NotSupportedException($"Cannot execute instruction [{instr}] of type [{instr.GetType()}].");
  52. }
  53. }
  54. }
  55. public IEnumerator<IJsmInstruction> GetEnumerator() => _list.GetEnumerator();
  56. IEnumerator IEnumerable.GetEnumerator() => _list.GetEnumerator();
  57. #endregion Methods
  58. }
  59. #endregion Classes
  60. }
  61. #endregion Classes
  62. }
  63. }