Beispiel #1
0
        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 + ")");
        }
Beispiel #2
0
        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");
        }
Beispiel #3
0
        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 + ")");
        }
Beispiel #4
0
        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]
            }
        }
Beispiel #5
0
        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");
            }
        }
Beispiel #6
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
        }
Beispiel #7
0
 private IEnumerable <Vmcmd> EnvmcdParse(string src)
 {
     return(src.ToLinesSkipComments().Select(stLine => Vmcmd.Fetch(stLine.ToWords())));
 }
Beispiel #8
0
 private static IEnumerable <string> ProcessLabel(Vmcmd vmcmd, Idgen idgen, string stFunc)
 {
     yield return("(" + stFunc + "$" + vmcmd.StLabel + ")");
 }
Beispiel #9
0
        private static IEnumerable <string> ProcessGoto(Vmcmd vmcmd, Idgen idgen, string stFunc)
        {
            yield return("@" + stFunc + "$" + vmcmd.StLabel);

            yield return("D;JMP");
        }
Beispiel #10
0
        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
        }
Beispiel #11
0
        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");
            }
        }
Beispiel #12
0
        private IEnumerable <string> ProcessReturn(Vmcmd vmcmd, Idgen idgen, string stFunc)
        {
            yield return("@" + lblReturn);

            yield return("0;JMP");
        }