Jsm.InstructionMerger.cs 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. using OpenVIII.Fields.Scripts.Instructions;
  2. using System.Collections.Generic;
  3. namespace OpenVIII.Fields.Scripts
  4. {
  5. public static partial class Jsm
  6. {
  7. #region Classes
  8. public static class InstructionMerger
  9. {
  10. #region Methods
  11. public static List<JsmInstruction> Merge(List<JsmInstruction> instructions, HashSet<int> labelIndices)
  12. {
  13. var result = new List<JsmInstruction>(instructions.Count);
  14. for (var i = 0; i < instructions.Count; i++)
  15. {
  16. var instruction = instructions[i];
  17. result.Add(instruction);
  18. if (labelIndices.Contains(i))
  19. continue;
  20. if (!(instructions[i] is JPF newJpf))
  21. continue;
  22. if (i + 1 < instructions.Count && instructions[i + 1] is JMP nextJmp)
  23. newJpf.Inverse(nextJmp);
  24. if (!(result[result.Count - 2] is JPF oldJpf))
  25. continue;
  26. if (oldJpf.Index != newJpf.Index)
  27. continue;
  28. var currentIndex = result.LastIndex();
  29. oldJpf.Union(newJpf);
  30. result.RemoveLast();
  31. oldJpf.Index--;
  32. for (var k = 0; k < instructions.Count; k++)
  33. {
  34. if (instructions[k] is IJumpToInstruction jmp && jmp.Index >= currentIndex && jmp != oldJpf)
  35. jmp.Index--;
  36. }
  37. }
  38. return result;
  39. }
  40. #endregion Methods
  41. }
  42. #endregion Classes
  43. }
  44. }