예제 #1
0
        static void GenericExplanation()
        {
            IntegerStack iStack = new IntegerStack(5);

            iStack.Push(0);
            iStack.Push(100);
            iStack.Push(1000);

            int element = iStack.Pop();

            Console.WriteLine(element);

            element = iStack.Pop();
            Console.WriteLine(element);

            element = iStack.Pop();
            Console.WriteLine(element);

            GeneralPurposeStack gStack = new GeneralPurposeStack(5);

            gStack.Push("ABCD");
            gStack.Push("jj");
            gStack.Push("kk");

            string element1 = (string)gStack.Pop();


            GenericStack <int> genericIntStack = new GenericStack <int>(5);

            genericIntStack.Push(0);
            genericIntStack.Push(1);

            int element22 = genericIntStack.Pop();

            Console.WriteLine(element);

            element = genericIntStack.Pop();
            Console.WriteLine(element);

            GenericStack <Person> pStack = new GenericStack <Person>(5);


            pStack.Push(new Person {
                FirstName = "ABCD"
            });
            pStack.Push(new Person {
                FirstName = "DEFG"
            });

            Person element122 = pStack.Pop();

            Console.WriteLine(element122.FirstName);

            element122 = pStack.Pop();
            Console.WriteLine(element122.FirstName);
        }
예제 #2
0
        public void PushPopTwiceTest()
        {
            var intStack = new IntegerStack();

            intStack.Push(2);
            intStack.Push(2);
            intStack.Push(1);
            intStack.Push(1);

            intStack.Pop();
            intStack.Pop();

            var mininumInt = intStack.Min();

            Assert.AreEqual(2, mininumInt);
        }
예제 #3
0
        private void Calc(Func <int, int, int> cfunc)
        {
            var e1 = IntegerStack.Pop();
            var e2 = IntegerStack.Pop();
            var e  = cfunc(e1, e2);

            IntegerStack.Push(e);
        }
예제 #4
0
        public void PushPopTest()
        {
            var intStack = new IntegerStack();

            var expectedInt = 12345;

            intStack.Push(expectedInt);
            var popInt = intStack.Pop();

            Assert.AreEqual(expectedInt, popInt);
        }
예제 #5
0
        public void PopMinimumTest()
        {
            var intStack = new IntegerStack();

            intStack.Push(1);
            intStack.Push(2);
            intStack.Push(3);
            intStack.Push(4);
            intStack.Push(5);

            var poppedInt  = intStack.Pop();
            var mininumInt = intStack.Min();

            Assert.AreEqual(1, mininumInt);
        }
예제 #6
0
        public void PushShuffleTwicePopTest()
        {
            var intStack = new IntegerStack();

            intStack.Push(3);
            intStack.Push(7);
            intStack.Push(5);
            intStack.Push(1);
            intStack.Push(6);
            intStack.Push(1);

            intStack.Pop();

            var mininumInt = intStack.Min();

            Assert.AreEqual(1, mininumInt);
        }
