Esempio n. 1
0
        public void WriteArrayIndex(uint arrayId, uint index, uint value)
        {
            if (!Platters.ContainsKey(arrayId))
            {
                Fail($"Attempting to read from abandoned array {arrayId}");
            }

            if (index >= Platters[arrayId].Length)
            {
                Fail($"Attempting to read out of bounds {arrayId} : {index}");
            }

            Platters[arrayId][index] = new Platter(value);
        }
Esempio n. 2
0
        public void DischargeOperator(Platter um32Operator)
        {
            switch (um32Operator.OperatorNumber)
            {
            case OperatorConstants.ConditionalMove:
                Logger.WriteInfo($"ConditionalMove: if {ReadRegister(um32Operator.RegisterC)} then {um32Operator.RegisterA} = {ReadRegister(um32Operator.RegisterB)}");

                if (ReadRegister(um32Operator.RegisterC) != 0)
                {
                    AssignRegister(
                        um32Operator.RegisterA,
                        ReadRegister(um32Operator.RegisterB));
                }
                break;

            case OperatorConstants.ArrayIndex:
                Logger.WriteInfo("ArrayIndex");

                AssignRegister(
                    um32Operator.RegisterA,
                    ReadArrayIndex(
                        ReadRegister(um32Operator.RegisterB),
                        ReadRegister(um32Operator.RegisterC)));
                break;

            case OperatorConstants.ArrayAmendment:
                Logger.WriteInfo("ArrayAmendment");

                WriteArrayIndex(
                    ReadRegister(um32Operator.RegisterA),
                    ReadRegister(um32Operator.RegisterB),
                    ReadRegister(um32Operator.RegisterC));
                break;

            case OperatorConstants.Addition:
                Logger.WriteInfo("Addition");

                AssignRegister(um32Operator.RegisterA, ReadRegister(um32Operator.RegisterB) + ReadRegister(um32Operator.RegisterC));
                break;

            case OperatorConstants.Multiplication:
                Logger.WriteInfo("Multiplication");

                AssignRegister(um32Operator.RegisterA, ReadRegister(um32Operator.RegisterB) * ReadRegister(um32Operator.RegisterC));
                break;

            case OperatorConstants.Division:
                Logger.WriteInfo("Division");

                AssignRegister(um32Operator.RegisterA, ReadRegister(um32Operator.RegisterB) / ReadRegister(um32Operator.RegisterC));

                break;

            case OperatorConstants.NotAnd:
                Logger.WriteInfo("NotAnd");

                AssignRegister(um32Operator.RegisterA, ~(ReadRegister(um32Operator.RegisterB) & ReadRegister(um32Operator.RegisterC)));

                break;

            case OperatorConstants.Halt:
                Logger.WriteInfo("Halt");

                IsExecuting = false;

                break;

            case OperatorConstants.Allocation:
                Logger.WriteInfo("Allocation");

                var numberOfPlatters = ReadRegister(um32Operator.RegisterC);
                var newPlatters      = new List <Platter>();
                for (int i = 0; i < numberOfPlatters; i++)
                {
                    newPlatters.Add(new Platter(0));
                }

                var newArrayId = Platters.Keys.Max() + 1;
                AllocatePlatterArray(newArrayId, newPlatters.ToArray());
                AssignRegister(um32Operator.RegisterB, newArrayId);

                break;

            case OperatorConstants.Abandonment:
                Logger.WriteInfo("Abandonment");

                AbandonPlatterArray(ReadRegister(um32Operator.RegisterC));

                break;

            case OperatorConstants.Output:

                char c = (char)ReadRegister(um32Operator.RegisterC);
                Console.Write(c);

                break;

            case OperatorConstants.Input:
                Logger.WriteInfo("Input");

                var x = Console.Read();
                if (x == -1)
                {
                    AssignRegister(um32Operator.RegisterC, 0xFFFFFFFF);
                }
                else
                {
                    AssignRegister(um32Operator.RegisterC, (uint)x);
                }

                break;

            case OperatorConstants.LoadProgram:
                Logger.WriteInfo("LoadProgram");

                var sourceArrayId      = ReadRegister(um32Operator.RegisterB);
                var newExecutionOffset = ReadRegister(um32Operator.RegisterC);

                var duplicatePlatters = new List <Platter>();
                foreach (var platter in Platters[sourceArrayId])
                {
                    duplicatePlatters.Add(new Platter(platter.Value));
                }

                ExecutionFinger = new ExecutionFinger {
                    ArrayId = 0, PlatterIndex = (int)newExecutionOffset
                };

                Platters[0] = duplicatePlatters.ToArray();

                break;


            case OperatorConstants.Orthography:
                Logger.WriteInfo("Orthography");

                AssignRegister(um32Operator.OrthograhyRegister, um32Operator.OrthograhyValue);

                break;


            default:
                Fail($"Unrecognized operator {um32Operator.OperatorNumber}");
                break;
            }
        }