private IEnumerable <string> ProcessEqGtLt(Vmcmd vmcmd, Idgen idgen, string stFunc) { var idAfter = idgen.Id(); yield return("@" + idAfter); yield return("D=A"); switch (vmcmd.Kcmd) { case Kcmd.Eq: yield return("@" + lblEq); break; case Kcmd.Gt: yield return("@" + lblGt); break; case Kcmd.Lt: yield return("@" + lblLt); break; } yield return("D;JMP"); yield return("(" + idAfter + ")"); }
private static IEnumerable <string> ProcessIfGoto(Vmcmd vmcmd, Idgen idgen, string stFunc) { yield return("@SP"); yield return("AM=M-1"); //yield return "A=M"; yield return("D=M"); yield return("@" + stFunc + "$" + vmcmd.StLabel); yield return("D;JNE"); }
private IEnumerable <string> ProcessCall(Vmcmd vmcmd, Idgen idgen, string stFunc) { var lblNext = idgen.Id("after_call"); yield return("//r14: hány argumentum van a veremben"); yield return("//r15: hova kell ugrani"); yield return("//D: hova kell visszatérni"); if (vmcmd.I == 0) { yield return("@R14"); yield return("M=0"); } else if (vmcmd.I == 1) { yield return("@R14"); yield return("M=1"); } else { yield return("@" + vmcmd.I); yield return("D=A"); yield return("@R14"); yield return("M=D"); } yield return("@" + idgen.Fun(vmcmd.StFn)); yield return("D=A"); yield return("@R15"); yield return("M=D"); yield return("@" + lblNext); yield return("D=A"); yield return("@" + lblFunCall); yield return("D;JMP"); yield return("(" + lblNext + ")"); }
private static IEnumerable <string> ProcessNegNot(Vmcmd vmcmd, Idgen idgen, string stFunc) { yield return("@SP"); //a = &sp yield return("A=M-1"); //a = sp - 1 if (vmcmd.Kcmd == Kcmd.Neg) { yield return("M=-M"); //d = -sp[-1] } else { yield return("M=!M"); //d = !sp[-1] } }
private static IEnumerable <string> ProcessFunction(Vmcmd vmcmd, Idgen idgen, string stFunc) { yield return("(" + idgen.Fun(vmcmd.StFn) + ")"); for (int k = 0; k < vmcmd.I; k++) { yield return("//push 0"); yield return("@SP"); yield return("AM=M+1"); yield return("A=A-1"); yield return("M=0"); } }
private static IEnumerable <string> ProcessAddSubAndOr(Vmcmd vmcmd, Idgen idgen, string stFunc) { yield return("@SP"); //a = &sp yield return("A=M-1"); //a = sp - 1 yield return("D=M"); //d = sp[-1] yield return("A=A-1"); //a = sp - 2 switch (vmcmd.Kcmd) { case Kcmd.Add: yield return("M=D+M"); //sp[-2] = sp[-1] + sp[-2] break; case Kcmd.Sub: yield return("M=M-D"); //sp[-2] = sp[-2] - sp[-1] break; case Kcmd.And: yield return("M=D&M"); //sp[-2] = sp[-1] + sp[-2] break; case Kcmd.Or: yield return("M=D|M"); //sp[-2] = sp[-1] + sp[-2] break; } yield return("@SP"); //a = &sp yield return("M=M-1"); //sp = sp - 1 }
private IEnumerable <Vmcmd> EnvmcdParse(string src) { return(src.ToLinesSkipComments().Select(stLine => Vmcmd.Fetch(stLine.ToWords()))); }
private static IEnumerable <string> ProcessLabel(Vmcmd vmcmd, Idgen idgen, string stFunc) { yield return("(" + stFunc + "$" + vmcmd.StLabel + ")"); }
private static IEnumerable <string> ProcessGoto(Vmcmd vmcmd, Idgen idgen, string stFunc) { yield return("@" + stFunc + "$" + vmcmd.StLabel); yield return("D;JMP"); }
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"); } }
private IEnumerable <string> ProcessReturn(Vmcmd vmcmd, Idgen idgen, string stFunc) { yield return("@" + lblReturn); yield return("0;JMP"); }