// mcs -r:Mono.Cecil.dll test.cs
using System;

using Mono.Cecil;
using Mono.Cecil.Cil;

public class Test {
    
    public static void Main (string [] args)
    {
        IAssemblyDefinition asm = AssemblyFactory.GetAssembly ("test.exe", LoadingType.Lazy);
        ITypeDefinition test = asm.MainModule.Types ["Test"];
        foreach (IMethodDefinition meth in test.Methods) {
            
            Console.WriteLine (meth.ToString ());
            Console.WriteLine ("{");
            Console.WriteLine ("  // code size : {0}", meth.Body.CodeSize);
            Console.WriteLine ("  .maxstack {0}", meth.Body.MaxStack);
            Console.Write ("  .locals (");
            for (int i = 0; i < meth.Body.Variables.Count; i++) {
                if (i > 0)
                    Console.Write (", ");
                IVariableDefinition var = meth.Body.Variables [i];
                Console.Write (string.Concat(var.Variable.FullName, " ", var.Name));
            }
            Console.WriteLine (")");
            
            foreach (IInstruction instr in meth.Body.Instructions) {
                Console.Write ("  IL_{0}: {1} ", instr.Offset.ToString ("X4"), instr.OpCode.Name);
                switch (instr.OpCode.OperandType) {
                    case OperandType.InlineNone :
                        Console.WriteLine (""); break;
                    case OperandType.InlineSwitch :
                        int [] brchs = instr.Operand as int [];
                        for (int i = 0; i < brchs.Length; i++) {
                            if (i > 0)
                                Console.Write (", ");
                            Console.Write ("IL_{0}", brchs [i].ToString ("X4"));
                        }
                        Console.WriteLine ("");
                        break;
                    case OperandType.ShortInlineBrTarget :
                    case OperandType.InlineBrTarget :
                        Console.WriteLine ("IL_{0}", ((int)instr.Operand).ToString ("X4")); break;
                    case OperandType.InlineString :
                        Console.WriteLine ("\"{0}\"", instr.Operand); break;
                    default :
                        Console.WriteLine (instr.Operand); break;
                }
            }
            Console.WriteLine ("}");
            Console.WriteLine ("");
        }
    }
}