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  }