public void AddCode(Expression expression) { expression.OperatorsHint.Clear(); int startIndex = Operations.Count; _sources.Push(expression); switch (expression) { case Command x: Commands.GenerateCode(x, this); break; case FunctionCall x: Creation.Functions.GenerateCode(x, this); break; case FunctionHeader x: Creation.Functions.GenerateCode(x, this); break; case IfHeader x: Conditional.GenerateCode(x, this); break; case LiteralArrayGet x: Literals.GenerateCode(x, this); break; case LiteralGet x: Literals.GenerateCode(x, this); break; case LoopHeader x: Conditional.GenerateCode(x, this); break; case OperatorCall x: Creation.Functions.GenerateCode(x, this); break; case ReturnE x: Commands.GenerateCode(x, this); break; case VariableAssignment x: Variables.GenerateCode(x, this); break; case VariableReference x: Variables.GenerateCode(x, this); break; case Block block: Blocks.GenerateCode(block, this); break; case Indexer indexer: Variables.GenerateCode(indexer, this); break; case ElseHeader elseHeader: Conditional.GenerateCode(elseHeader, this); break; case ElseIfHeader elseIfHeader: Conditional.GenerateCode(elseIfHeader, this); break; case Group group: Literals.GenerateCode(group, this); break; case MainHeader _: break; case null: throw new ArgumentNullException(nameof(expression)); default: throw new NotSupportedException( $"Unsupported expression type: {expression.GetType()}"); } _sources.Pop(); if (startIndex == Operations.Count) { // No operations have been added, there is no point // trying to link test commands return; } int endIndex = Operations.Count - 1; OpDebugInfo firstOp = DebugInfo[startIndex]; OpDebugInfo lastOp = DebugInfo[endIndex]; if (expression.TestsHint != null) { foreach (TestCommand command in expression.TestsHint) { if (command.IsPreOp && firstOp != null) { firstOp.AddTest(command); } else if (!command.IsPreOp && lastOp != null) { lastOp.AddTest(command); } } } }