private static void PrintBlock(CodeGenContext context, AstBlock block) { AstBlockVisitor visitor = new AstBlockVisitor(block); visitor.BlockEntered += (sender, e) => { switch (e.Block.Type) { case AstBlockType.DoWhile: context.AppendLine("do"); break; case AstBlockType.Else: context.AppendLine("else"); break; case AstBlockType.ElseIf: context.AppendLine($"else if ({GetCondExpr(context, e.Block.Condition)})"); break; case AstBlockType.If: context.AppendLine($"if ({GetCondExpr(context, e.Block.Condition)})"); break; default: throw new InvalidOperationException($"Found unexpected block type \"{e.Block.Type}\"."); } context.EnterScope(); }; visitor.BlockLeft += (sender, e) => { context.LeaveScope(); if (e.Block.Type == AstBlockType.DoWhile) { context.AppendLine($"while ({GetCondExpr(context, e.Block.Condition)});"); } }; foreach (IAstNode node in visitor.Visit()) { if (node is AstOperation operation) { context.AppendLine(InstGen.GetExpression(context, operation) + ";"); } else if (node is AstAssignment assignment) { VariableType srcType = OperandManager.GetNodeDestType(assignment.Source); VariableType dstType = OperandManager.GetNodeDestType(assignment.Destination); string dest; if (assignment.Destination is AstOperand operand && operand.Type == OperandType.Attribute) { dest = OperandManager.GetOutAttributeName(operand, context.Config); } else { dest = InstGen.GetExpression(context, assignment.Destination); } string src = ReinterpretCast(context, assignment.Source, srcType, dstType); context.AppendLine(dest + " = " + src + ";"); }