private static IEnumerable <string> ProcessPush(Vmcmd vmcmd, Idgen idgen, string stFunc) { switch (vmcmd.Ksegment) { case Ksegment.Constant: { if (vmcmd.I.FIn(0, 1)) { yield return("@SP"); yield return("AM=M+1"); yield return("A=A-1"); yield return("M={0}".StFormat(vmcmd.I)); yield break; } else { yield return("@" + vmcmd.I); yield return("D=A"); //d = vmcmd.I break; } } case Ksegment.Local: yield return("@LCL"); if (vmcmd.I == 0) { yield return("A=M"); } else if (vmcmd.I == 1) { yield return("A=M+1"); } else { yield return("D=M"); //d = vmcmd.I yield return("@" + vmcmd.I); yield return("A=D+A"); //d = vmcmd.I } yield return("D=M"); break; case Ksegment.Argument: yield return("@ARG"); if (vmcmd.I == 0) { yield return("A=M"); } else if (vmcmd.I == 1) { yield return("A=M+1"); } else { yield return("D=M"); //d = vmcmd.I yield return("@" + vmcmd.I); yield return("A=D+A"); //d = vmcmd.I } yield return("D=M"); break; case Ksegment.This: yield return("@THIS"); if (vmcmd.I == 0) { yield return("A=M"); } else if (vmcmd.I == 1) { yield return("A=M+1"); } else { yield return("D=M"); //d = vmcmd.I yield return("@" + vmcmd.I); yield return("A=D+A"); //d = vmcmd.I } yield return("D=M"); break; case Ksegment.That: yield return("@THAT"); if (vmcmd.I == 0) { yield return("A=M"); } else if (vmcmd.I == 1) { yield return("A=M+1"); } else { yield return("D=M"); //d = vmcmd.I yield return("@" + vmcmd.I); yield return("A=D+A"); //d = vmcmd.I } yield return("D=M"); break; case Ksegment.Temp: yield return("@R5"); if (vmcmd.I == 0) { ; } else if (vmcmd.I == 1) { yield return("A=A+1"); } else { yield return("D=A"); //d = vmcmd.I yield return("@" + vmcmd.I); yield return("A=D+A"); //d = vmcmd.I } yield return("D=M"); break; case Ksegment.Pointer: yield return("@THIS"); if (vmcmd.I == 0) { ; } else if (vmcmd.I == 1) { yield return("A=A+1"); } else { yield return("D=A"); //d = vmcmd.I yield return("@" + vmcmd.I); yield return("A=D+A"); //d = vmcmd.I } yield return("D=M"); break; case Ksegment.Static: yield return("@" + idgen.Static(vmcmd.I)); yield return("D=M"); break; default: throw new ArgumentOutOfRangeException(); } yield return("@SP"); //a = &sp yield return("AM=M+1"); //sp++ yield return("A=A-1"); //a = sp-1 yield return("M=D"); //sp[-1] = d }
private static IEnumerable <string> ProcessPop(Vmcmd vmcmd, Idgen idgen, string stFunc) { if (vmcmd.Ksegment == Ksegment.Static) { yield return("@SP"); //a = &sp yield return("AM=M-1"); //sp-- yield return("D=M"); //d = sp[0] yield return("@" + idgen.Static(vmcmd.I)); yield return("M=D"); } else if (vmcmd.I == 0) { yield return("@SP"); //a = &sp yield return("AM=M-1"); //sp-- yield return("D=M"); //d = sp[0] switch (vmcmd.Ksegment) { case Ksegment.Local: yield return("@LCL"); yield return("A=M"); break; case Ksegment.Argument: yield return("@ARG"); yield return("A=M"); break; case Ksegment.This: yield return("@THIS"); yield return("A=M"); break; case Ksegment.That: yield return("@THAT"); yield return("A=M"); break; case Ksegment.Temp: yield return("@R5"); break; case Ksegment.Pointer: yield return("@THIS"); break; default: throw new ArgumentOutOfRangeException(); } yield return("M=D"); } else if (vmcmd.I == 1) { yield return("@SP"); //a = &sp yield return("AM=M-1"); //sp-- yield return("D=M"); //d = sp[0] switch (vmcmd.Ksegment) { case Ksegment.Local: yield return("@LCL"); yield return("A=M+1"); break; case Ksegment.Argument: yield return("@ARG"); yield return("A=M+1"); break; case Ksegment.This: yield return("@THIS"); yield return("A=M+1"); break; case Ksegment.That: yield return("@THAT"); yield return("A=M+1"); break; case Ksegment.Temp: yield return("@R5"); yield return("A=A+1"); break; case Ksegment.Pointer: yield return("@THIS"); yield return("A=A+1"); break; default: throw new ArgumentOutOfRangeException(); } yield return("M=D"); } else { switch (vmcmd.Ksegment) { case Ksegment.Local: yield return("@LCL"); yield return("D=M"); break; case Ksegment.Argument: yield return("@ARG"); yield return("D=M"); break; case Ksegment.This: yield return("@THIS"); yield return("D=M"); break; case Ksegment.That: yield return("@THAT"); yield return("D=M"); break; case Ksegment.Temp: yield return("@R5"); yield return("D=A"); break; case Ksegment.Pointer: yield return("@THIS"); yield return("D=A"); break; default: throw new ArgumentOutOfRangeException(); } yield return("@" + vmcmd.I); yield return("D=D+A"); yield return("@R13"); yield return("M=D"); yield return("@SP"); //a = &sp yield return("AM=M-1"); //sp-- yield return("D=M"); //d = sp[0] yield return("@R13"); yield return("A=M"); yield return("M=D"); } }