コード例 #1
0
ファイル: VMTranslator.cs プロジェクト: encse/nand2tetris
        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
        }
コード例 #2
0
ファイル: VMTranslator.cs プロジェクト: encse/nand2tetris
        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");
            }
        }