예제 #7
0
        public SpellburstRuntimeError Run()
        {
            var mode = ReadMode.WaitIMP;

            var IMP     = new SpellburstIMP();
            var Command = new SpellburstCommand();
            var Number  = new SpellburstNumber();
            var Label   = new SpellburstLabel();

            var ProgramCounter = 0;

            var RoutineMaxDepth = 31;
            var RoutineNowDepth = 0;

            var LabelTemp = 0;

            Action reset = () => { IMP.Reset(); Command.Reset(); Number.Reset(); Label.Reset(); mode = ReadMode.WaitIMP; };

            while (Codes.Count != 0)
            {
                if (ProgramCounter >= Codes.Count)
                {
                    break;
                }
                var first = Codes[ProgramCounter];


                switch (mode)
                {
                case ReadMode.WaitIMP:
                    IMP.AddIMP(first);

                    if (IMP.IsEqualTo("S"))
                    {
                        mode = ReadMode.WaitCommand;
                    }
                    if (IMP.IsEqualTo("N"))
                    {
                        mode = ReadMode.WaitCommand;
                    }
                    if (IMP.IsEqualTo("TS"))
                    {
                        mode = ReadMode.WaitCommand;
                    }
                    if (IMP.IsEqualTo("TN"))
                    {
                        mode = ReadMode.WaitCommand;
                    }
                    if (IMP.IsEqualTo("TT"))
                    {
                        mode = ReadMode.WaitCommand;
                    }
                    break;

                case ReadMode.WaitCommand:
                    Command.AddCommand(first);

                    //楽なのを先に処理
                    if (IMP.IsEqualTo("TT"))
                    {
                        //スタックの値をアドレスに格納
                        if (Command.IsEqualTo("S"))
                        {
                            if (CheckStackEmpty())
                            {
                                return(new SpellburstRuntimeError(ErrorType.StackIsEmpty));
                            }
                            Heap = IntegerStack.Peek();
                            reset();
                        }
                        //アドレスの値をスタックに積む
                        if (Command.IsEqualTo("T"))
                        {
                            IntegerStack.Push(Heap);
                            reset();
                        }
                    }
                    //ここから本題

                    //スタック操作
                    if (IMP.IsEqualTo("S"))
                    {
                        //数値をスタックにプッシュ(ReadMode.InputIntegerの方で処理は行う)
                        if (Command.IsEqualTo("S"))
                        {
                            mode = ReadMode.InputInteger;
                        }
                        //スタックトップを複製
                        if (Command.IsEqualTo("NS"))
                        {
                            IntegerStack.Push(IntegerStack.Peek());
                            reset();
                        }
                        //スタックの1番目と2番目を交換
                        if (Command.IsEqualTo("NT"))
                        {
                            var e1 = IntegerStack.Pop();
                            var e2 = IntegerStack.Pop();
                            IntegerStack.Push(e1);
                            IntegerStack.Push(e2);

                            reset();
                        }
                        //スタックトップを破棄
                        if (Command.IsEqualTo("NN"))
                        {
                            IntegerStack.Pop();

                            reset();
                        }
                    }
                    //四則演算+余
                    if (IMP.IsEqualTo("TS"))
                    {
                        //加減乗除余
                        if (Command.IsEqualTo("SS"))
                        {
                            Calc((e1, e2) => e1 + e2);
                            reset();
                        }
                        if (Command.IsEqualTo("ST"))
                        {
                            Calc((e1, e2) => e1 - e2);
                            reset();
                        }
                        if (Command.IsEqualTo("SN"))
                        {
                            Calc((e1, e2) => e1 * e2);
                            reset();
                        }
                        if (Command.IsEqualTo("TS"))
                        {
                            Calc((e1, e2) => e1 / e2);
                            reset();
                        }
                        if (Command.IsEqualTo("TT"))
                        {
                            Calc((e1, e2) => e1 % e2);
                            reset();
                        }
                    }

                    //ラベル
                    if (IMP.IsEqualTo("N"))
                    {
                        //ラベル定義
                        if (Command.IsEqualTo("SS"))
                        {
                            mode = ReadMode.InputLabel; LabelTemp = ProgramCounter;
                        }
                        //サブルーチン呼び出し
                        if (Command.IsEqualTo("ST"))
                        {
                            //階層チェック
                            if (++RoutineNowDepth > RoutineMaxDepth)
                            {
                                return(new SpellburstRuntimeError(ErrorType.SubRoutineLevelTooDeep));
                            }
                            mode      = ReadMode.InputLabel;
                            LabelTemp = ProgramCounter;
                        }
                        //無条件ジャンプ
                        if (Command.IsEqualTo("SN"))
                        {
                            mode = ReadMode.InputLabel; LabelTemp = ProgramCounter;
                        }
                        //スタックトップがゼロならジャンプ
                        if (Command.IsEqualTo("TS"))
                        {
                            mode = ReadMode.InputLabel; LabelTemp = ProgramCounter;
                        }
                        //スタックトップが負ならジャンプ
                        if (Command.IsEqualTo("TT"))
                        {
                            mode = ReadMode.InputLabel; LabelTemp = ProgramCounter;
                        }
                        //サブルーチン終了
                        if (Command.IsEqualTo("TN"))
                        {
                            //階層チェック
                            if (--RoutineNowDepth < 0)
                            {
                                return(new SpellburstRuntimeError(ErrorType.ReturnInNonSubroutine));
                            }
                            ProgramCounter = CallFrom.Pop();

                            reset();
                        }
                        //プログラム終了
                        if (Command.IsEqualTo("NN"))
                        {
                            mode = ReadMode.Finish;
                        }
                    }
                    //入出力
                    if (IMP.IsEqualTo("TN"))
                    {
                        //スタックトップの文字を出力
                        if (Command.IsEqualTo("SS"))
                        {
                            var e = IntegerStack.Peek();
                            Console.Write(Convert.ToChar(e));

                            reset();
                        }
                        //スタックトップの数値を出力
                        if (Command.IsEqualTo("ST"))
                        {
                            var e = IntegerStack.Peek();
                            Console.Write(e);

                            reset();
                        }
                        //文字を読み込みアドレスに格納
                        if (Command.IsEqualTo("TS"))
                        {
                            Heap = Console.Read();

                            reset();
                        }
                        //数値を読み込みアドレスに格納
                        if (Command.IsEqualTo("TN"))
                        {
                            Heap = int.Parse(Console.ReadLine());

                            reset();
                        }
                    }
                    break;

                case ReadMode.InputInteger:
                    if (first.Equals(SpellCode.NewLine))
                    {
                        //スタックに数値をpushする(preprocessなのでしない)
                        IntegerStack.Push(Number.Result);

                        reset();
                    }

                    Number.AddNumber(first);
                    break;

                case ReadMode.InputLabel:
                    if (first.Equals(SpellCode.NewLine))
                    {
                        //ラベル定義
                        if (Command.IsEqualTo("SS"))
                        {
                            //何もしない
                        }
                        //サブルーチン呼び出し
                        if (Command.IsEqualTo("ST"))
                        {
                            var row = LabelDict[Label.Result] - 1;
                            CallFrom.Push(ProgramCounter);
                            ProgramCounter = row;
                        }
                        //無条件ジャンプ
                        if (Command.IsEqualTo("SN"))
                        {
                            ProgramCounter = LabelDict[Label.Result] - 1;
                        }
                        //ゼロならジャンプ
                        if (Command.IsEqualTo("TS"))
                        {
                            if (IntegerStack.Peek() == 0)
                            {
                                ProgramCounter = LabelDict[Label.Result] - 1;
                            }
                        }
                        //負ならジャンプ
                        if (Command.IsEqualTo("TT"))
                        {
                            if (IntegerStack.Peek() < 0)
                            {
                                ProgramCounter = LabelDict[Label.Result] - 1;
                            }
                        }
                        reset();
                    }

                    Label.Add(first);
                    break;

                case ReadMode.Finish:
                    Codes.Clear();
                    break;
                }
                ProgramCounter++;
            }

            return(new SpellburstRuntimeError(ErrorType.Success));
        }