private static IEnumerable <string> GenerateEqGtLt(Idgen idgen, string lbl, string kjmp) { yield return("(" + lbl + ")"); yield return("@R14"); //a = &sp yield return("M=D"); 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 yield return("D=M-D"); var idTrue = idgen.Id(); var idAfter = idgen.Id(); yield return("@" + idTrue); yield return("D;" + kjmp); yield return("@" + idAfter); yield return("D=0;JEQ"); yield return("(" + idTrue + ")"); yield return("D=-1"); yield return("(" + idAfter + ")"); yield return("@SP"); //a = &sp yield return("M=M-1"); //sp-- yield return("A=M-1"); //a = sp-1 yield return("M=D"); //sp[-1] = d yield return("@R14"); yield return("A=M"); yield return("D;JMP"); }
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 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 IEnumerable <string> Bootstrap(Idgen idgen) { lblFunCall = idgen.Id("funcall"); lblReturn = idgen.Id("return"); lblEq = idgen.Id("eq"); lblGt = idgen.Id("gt"); lblLt = idgen.Id("lt"); var lblEnd = idgen.Id("end"); yield return("//SP=256"); yield return("@256"); yield return("D=A"); yield return("@0"); yield return("M=D"); idgen.filn = "Sys.vm"; foreach (var st in ProcessCall(new Vmcmd(Kcmd.Call, Ksegment.Nil, 0, "Sys.init"), idgen, null)) { yield return(st); } idgen.filn = null; yield return("(" + lblEnd + ")"); yield return("@" + lblEnd); yield return("0;JMP"); foreach (var st in GenerateEqGtLt(idgen, lblEq, "JEQ")) { yield return(st); } foreach (var st in GenerateEqGtLt(idgen, lblGt, "JGT")) { yield return(st); } foreach (var st in GenerateEqGtLt(idgen, lblLt, "JLT")) { yield return(st); } foreach (var st in GenerateFunCall()) { yield return(st); } foreach (var st in GenerateReturn()) { yield return(st); } }