import edu.arizona.cs.mbel.mbel.*;
import edu.arizona.cs.mbel.instructions.*;
import edu.arizona.cs.mbel.signature.*;

public class example1{
   public void makeFactorial(TypeDef def){
      MethodSignature sig=null;
      LocalVarList locals=null;
      try{
         ParameterSignature nParam = new ParameterSignature(TypeSignature.I4, false);
         nParam.setParameterInfo(new ParameterInfo("n", 0));
         sig = new MethodSignature(
            new ReturnTypeSignature(TypeSignature.I4, false),
            new ParameterSignature[]{nParam}
         );

         locals = new LocalVarList(
            new LocalVar[]{
               new LocalVar(false, TypeSignature.I4)
            }
         );
      }catch(SignatureException se){}

      Method factorial = new Method("factorial", Method.IL,
                                    Method.Public|Method.HideBySig, 
                                    sig);

      MethodBody body = new MethodBody(false, 10, locals);
      factorial.setMethodBody(body);

      InstructionList ilist = body.getInstructionList();
      ilist.append(new LDARG(LDARG.LDARG_1));
      ilist.append(new LDC(LDC.LDC_I4_0));

      InstructionHandle target1 = new InstructionHandle(
                                     new LDARG(LDARG.LDARG_1)
                                  );
      ilist.append(new BGT(true, false, target1));

      ilist.append(new LDC(LDC.LDC_I4_1));
      ilist.append(new STLOC(STLOC.STLOC_0));

      InstructionHandle target2 = new InstructionHandle(
                                     new LDLOC(LDLOC.LDLOC_0)
                                  );
      ilist.append(new BR(true, target2));
      ilist.append(target1);
      ilist.append(new LDARG(LDARG.LDARG_0));
      ilist.append(new LDARG(LDARG.LDARG_1));
      ilist.append(new LDC(LDC.LDC_I4_1));
      ilist.append(new SUB());
      ilist.append(new CALL(factorial));
      ilist.append(new MUL());
      ilist.append(new STLOC(STLOC.STLOC_0));
      ilist.append(new BR(true, target2));
      ilist.append(target2);
      ilist.append(new RET());

      def.addMethod(factorial);
   }
}


