AstBlock.cs
1 using Ryujinx.Graphics.Shader.IntermediateRepresentation; 2 using System; 3 using System.Collections; 4 using System.Collections.Generic; 5 6 using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper; 7 8 namespace Ryujinx.Graphics.Shader.StructuredIr 9 { 10 class AstBlock : AstNode, IEnumerable<IAstNode> 11 { 12 public AstBlockType Type { get; private set; } 13 14 private IAstNode _condition; 15 16 public IAstNode Condition 17 { 18 get 19 { 20 return _condition; 21 } 22 set 23 { 24 RemoveUse(_condition, this); 25 26 AddUse(value, this); 27 28 _condition = value; 29 } 30 } 31 32 private readonly LinkedList<IAstNode> _nodes; 33 34 public IAstNode First => _nodes.First?.Value; 35 public IAstNode Last => _nodes.Last?.Value; 36 37 public int Count => _nodes.Count; 38 39 public AstBlock(AstBlockType type, IAstNode condition = null) 40 { 41 Type = type; 42 Condition = condition; 43 44 _nodes = new LinkedList<IAstNode>(); 45 } 46 47 public void Add(IAstNode node) 48 { 49 Add(node, _nodes.AddLast(node)); 50 } 51 52 public void AddFirst(IAstNode node) 53 { 54 Add(node, _nodes.AddFirst(node)); 55 } 56 57 public void AddBefore(IAstNode next, IAstNode node) 58 { 59 Add(node, _nodes.AddBefore(next.LLNode, node)); 60 } 61 62 public void AddAfter(IAstNode prev, IAstNode node) 63 { 64 Add(node, _nodes.AddAfter(prev.LLNode, node)); 65 } 66 67 private void Add(IAstNode node, LinkedListNode<IAstNode> newNode) 68 { 69 if (node.Parent != null) 70 { 71 throw new ArgumentException("Node already belongs to a block."); 72 } 73 74 node.Parent = this; 75 node.LLNode = newNode; 76 } 77 78 public void Remove(IAstNode node) 79 { 80 _nodes.Remove(node.LLNode); 81 82 node.Parent = null; 83 node.LLNode = null; 84 } 85 86 public void AndCondition(IAstNode cond) 87 { 88 Condition = new AstOperation(Instruction.LogicalAnd, Condition, cond); 89 } 90 91 public void OrCondition(IAstNode cond) 92 { 93 Condition = new AstOperation(Instruction.LogicalOr, Condition, cond); 94 } 95 public void TurnIntoIf(IAstNode cond) 96 { 97 Condition = cond; 98 99 Type = AstBlockType.If; 100 } 101 102 public void TurnIntoElseIf() 103 { 104 Type = AstBlockType.ElseIf; 105 } 106 107 public IEnumerator<IAstNode> GetEnumerator() 108 { 109 return _nodes.GetEnumerator(); 110 } 111 112 IEnumerator IEnumerable.GetEnumerator() 113 { 114 return GetEnumerator(); 115 } 116 } 117 }