コード例 #1
0
    public static void Main(string[] args)
    {
        Console.WriteLine("Started");
        //Validate Args were provided
        if (args.Length != 1)
        {
            Console.WriteLine("missing args");
            System.Environment.Exit(1);
        }

        //open data file
        InFile puzzleData = new InFile(args[0]);

        Console.WriteLine("File read.");
        //exit program if data file unreadable
        if (puzzleData.OpenError())
        {
            Console.WriteLine("Failed to open " + args[0]);
            System.Environment.Exit(1);
        }

        //process data file
        string[] data = new string[9];
        for (int i = 0; i < data.Length; i++)
        {
            data[i] = puzzleData.ReadLine();
        }

        for (int i = 0; i < data.Length; i++)
        {
            Console.WriteLine(data[i]);
        }
    }
コード例 #2
0
        //Proccess the data file.
        int[,] ProcessDataFile(InFile data)
        {
            int[,] board = new int[9, 9];
            int rows = 0;
            int cols = 0;

            while (!data.NoMoreData())
            {
                if (rows == 9)
                {
                    break;
                }
                board[rows, cols] = data.ReadInt();
                //incrementing cols & rows
                if (cols == 8)
                {
                    cols = 0;
                    rows++;
                }
                else
                {
                    cols++;
                }
            }
            return(board);
        }
コード例 #3
0
ファイル: Declarations.cs プロジェクト: MatrixCore/TransPrac5
    // +++++++++++++++++++++ Main driver function +++++++++++++++++++++++++++++++

    public static void Main(string[] args)
    {
        // Open input and output files from command line arguments
        if (args.Length == 0)
        {
            Console.WriteLine("Usage: Declarations FileName");
            System.Environment.Exit(1);
        }
        input  = new InFile(args[0]);
        output = new OutFile(NewFileName(args[0], ".out"));

        GetChar();                                // Lookahead character

        //  To test the scanner we can use a loop like the following:

        /*
         * do {
         * GetSym();                                 // Lookahead symbol
         * OutFile.StdOut.Write(sym.kind, 3);
         * OutFile.StdOut.WriteLine(" " + sym.val);  // See what we got
         * } while (sym.kind != EOFSym);
         */

        //After the scanner is debugged we shall substitute this code:

        GetSym();                                 // Lookahead symbol
        Mod2Decl();                               // Start to parse from the goal symbol
        // if we get back here everything must have been satisfactory
        Console.WriteLine("Parsed correctly");

        output.Close();
    } // Main
コード例 #4
0
        } // PVM.QuickInterpret

        public static void Interpret(int codeLen, int initSP)
        {
            // Interactively opens data and results files.  Then interprets the codeLen
            // instructions stored in mem, with stack pointer initialized to initSP
            Console.Write("\nTrace execution (y/N/q)? ");
            char reply = (Console.ReadLine() + " ").ToUpper()[0];
            bool traceStack = false, traceHeap = false;

            if (reply != 'Q')
            {
                bool tracing = reply == 'Y';
                if (tracing)
                {
                    Console.Write("\nTrace Stack (y/N)? ");
                    traceStack = (Console.ReadLine() + " ").ToUpper()[0] == 'Y';
                    Console.Write("\nTrace Heap (y/N)? ");
                    traceHeap = (Console.ReadLine() + " ").ToUpper()[0] == 'Y';
                }
                Console.Write("\nData file [STDIN] ? ");
                InFile data = new InFile(Console.ReadLine());
                Console.Write("\nResults file [STDOUT] ? ");
                OutFile results = new OutFile(Console.ReadLine());
                Emulator(0, codeLen, initSP, data, results, tracing, traceStack, traceHeap);
                results.Close();
                data.Close();
            }
        } // PVM.Interpret
コード例 #5
0
    public static void Main(string[] args)
    {
        //                                        check that arguments have been supplied
        if (args.Length != 2)
        {
            Console.WriteLine("missing args");
            System.Environment.Exit(1);
        }
        //                                        attempt to open data file
        InFile data = new InFile(args[0]);

        if (data.OpenError())
        {
            Console.WriteLine("cannot open " + args[0]);
            System.Environment.Exit(1);
        }
        //                                        attempt to open results file
        OutFile results = new OutFile(args[1]);

        if (results.OpenError())
        {
            Console.WriteLine("cannot open " + args[1]);
            System.Environment.Exit(1);
        }
        //                                        various initializations
        int    total       = 0;
        IntSet mySet       = new IntSet();
        IntSet smallSet    = new IntSet(1, 2, 3, 4, 5);
        string smallSetStr = smallSet.ToString();
        //                                        read and process data file
        int item = data.ReadInt();

        while (!data.NoMoreData())
        {
            total = total + item;
            if (item > 0)
            {
                mySet.Incl(item);
            }
            item = data.ReadInt();
        }
        //                                        write various results to output file
        results.Write("total = ");
        results.WriteLine(total, 5);
        results.WriteLine("unique positive numbers " + mySet.ToString());
        results.WriteLine("union with " + smallSetStr
                          + " = " + mySet.Union(smallSet).ToString());
        results.WriteLine("intersection with " + smallSetStr
                          + " = " + mySet.Intersection(smallSet).ToString());

        /* or simply
         * results.WriteLine("union with " + smallSetStr + " = " + mySet.Union(smallSet));
         * results.WriteLine("intersection with " + smallSetStr + " = " + mySet.Intersection(smallSet));
         */

        results.Close();
    } // Main
コード例 #6
0
    } // PVM.Emulator

    public static void QuickInterpret(int codeLen, int initSP) {
    // Interprets the codeLen instructions stored in mem, with stack pointer
    // initialized to initSP.  Use StdIn and StdOut without asking
      Console.WriteLine("\nHit <Enter> to start");
      Console.ReadLine();
      bool tracing = false;
      InFile data = new InFile("");
      OutFile results = new OutFile("");
      Emulator(0, codeLen, initSP, data, results, false, false, false);
    } // PVM.QuickInterpret
コード例 #7
0
ファイル: prac1Temp.cs プロジェクト: TomMakkink/Sudoku.cs
    public static List <IntSet> readInBoard(InFile data)
    {
        // Read in all of the rows
        List <InSet> rowList = new List <InSet> {
        };

        for (int i = 0; i < 9; i++)
        {
        }
    }
コード例 #8
0
        public void ShouldReturn3SellersWhenParse3Sellers()
        {
            const string sourcePath = "C:\\test.dat";
            var          content    = "001ç1234567891234çPedroç50000 001ç3245678865434çPauloç40000.99 001ç3445678865434çJoseç60000.99" + Environment.NewLine +
                                      "002ç2345675434544345çJose da SilvaçRural 002ç2345675433444345çEduardo PereiraçRural" + Environment.NewLine +
                                      "003ç10ç[1-10-100,2-30-2.50,3-40-3.10]çPedro 003ç08ç[1-34-10,2-33-1.50,3-40-0.10]çPaulo 003ç08ç[1-1-1000]çJose";

            var sut = new InFile(Guid.NewGuid(), sourcePath, content);

            Assert.Equal(3, sut.Sellers.Count);
        }
コード例 #9
0
ファイル: Sudoku.cs プロジェクト: TomMakkink/Compilers
    public static void Main(string[] args)
    {
        Screen.ClrScr();

        InFile data = new InFile(args[0]);

        if (data.OpenError())
        {
            Console.WriteLine("cannot open " + args[0]);
            System.Environment.Exit(1);
        }

        List <List <int> > Board = createBoard(data);

        List <List <IntSet> > predictionBoard = createPredicativeBoard(Board);

        predictionBoard = FilterRows(predictionBoard);
        predictionBoard = FilterCols(predictionBoard);

        IO.Write('\n');
        IO.WriteLine("Please may you about to begin a new Game of Sudoku.");
        //writeBoard();
        IO.WriteLine("Please may you you either type in (S)tart or (Q)uite");
        char T = IO.ReadChar();

        if (T == 'S' || T == 's')
        {
            writeBoard(Board);
            string trash = IO.ReadLine();
            while (!isGameOver(Board))
            {
                // Get input from user
                string [] userInput = getInputFromUser();
                while (!validateInput(userInput))
                {
                    IO.WriteLine("Invalid Input.");
                    userInput = getInputFromUser();
                }
                // List of valid input
                List <int> userMove = convertToIntList(userInput);
                Board[userMove[0]][userMove[1]] = userMove[2];
                writeBoard(Board);
            }
        }
        if (T == 'q' || T == 'Q')
        {
            Screen.ClrScr(); System.Environment.Exit(1);
        }
    }
コード例 #10
0
        public static void ProcessFiles()
        {
            var inFiles = new List <InFile>();

            // Caminhos
            var homeDir    = Environment.GetEnvironmentVariable("HOMEPATH");
            var inPath     = $"{homeDir}\\data\\in";
            var inPathRead = $"{inPath}\\read";

            // Cria as pastas, caso não existam
            if (!Directory.Exists(inPath))
            {
                Directory.CreateDirectory(inPath);
            }

            if (!Directory.Exists(inPathRead))
            {
                Directory.CreateDirectory(inPathRead);
            }

            var files = new DirectoryInfo(inPath).GetFiles("*.dat");

            if (files.Length < 1)
            {
                Console.WriteLine($"{inPath} is empty.");
                return;
            }
            // Lista os arquivos
            foreach (var file in new DirectoryInfo(inPath).GetFiles("*.dat"))
            {
                // Cria um novo objeto com o arquivo e conteúdo
                var inFile = new InFile(Guid.NewGuid(),
                                        file.FullName,
                                        File.ReadAllText(file.FullName));

                inFiles.Add(inFile);
                file.MoveTo($"{inPathRead}\\{file.Name}");

                var outFile = new OutFile(Guid.NewGuid(), inFile);
                var outPath = $"{homeDir}\\data\\out";

                // Criar o arquivo de saída
                File.WriteAllText($"{outPath}\\" + file.Name.Replace(".dat", ".done.dat"), outFile.Out);
            }

            WriteInConsole(inFiles);
        }
コード例 #11
0
        static int[][] initialiseBoard()
        {
            InFile data = new InFile("sample.txt");

            int[][] board = new int[9][];

            for (int j = 0; j < 9; j++)
            {
                board[j] = new int[9];

                for (int k = 0; k < 9; k++)
                {
                    board[j][k] = data.ReadInt();
                }
            }
            return(board);
        }
コード例 #12
0
        static void Main(string[] args)
        {
            Program p = new Program();

            int[,] Board = new int[9, 9];

            //Read in Data file
            InFile data = new InFile(args[0]);

            if (data.OpenError())
            {
                Console.WriteLine("cannot open " + args[0]);
                Environment.Exit(1);
            }


            Board = p.ProcessDataFile(data);
        }
コード例 #13
0
        protected override void Execute(CodeActivityContext context)
        {
            var inFile  = InFile.Get(context);
            var outFile = OutFile.Get(context);

            Xdwapi.XDW_DOCUMENT_HANDLE documentHandle = new Xdwapi.XDW_DOCUMENT_HANDLE();
            Xdwapi.XDW_OPEN_MODE_EX    mode           = new Xdwapi.XDW_OPEN_MODE_EX();
            mode.Option   = Xdwapi.XDW_OPEN_UPDATE;
            mode.AuthMode = Xdwapi.XDW_AUTH_NODIALOGUE;
            //api_result =
            Xdwapi.XDW_OpenDocumentHandle(outFile, ref documentHandle, mode);
            Xdwapi.XDW_DeletePage(documentHandle, 1);

            // inputPath
            Xdwapi.XDW_InsertDocument(documentHandle, 1, inFile);
            Xdwapi.XDW_SaveDocument(documentHandle);
            Xdwapi.XDW_CloseDocumentHandle(documentHandle);
        }
コード例 #14
0
        static void readBoard(string[,] board, int[, ][,] suggestedBoard, InFile data, bool solution)
        {
            int row = 0, col = 0;

            while (row != 9 && !data.NoMoreData())
            {
                int num = data.ReadInt();

                if (num == 0)
                {
                    board[row, col] = "..";
                    if (!solution)
                    {
                        suggestedBoard[row, col] = new int[3, 3] {
                            { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }
                        };
                    }
                }
                else
                {
                    board[row, col] = " " + num;
                    if (!solution)
                    {
                        suggestedBoard[row, col] = null;
                        known++;
                    }
                }
                col++;
                if (col == 9)
                {
                    row++;
                    col = 0;
                }
            }

            /*if the board just filled was not the solution then
             * skip next three lines to get to the next board (which is the solution board)*/
            if (!solution)
            {
                data.ReadLine();
                data.ReadLine();
                data.ReadLine();
            }
        }
コード例 #15
0
ファイル: Sudoku.cs プロジェクト: TomMakkink/Compilers
    // Create a standard board
    public static List <List <int> > createBoard(InFile data)
    {
        // We know it is a 3 element input, as we have checked it
        List <List <int> > tempBoard = new List <List <int> > {
        };

        for (int i = 0; i < 9; i++)
        {
            List <int> te = new List <int> {
            };
            for (int j = 0; j < 9; j++)
            {
                int t = data.ReadInt();
                te.Add(t);
            }
            tempBoard.Add(te);
        }
        return(tempBoard);
    }
コード例 #16
0
        private static InFile ParseKeys(string[] keysClean)
        {
            var global = new InFile {
                CommentMode = CommentMode.Off
            };

            foreach (var key in keysClean)
            {
                switch (key[0])
                {
                case 'd':
                    global.StripDebug = true;
                    continue;

                case 's':
                    global.CommentMode = GetCommentMode(key);
                    continue;

                case 'm':
                    global.Minify = true;
                    continue;

                case 'l':
                    global.LocalAliases = true;
                    continue;

                case 'o':
                    global.Filename = GetValue(key);
                    continue;

                default:
                    ConsoleHelper.ShowHelp();
                    ConsoleHelper.ShowError($"Invalid configuration key: {key}", 8);
                    continue;
                }
            }

            return(global);
        }
コード例 #17
0
        private void Form1_Load(object sender, EventArgs e)
        {
            //Code which Changes the visibility of Form.
            ProductPanel.Visible      = true;
            ButtonPanelOne.Visible    = false;
            ExitButtonTwo.Visible     = true;
            DataGridViewPanel.Visible = false;
            //The Opening stock is loaded from the file and stored in stock array.
            StreamReader InFile;

            InFile = File.OpenText("StockFile.txt");
            for (int i = 0; i < 14; i++)
            {
                for (int j = 0; j < 5; j++)
                {
                    StockArray[i, j] = int.Parse(InFile.ReadLine());
                }
            }
            InFile.Close();
            //code in which loaded Stock is copied to Temporary Array for daily operation.
            Array.Copy(StockArray, TempStockArray, StockArray.Length);
        }
コード例 #18
0
    /// <summary>
    /// 获取文件
    /// </summary>
    /// <param name="dir"></param>
    /// <returns></returns>
    private List <TreeNodeEntity> GetDirNode(string dir)
    {
        List <TreeNodeEntity> filesEntities = new List <TreeNodeEntity>();

        string[] dirs = Directory.GetDirectories(dir);
        foreach (string InDir in dirs)
        {
            TreeNodeEntity dirNode = new TreeNodeEntity();
            dirNode.Name     = InDir.Substring(InDir.LastIndexOf("\\") + 1, InDir.Length - InDir.LastIndexOf("\\") - 1);
            dirNode.Open     = false;
            dirNode.Children = GetDirNode(InDir);
            filesEntities.Add(dirNode);
        }
        string[] files = Directory.GetFiles(dir);
        foreach (string InFile in files)
        {
            TreeNodeEntity fileNode = new TreeNodeEntity();
            CodeEntity     ce       = CodeOperation.GetCodeFromPath(dir.Replace(
                                                                        Server.MapPath(AppConfiger.GetProjectsDir(Server)), "") +
                                                                    "\\" + InFile.Substring(InFile.LastIndexOf("\\") + 1, InFile.Length - InFile.LastIndexOf("\\") - 1));
            if (ce != null)
            {
                fileNode.Id         = ce.Id;
                fileNode.Name       = ce.Path.Substring(ce.Path.LastIndexOf("\\") + 1, ce.Path.Length - ce.Path.LastIndexOf("\\") - 1);
                fileNode.TargetName = "sourceFrame";
                fileNode.UrlFormat  = "/Viewer.aspx?id={0}";
                filesEntities.Add(fileNode);
            }
            else
            {
                fileNode.Name = InFile.Substring(InFile.LastIndexOf("\\") + 1, InFile.Length - InFile.LastIndexOf("\\") - 1);
                filesEntities.Add(fileNode);
            }
        }
        return(filesEntities);
    }
コード例 #19
0
        // Module defining this command


        // Optional custom code for this activity


        /// <summary>
        /// Returns a configured instance of System.Management.Automation.PowerShell, pre-populated with the command to run.
        /// </summary>
        /// <param name="context">The NativeActivityContext for the currently running activity.</param>
        /// <returns>A populated instance of Sytem.Management.Automation.PowerShell</returns>
        /// <remarks>The infrastructure takes responsibility for closing and disposing the PowerShell instance returned.</remarks>
        protected override ActivityImplementationContext GetPowerShell(NativeActivityContext context)
        {
            System.Management.Automation.PowerShell invoker       = global::System.Management.Automation.PowerShell.Create();
            System.Management.Automation.PowerShell targetCommand = invoker.AddCommand(PSCommandName);

            // Initialize the arguments

            if (Method.Expression != null)
            {
                targetCommand.AddParameter("Method", Method.Get(context));
            }

            if (UseBasicParsing.Expression != null)
            {
                targetCommand.AddParameter("UseBasicParsing", UseBasicParsing.Get(context));
            }

            if (Uri.Expression != null)
            {
                targetCommand.AddParameter("Uri", Uri.Get(context));
            }

            if (WebSession.Expression != null)
            {
                targetCommand.AddParameter("WebSession", WebSession.Get(context));
            }

            if (SessionVariable.Expression != null)
            {
                targetCommand.AddParameter("SessionVariable", SessionVariable.Get(context));
            }

            if (Credential.Expression != null)
            {
                targetCommand.AddParameter("Credential", Credential.Get(context));
            }

            if (UseDefaultCredentials.Expression != null)
            {
                targetCommand.AddParameter("UseDefaultCredentials", UseDefaultCredentials.Get(context));
            }

            if (CertificateThumbprint.Expression != null)
            {
                targetCommand.AddParameter("CertificateThumbprint", CertificateThumbprint.Get(context));
            }

            if (Certificate.Expression != null)
            {
                targetCommand.AddParameter("Certificate", Certificate.Get(context));
            }

            if (UserAgent.Expression != null)
            {
                targetCommand.AddParameter("UserAgent", UserAgent.Get(context));
            }

            if (DisableKeepAlive.Expression != null)
            {
                targetCommand.AddParameter("DisableKeepAlive", DisableKeepAlive.Get(context));
            }

            if (TimeoutSec.Expression != null)
            {
                targetCommand.AddParameter("TimeoutSec", TimeoutSec.Get(context));
            }

            if (Headers.Expression != null)
            {
                targetCommand.AddParameter("Headers", Headers.Get(context));
            }

            if (MaximumRedirection.Expression != null)
            {
                targetCommand.AddParameter("MaximumRedirection", MaximumRedirection.Get(context));
            }

            if (Proxy.Expression != null)
            {
                targetCommand.AddParameter("Proxy", Proxy.Get(context));
            }

            if (ProxyCredential.Expression != null)
            {
                targetCommand.AddParameter("ProxyCredential", ProxyCredential.Get(context));
            }

            if (ProxyUseDefaultCredentials.Expression != null)
            {
                targetCommand.AddParameter("ProxyUseDefaultCredentials", ProxyUseDefaultCredentials.Get(context));
            }

            if (Body.Expression != null)
            {
                targetCommand.AddParameter("Body", Body.Get(context));
            }

            if (ContentType.Expression != null)
            {
                targetCommand.AddParameter("ContentType", ContentType.Get(context));
            }

            if (TransferEncoding.Expression != null)
            {
                targetCommand.AddParameter("TransferEncoding", TransferEncoding.Get(context));
            }

            if (InFile.Expression != null)
            {
                targetCommand.AddParameter("InFile", InFile.Get(context));
            }

            if (OutFile.Expression != null)
            {
                targetCommand.AddParameter("OutFile", OutFile.Get(context));
            }

            if (PassThru.Expression != null)
            {
                targetCommand.AddParameter("PassThru", PassThru.Get(context));
            }


            return(new ActivityImplementationContext()
            {
                PowerShellInstance = invoker
            });
        }
コード例 #20
0
        } // PVM.PostMortem

        // The interpreters and utility methods

        public static void Emulator(int initPC, int codeLen, int initSP,
                                    InFile data, OutFile results, bool tracing,
                                    bool traceStack, bool traceHeap)
        {
            // Emulates action of the codeLen instructions stored in mem[0 .. codeLen-1], with
            // program counter initialized to initPC, stack pointer initialized to initSP.
            // data and results are used for I/O.  Tracing at the code level may be requested

            int pcNow;            // current program counter
            int loop;             // internal loops
            int tos, sos;         // value popped from stack

            stackBase = initSP;
            heapBase  = codeLen;  // initialize boundaries
            cpu.hp    = heapBase; // initialize registers
            cpu.sp    = stackBase;
            cpu.gp    = stackBase;
            cpu.mp    = stackBase;
            cpu.fp    = stackBase;
            cpu.pc    = initPC;   // initialize program counter
            ps        = running;  // prepare to execute
            int ops = 0;

            timer.Start();
            do
            {
                ops++;
                pcNow  = cpu.pc;        // retain for tracing/postmortem
                cpu.ir = mem[cpu.pc++]; // fetch
//        if (tracing) Trace(results, pcNow, traceStack, traceHeap);
                switch (cpu.ir)         // execute
                {
                case PVM.nop:           // no operation
                    break;

                case PVM.dsp:     // decrement stack pointer (allocate space for variables)
                    cpu.sp -= mem[cpu.pc++];
                    break;

                case PVM.ldc:     // push constant value
                    mem[--cpu.sp] = mem[cpu.pc++];
                    break;

                case PVM.lda:     // push local address
                    mem[--cpu.sp] = cpu.fp - 1 - mem[cpu.pc++];
                    break;

                case PVM.ldv:     // dereference
                    mem[cpu.sp] = mem[mem[cpu.sp]];
                    break;

                case PVM.sto:     // store
                    tos = mem[cpu.sp++]; mem[mem[cpu.sp++]] = tos;
                    break;

                case PVM.ldxa:    // heap array indexing
                    tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] + tos;
                    break;

                case PVM.inpi:    // integer input
                    mem[mem[cpu.sp++]] = data.ReadInt();
                    break;

                case PVM.inpc:    // char input
                    mem[mem[cpu.sp++]] = data.ReadChar();
                    break;

                case PVM.prni:    // integer output
//            if (tracing) results.Write(padding);
                    results.Write(mem[cpu.sp++], 0);
//            if (tracing) results.WriteLine();
                    break;

                case PVM.prnc:    // integer output
                    results.Write((char)mem[cpu.sp++], 0);
                    break;

                case PVM.inpb:    // boolean input
                    mem[mem[cpu.sp++]] = data.ReadBool() ? 1 : 0;
                    break;

                case PVM.prnb:    // boolean output
//            if (tracing) results.Write(padding);
                    if (mem[cpu.sp++] != 0)
                    {
                        results.Write(" true  ");
                    }
                    else
                    {
                        results.Write(" false ");
                    }
//            if (tracing) results.WriteLine();
                    break;

                case PVM.prns:    // string output
//            if (tracing) results.Write(padding);
                    loop = mem[cpu.pc++];
                    while (mem[loop] != 0)
                    {
                        results.Write((char)mem[loop]); loop--;
                    }
//            if (tracing) results.WriteLine();
                    break;

                case PVM.prnl:    // newline
                    results.WriteLine();
                    break;

                case PVM.neg:     // integer negation
                    mem[cpu.sp] = -mem[cpu.sp];
                    break;

                case PVM.add:     // integer addition
                    tos = mem[cpu.sp++]; mem[cpu.sp] += tos;
                    break;

                case PVM.sub:     // integer subtraction
                    tos = mem[cpu.sp++]; mem[cpu.sp] -= tos;
                    break;

                case PVM.mul:
                    tos = mem[cpu.sp++];
                    sos = mem[cpu.sp];   // integer multiplication
                    int freeSpace = (memSize - cpu.hp - (memSize - cpu.sp));
                    if ((freeSpace / tos) > sos)
                    {
                        mem[cpu.sp] *= tos;
                    }
                    else
                    {
                        ps = badVal;
                    }
                    break;

                case PVM.div:     // integer division (quotient)
                    tos = mem[cpu.sp++];
                    if (tos == 0)
                    {
                        ps = divZero;
                    }
                    else
                    {
                        mem[cpu.sp] /= tos;
                    }
                    break;

                case PVM.rem:     // integer division (remainder)
                    tos = mem[cpu.sp++]; mem[cpu.sp] %= tos;
                    break;

                case PVM.not:     // logical negation
                    mem[cpu.sp] = mem[cpu.sp] == 0 ? 1 : 0;
                    break;

                case PVM.and:     // logical and
                    tos = mem[cpu.sp++]; mem[cpu.sp] &= tos;
                    break;

                case PVM.or:      // logical or
                    tos = mem[cpu.sp++]; mem[cpu.sp] |= tos;
                    break;

                case PVM.ceq:     // logical equality
                    tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] == tos ? 1 : 0;
                    break;

                case PVM.cne:     // logical inequality
                    tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] != tos ? 1 : 0;
                    break;

                case PVM.clt:     // logical less
                    tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] < tos ? 1 : 0;
                    break;

                case PVM.cle:     // logical less or equal
                    tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] <= tos ? 1 : 0;
                    break;

                case PVM.cgt:     // logical greater
                    tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] > tos ? 1 : 0;
                    break;

                case PVM.cge:     // logical greater or equal
                    tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] >= tos ? 1 : 0;
                    break;

                case PVM.brn:     // unconditional branch
                    cpu.pc = mem[cpu.pc++];
                    break;

                case PVM.bze:     // pop top of stack, branch if false
                    int target = mem[cpu.pc++];
                    if (mem[cpu.sp++] == 0)
                    {
                        cpu.pc = target;
                    }
                    break;

                case PVM.anew:    // heap array allocation
                    int size = mem[cpu.sp];
                    mem[cpu.sp] = cpu.hp;
                    cpu.hp     += size;
                    break;

                case PVM.halt:    // halt
                    ps = finished;
                    break;

                case PVM.stk:     // stack dump (debugging)
                    StackDump(results, pcNow);
                    break;

                case PVM.heap:     // heap dump (debugging)
                    HeapDump(results, pcNow);
                    break;

                case PVM.ldc_0:   // push constant 0
                    mem[--cpu.sp] = 0;
                    break;

                case PVM.ldc_1:   // push constant 1
                    mem[--cpu.sp] = 1;
                    break;

                case PVM.ldc_2:   // push constant 2
                    mem[--cpu.sp] = 2;
                    break;

                case PVM.ldc_3:   // push constant 3
                    mem[--cpu.sp] = 3;
                    break;

                case PVM.lda_0:   // push local address 0
                    mem[--cpu.sp] = cpu.fp - 1 - 0;
                    break;

                case PVM.lda_1:   // push local address 1
                    mem[--cpu.sp] = cpu.fp - 1 - 1;
                    break;

                case PVM.lda_2:   // push local address 2
                    mem[--cpu.sp] = cpu.fp - 1 - 2;
                    break;

                case PVM.lda_3:   // push local address 3
                    mem[--cpu.sp] = cpu.fp - 1 - 3;
                    break;

                case PVM.ldl:     // push local value
                    mem[--cpu.sp] = cpu.fp - 1 - mem[cpu.pc++];
                    mem[cpu.sp]   = mem[mem[cpu.sp]];
                    break;

                case PVM.ldl_0:   // push value of local variable 0
                    mem[--cpu.sp] = cpu.fp - 1 - 0;
                    mem[cpu.sp]   = mem[mem[cpu.sp]];
                    break;

                case PVM.ldl_1:   // push value of local variable 1
                    mem[--cpu.sp] = cpu.fp - 1 - 1;
                    mem[cpu.sp]   = mem[mem[cpu.sp]];
                    break;

                case PVM.ldl_2:   // push value of local variable 2
                    mem[--cpu.sp] = cpu.fp - 1 - 2;
                    mem[cpu.sp]   = mem[mem[cpu.sp]];
                    break;

                case PVM.ldl_3:   // push value of local variable 3
                    mem[--cpu.sp] = cpu.fp - 1 - 3;
                    mem[cpu.sp]   = mem[mem[cpu.sp]];
                    break;

                case PVM.stl:     // store local value
                    mem[--cpu.sp]      = cpu.fp - 1 - mem[cpu.pc++];
                    mem[mem[cpu.sp++]] = mem[cpu.sp++];
                    break;

                case PVM.stlc:    // store local value
                case PVM.stl_0:   // pop to local variable 0
                    mem[--cpu.sp]      = cpu.fp - 1 - 0;
                    mem[mem[cpu.sp++]] = mem[cpu.sp++];
                    break;

                case PVM.stl_1:   // pop to local variable 1
                    mem[--cpu.sp]      = cpu.fp - 1 - 1;
                    mem[mem[cpu.sp++]] = mem[cpu.sp++];
                    break;

                case PVM.stl_2:   // pop to local variable 2
                    mem[--cpu.sp]      = cpu.fp - 1 - 2;
                    mem[mem[cpu.sp++]] = mem[cpu.sp++];
                    break;

                case PVM.stl_3:   // pop to local variable 3
                    mem[--cpu.sp]      = cpu.fp - 1 - 3;
                    mem[mem[cpu.sp++]] = mem[cpu.sp++];
                    break;

                case PVM.stoc:    // character checked store
                //case PVM.inpc:          // character input         // character output
                case PVM.cap:
                    tos = mem[cpu.sp++];
                    if (96 < tos && tos < 123)
                    {
                        mem[--cpu.sp] = (tos - 32);
                    }
                    else
                    {
                        mem[--cpu.sp] = (tos);
                    }
                    break;

                // toUpperCase
                case PVM.low:
                    tos = mem[cpu.sp++];
                    if (64 < tos && tos < 91)
                    {
                        mem[--cpu.sp] = (tos + 31);
                    }
                    else
                    {
                        ps = badOp;
                    }
                    break; // toLowerCase

                case PVM.islet:
                    tos = mem[cpu.sp++];
                    if (64 < tos && tos < 91 || 96 < tos && tos < 123)
                    {
                        mem[--cpu.sp] = 1;
                    }
                    else
                    {
                        mem[--cpu.sp] = 0;
                    } // isLetter
                    break;

                case PVM.inc:                      //NOT DONE PROPERLY
                    tos           = mem[cpu.sp++]; // ++  //NOT DONE PROPERLY
                    mem[--cpu.sp] = (tos += 1);    //NOT DONE PROPERLY
                    break;                         //NOT DONE PROPERLY

                case PVM.dec:                      //NOT DONE PROPERLY
                    tos           = mem[cpu.sp++]; // --  //NOT DONE PROPERLY
                    mem[--cpu.sp] = (tos -= 1);    //NOT DONE PROPERLY
                    break;

                default:          // unrecognized opcode
                    ps = badOp;
                    break;
                }
            } while (ps == running);
            TimeSpan ts = timer.Elapsed;

            // Format and display the TimeSpan value.
            string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                                               ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);

            Console.WriteLine("\n\n" + ops + " operations.  Run Time " + elapsedTime + "\n\n");
            if (ps != finished)
            {
                PostMortem(results, pcNow);
            }
            timer.Reset();
            timer.Stop();
        } // PVM.Emulator
コード例 #21
0
        ///
        /// <summary>
        /// Copy a directory, including all files and [optionally] subdirectories.
        /// </summary>
        /// <param name="InName">Input directory name.</param>
        /// <param name="OutName">Output directory name.</param>
        /// <param name="IncludeDirs">true to include subdirectories.</param>
        /// <param name="CheckAttr">true to reset attributes of existing files before copying
        /// (allows r/o files to be overwritten).</param>
        /// <param name="PreserveTime">true to preserve the timestamp from the input file.</param>
        /// <param name="OnlyNew">True to only copy new files (no existing file).</param>
        /// <param name="KeepNewest">true to retain any newer existing file.</param>
        /// <param name="ErrorHandler">Error handler for a file copy failure.</param>
        /// <returns>error message if copy failed, otherwise null.</returns>
        ///
        public static string CopyDirectory(string InName, string OutName,
                                           bool IncludeDirs, bool CheckAttr, bool PreserveTime,
                                           bool OnlyNew, bool KeepNewest, FileErrorHandler ErrorHandler)
        {
            if (!Directory.Exists(InName))
            {
                return("Directory " + InName + " does not exist!");
            }

            try
            {
                DirectoryInfo Input = new DirectoryInfo(InName);
                if (!Directory.Exists(OutName))
                {
                    Directory.CreateDirectory(OutName);
                }

                if (IncludeDirs)
                {
                    DirectoryInfo[] SubDirs = Input.GetDirectories();
                    foreach (DirectoryInfo DirName in SubDirs)
                    {
                        string ErrMsg = CopyDirectory(Path.Combine(InName, DirName.Name),
                                                      Path.Combine(OutName, DirName.Name), true,
                                                      CheckAttr, PreserveTime, false, ErrorHandler);
                        if (ErrMsg != null)
                        {
                            return(ErrMsg);
                        }
                    }
                }

                FileInfo[] InFiles = Input.GetFiles();
                foreach (FileInfo InFile in InFiles)
                {
                    string FileName = Path.Combine(OutName, InFile.Name);

                    if (File.Exists(FileName))
                    {
                        if (OnlyNew)
                        {
                            continue;
                        }
                        if (KeepNewest)
                        {
                            DateTime OldFileTime = DataConverter.ReadDateToSecond(File.GetLastWriteTimeUtc(FileName));
                            DateTime NewFileTime = DataConverter.ReadDateToSecond(InFile.LastWriteTimeUtc);
                            if (OldFileTime > NewFileTime)
                            {
                                continue;
                            }
                        }
                        if (CheckAttr)
                        {
                            File.SetAttributes(FileName, FileAttributes.Normal);
                        }
                    }

                    // Make sure not Hidden
                    FileAttributes TempAtt = InFile.Attributes;
                    if ((TempAtt & FileAttributes.Hidden) != FileAttributes.Hidden)
                    {
                        bool Retry  = true;
                        bool Copied = false;
                        while (Retry)
                        {
                            try
                            {
                                Retry = false;
                                InFile.CopyTo(FileName, true);
                                Copied = true;
                            }
                            catch (Exception ex)
                            {
                                if (ErrorHandler == null)
                                {
                                    throw;
                                }

                                FileErrorEvent  Ev     = new FileErrorEvent(InFile, FileName, ex);
                                FileErrorAction Action = ErrorHandler(Ev);
                                switch (Action)
                                {
                                case FileErrorAction.Cancel:
                                    return(Ev.ReturnMsg);

                                case FileErrorAction.Retry:
                                    Retry = true;
                                    break;

                                default:
                                    break;
                                }
                            }
                        }

                        if (PreserveTime && Copied)
                        {
                            FileAttributes NewAttr = 0;
                            if (InFile.IsReadOnly)
                            {
                                NewAttr  = File.GetAttributes(FileName);
                                NewAttr &= ~FileAttributes.ReadOnly;
                                File.SetAttributes(FileName, NewAttr);
                            }
                            File.SetCreationTimeUtc(FileName, InFile.CreationTimeUtc);
                            File.SetLastAccessTimeUtc(FileName, InFile.LastAccessTimeUtc);
                            File.SetLastWriteTimeUtc(FileName, InFile.LastWriteTimeUtc);
                            if (InFile.IsReadOnly)
                            {
                                NewAttr |= FileAttributes.ReadOnly;
                                File.SetAttributes(FileName, NewAttr);
                            }
                        }
                    }
                }
            }

            catch (Exception ex)
            {
                return(ex.Message);
            }

            return(null);
        }
コード例 #22
0
ファイル: PVMInLine.cs プロジェクト: stephen10203/Pvm
        } // PVM.PostMortem

        // The interpreters and utility methods

        public static void Emulator(int initPC, int codeLen, int initSP,
                                    InFile data, OutFile results, bool tracing,
                                    bool traceStack, bool traceHeap)
        {
            // Emulates action of the codeLen instructions stored in mem[0 .. codeLen-1], with
            // program counter initialized to initPC, stack pointer initialized to initSP.
            // data and results are used for I/O.  Tracing at the code level may be requested

            int pcNow;                  // current program counter
            int loop;                   // internal loops
            int tos, sos;               // value popped from stack
            int adr;
            stackBase = initSP;
            heapBase = codeLen;         // initialize boundaries
            cpu.hp = heapBase;          // initialize registers
            cpu.sp = stackBase;
            cpu.gp = stackBase;
            cpu.mp = stackBase;
            cpu.fp = stackBase;
            cpu.pc = initPC;            // initialize program counter
            ps = running;               // prepare to execute
            int ops = 0;
            timer.Start();
            do
            {
                ops++;
                pcNow = cpu.pc;           // retain for tracing/postmortem
                cpu.ir = mem[cpu.pc++];          // fetch
                                                 //        if (tracing) Trace(results, pcNow, traceStack, traceHeap);
                switch (cpu.ir)
                {         // execute
                    case PVM.nop:           // no operation
                        break;

                    case PVM.dsp:           // decrement stack pointer (allocate space for variables)
                        cpu.sp -= mem[cpu.pc++];
                        break;

                    case PVM.ldc:           // push constant value
                        mem[--cpu.sp] = mem[cpu.pc++];
                        break;

                    case PVM.lda:           // push local address
                        mem[--cpu.sp] = cpu.fp - 1 - mem[cpu.pc++];
                        break;

                    case PVM.ldv:           // dereference
                        mem[cpu.sp] = mem[mem[cpu.sp]];
                        break;

                    case PVM.sto:           // store
                        tos = mem[cpu.sp++]; mem[mem[cpu.sp++]] = tos;
                        break;

                    case PVM.ldxa:          // heap array indexing
                        tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] + tos;
                        break;

                    case PVM.inpi:          // integer input
                        mem[mem[cpu.sp++]] = data.ReadInt();
                        break;

                    case PVM.prni:          // integer output
                                            //            if (tracing) results.Write(padding);
                        results.Write(mem[cpu.sp++], 0);
                        //            if (tracing) results.WriteLine();
                        break;

                    case PVM.inpb:          // boolean input
                        mem[mem[cpu.sp++]] = data.ReadBool() ? 1 : 0;
                        break;

                    case PVM.prnb:          // boolean output
                                            //            if (tracing) results.Write(padding);
                        if (mem[cpu.sp++] != 0) results.Write(" true  "); else results.Write(" false ");
                        //            if (tracing) results.WriteLine();
                        break;

                    case PVM.prns:          // string output
                                            //            if (tracing) results.Write(padding);
                        loop = mem[cpu.pc++];
                        while (mem[loop] != 0)
                        {
                            results.Write((char)mem[loop]); loop--;
                        }
                        //            if (tracing) results.WriteLine();
                        break;

                    case PVM.prnl:          // newline
                        results.WriteLine();
                        break;

                    case PVM.neg:           // integer negation
                        mem[cpu.sp] = -mem[cpu.sp];
                        break;

                    case PVM.add:           // integer addition
                        tos = mem[cpu.sp++]; mem[cpu.sp] += tos;
                        break;

                    case PVM.sub:           // integer subtraction
                        tos = mem[cpu.sp++]; mem[cpu.sp] -= tos;
                        break;

                    case PVM.mul:           // integer multiplication
                        tos = mem[cpu.sp++];
                        int temp = mem[cpu.sp];
                        int answer = temp * tos;
                        if (((tos > 0 && temp > 0) && answer < 0) || ((tos < 0 && temp < 0) && answer > 0) || ((tos > 0 || temp > 0) && answer < 0) || ((tos < 0 || temp < 0) && answer > 0) || answer > maxInt || answer < -maxInt)
                        {
                            PostMortem(results, pcNow);
                            break;
                        }
                        mem[cpu.sp] *= tos;
                        break;

                    case PVM.div:           // integer division (quotient)
                        tos = mem[cpu.sp++];
                        if (tos == 0)
                        {
                            PostMortem(results, pcNow);
                            break;
                        }
                        mem[cpu.sp] /= tos;
                        break;

                    case PVM.rem:           // integer division (remainder)
                        tos = mem[cpu.sp++]; mem[cpu.sp] %= tos;
                        break;

                    case PVM.not:           // logical negation
                        mem[cpu.sp] = mem[cpu.sp] == 0 ? 1 : 0;
                        break;

                    case PVM.and:           // logical and
                        tos = mem[cpu.sp++]; mem[cpu.sp] &= tos;
                        break;

                    case PVM.or:            // logical or
                        tos = mem[cpu.sp++]; mem[cpu.sp] |= tos;
                        break;

                    case PVM.ceq:           // logical equality
                        tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] == tos ? 1 : 0;
                        break;

                    case PVM.cne:           // logical inequality
                        tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] != tos ? 1 : 0;
                        break;

                    case PVM.clt:           // logical less
                        tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] < tos ? 1 : 0;
                        break;

                    case PVM.cle:           // logical less or equal
                        tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] <= tos ? 1 : 0;
                        break;

                    case PVM.cgt:           // logical greater
                        tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] > tos ? 1 : 0;
                        break;

                    case PVM.cge:           // logical greater or equal
                        tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] >= tos ? 1 : 0;
                        break;

                    case PVM.brn:           // unconditional branch
                        cpu.pc = mem[cpu.pc++];
                        break;
                    case PVM.bze:           // pop top of stack, branch if false
                        int target = mem[cpu.pc++];
                        if (mem[cpu.sp++] == 0) cpu.pc = target;
                        break;
                    case PVM.anew:          // heap array allocation
                        int size = mem[cpu.sp];
                        mem[cpu.sp] = cpu.hp;
                        cpu.hp += size;
                        break;
                    case PVM.halt:          // halt
                        ps = finished;
                        break;
                    case PVM.stk:           // stack dump (debugging)
                        StackDump(results, pcNow);
                        break;
                    case PVM.heap:           // heap dump (debugging)
                        HeapDump(results, pcNow);
                        break;
                    case PVM.ldc_0:         // push constant 0
                        mem[--cpu.sp] = 0;
                        break;
                    case PVM.ldc_1:         // push constant 1
                        mem[--cpu.sp] = 1;
                        break;
                    case PVM.ldc_2:         // push constant 2
                        mem[--cpu.sp] = 2;
                        break;
                    case PVM.ldc_3:         // push constant 3
                        mem[--cpu.sp] = 3;
                        break;
                    case PVM.lda_0:         // push local address 0
                     mem[--cpu.sp] = cpu.fp - mem[cpu.pc++];
                     break;
                    case PVM.lda_1:         // push local address 1
                        mem[--cpu.sp] = cpu.fp -1 -mem[cpu.pc++];
                        break;
                    case PVM.lda_2:         // push local address 2
                        mem[--cpu.sp] = cpu.fp -2- mem[cpu.pc++];
                        break;
                    case PVM.lda_3:         // push local address 3
                        mem[--cpu.sp] = cpu.fp -3- mem[cpu.pc++];
                        break;
                    case PVM.ldl_0:         // push value of local variable 0
                        mem[--cpu.sp] = cpu.fp - mem[cpu.pc++];
                        mem[cpu.sp] = mem[mem[cpu.sp]];
                        break;
                    case PVM.ldl_1:         // push value of local variable 1
                        mem[--cpu.sp] = cpu.fp -1- mem[cpu.pc++];
                        mem[cpu.sp] = mem[mem[cpu.sp]];
                        break;
                    case PVM.ldl_2:         // push value of local variable 2
                        mem[--cpu.sp] = cpu.fp -2- mem[cpu.pc++];
                        mem[cpu.sp] = mem[mem[cpu.sp]];
                        break;
                    case PVM.ldl_3:         // push value of local variable 3
                        mem[--cpu.sp] = cpu.fp -3- mem[cpu.pc++];
                        mem[cpu.sp] = mem[mem[cpu.sp]];
                        break;
                    case PVM.stl:           // store local value
                        // we have bug here with PushPop, test here shows:
                        adr = cpu.fp - 1 - mem[cpu.pc++];
                        mem[cpu.sp++] = mem[adr];
                        break;
                    case PVM.stl_0:         // pop to local variable 0
                        mem[cpu.sp] = mem[mem[cpu.sp]];
                        mem[--cpu.sp] = cpu.fp - mem[cpu.pc++];
                        break;
                    case PVM.stl_1:         // pop to local variable 1
                        mem[cpu.sp] = mem[mem[cpu.sp]];
                        mem[--cpu.sp] = cpu.fp -1- mem[cpu.pc++];
                        break;
                    case PVM.stl_2:         // pop to local variable 2
                        mem[cpu.sp] = mem[mem[cpu.sp]];
                        mem[--cpu.sp] = cpu.fp -2- mem[cpu.pc++];
                        break;
                    case PVM.stl_3:         // pop to local variable 3
                        mem[cpu.sp] = mem[mem[cpu.sp]];
                        mem[--cpu.sp] = cpu.fp -3-mem[cpu.pc++];
                        break;
                    case PVM.inpc: // character input
                        var line = data.ReadLine();
                        char tempChar = string.IsNullOrEmpty(line) ? ' ' : line[0];
                        mem[cpu.sp++] = tempChar;
                        if (data.Error()) ps = badData;
                        break;
                    case PVM.prnc:          // character output
                        if (tracing) results.WriteLine(padding);
                        int readIn = mem[mem[cpu.sp++]];
                        results.WriteLine((char)readIn);
                        if (tracing) results.WriteLine();
                        break;

                    case PVM.cap:           // toUpperCase
                        int cUp = mem[cpu.sp++];
                        cUp = (int)char.ToUpper((char)cUp);
                        mem[cpu.sp++] = cUp;
                        break;
                    case PVM.low:           // toLowerCase
                        int cLow = mem[cpu.sp++];
                        cLow = (int)char.ToLower((char)cLow);
                        mem[cpu.sp++] = cLow;
                        break;

                    case PVM.islet:         // isLetter
                        int val = mem[mem[cpu.sp]];
                        results.WriteLine("Character readIn: " + ((char)val).ToString());
                        if (Char.IsLetter((char)val)) mem[cpu.sp] = 1; else mem[cpu.sp] = 0;
                        break;

                    case PVM.inc:           // ++
                        int inc_a = mem[cpu.sp++] + 1;
                        mem[cpu.sp++] = inc_a;
                        break;
                    case PVM.dec:           // --
                        int dec_a = mem[cpu.sp++] - 1;
                        mem[cpu.sp++] = dec_a;
                        break;

                    case PVM.ldl: // push local value
                        mem[--cpu.sp] = mem[cpu.pc++];
                        var N = mem[cpu.sp];
                        mem[--cpu.sp] = cpu.fp - 1 - N;
                        mem[cpu.sp] = mem[mem[cpu.sp]];
                        break;
                    case PVM.stlc:          // store local value
                        tos = mem[cpu.sp++]; mem[mem[cpu.sp++]] = tos;
                        break;
                    case PVM.stoc:          // character checked store
                    default:                // unrecognized opcode
                        ps = badOp;
                        break;
                }
            } while (ps == running);
            TimeSpan ts = timer.Elapsed;

            // Format and display the TimeSpan value.
            string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                                               ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
            Console.WriteLine("\n\n" + ops + " operations.  Run Time " + elapsedTime + "\n\n");
            if (ps != finished) PostMortem(results, pcNow);
            timer.Reset();
            timer.Stop();
        } // PVM.Emulator
コード例 #23
0
ファイル: PVMInLine.cs プロジェクト: Lexical-Luke/Compilers
        } // PVM.PostMortem

        // The interpreters and utility methods

        public static void Emulator(int initPC, int codeLen, int initSP,
                                    InFile data, OutFile results, bool tracing,
                                    bool traceStack, bool traceHeap)
        {
            // Emulates action of the codeLen instructions stored in mem[0 .. codeLen-1], with
            // program counter initialized to initPC, stack pointer initialized to initSP.
            // data and results are used for I/O.  Tracing at the code level may be requested

            int pcNow;            // current program counter
            int loop;             // internal loops
            int tos, sos;         // value popped from stack

            stackBase = initSP;
            heapBase  = codeLen;  // initialize boundaries
            cpu.hp    = heapBase; // initialize registers
            cpu.sp    = stackBase;
            cpu.gp    = stackBase;
            cpu.mp    = stackBase;
            cpu.fp    = stackBase;
            cpu.pc    = initPC;   // initialize program counter
            ps        = running;  // prepare to execute
            int ops = 0;

            timer.Start();
            do
            {
                ops++;
                pcNow  = cpu.pc;        // retain for tracing/postmortem
                cpu.ir = mem[cpu.pc++]; // fetch
//        if (tracing) Trace(results, pcNow, traceStack, traceHeap);
                switch (cpu.ir)         // execute
                {
                case PVM.nop:           // no operation
                    break;

                case PVM.dsp:     // decrement stack pointer (allocate space for variables)
                    cpu.sp -= mem[cpu.pc++];
                    break;

                case PVM.ldc:     // push constant value
                    mem[--cpu.sp] = mem[cpu.pc++];
                    break;

                case PVM.lda:     // push local address
                    mem[--cpu.sp] = cpu.fp - 1 - mem[cpu.pc++];
                    break;

                case PVM.ldv:     // dereference
                    mem[cpu.sp] = mem[mem[cpu.sp]];
                    break;

                case PVM.sto:     // store
                    tos = mem[cpu.sp++]; mem[mem[cpu.sp++]] = tos;
                    break;

                case PVM.ldxa:    // heap array indexing
                    tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] + tos;
                    break;

                case PVM.inpi:    // integer input
                    mem[mem[cpu.sp++]] = data.ReadInt();
                    break;

                case PVM.prni:    // integer output
//            if (tracing) results.Write(padding);
                    results.Write(mem[cpu.sp++], 0);
//            if (tracing) results.WriteLine();
                    break;

                case PVM.inpb:    // boolean input
                    mem[mem[cpu.sp++]] = data.ReadBool() ? 1 : 0;
                    break;

                case PVM.prnb:    // boolean output
//            if (tracing) results.Write(padding);
                    if (mem[cpu.sp++] != 0)
                    {
                        results.Write(" true  ");
                    }
                    else
                    {
                        results.Write(" false ");
                    }
//            if (tracing) results.WriteLine();
                    break;

                case PVM.prns:    // string output
//            if (tracing) results.Write(padding);
                    loop = mem[cpu.pc++];
                    while (mem[loop] != 0)
                    {
                        results.Write((char)mem[loop]); loop--;
                    }
//            if (tracing) results.WriteLine();
                    break;

                case PVM.prnl:    // newline
                    results.WriteLine();
                    break;

                case PVM.neg:     // integer negation
                    mem[cpu.sp] = -mem[cpu.sp];
                    break;

                case PVM.add:     // integer addition
                    tos = mem[cpu.sp++]; mem[cpu.sp] += tos;
                    break;

                case PVM.sub:     // integer subtraction
                    tos = mem[cpu.sp++]; mem[cpu.sp] -= tos;
                    break;

                /*
                 * case PVM.mul:           // integer multiplication ORIGINAL
                 * tos = mem[cpu.sp++];
                 * mem[cpu.sp] *= tos;
                 * break;
                 */
                case PVM.mul:    // integer multiplication UPDATED
                    tos = mem[cpu.sp++];
                    //if multiplication laws are incorrect an overflow must have occured.
                    //e.g. -? x -? = -? || ? x ? = -? !!!!!!
                    if ((tos > 0 && mem[cpu.sp] > 0 && (mem[cpu.sp] * tos < 0)) || (tos < 0 && mem[cpu.sp] > 0 && (mem[cpu.sp] * tos > 0)))
                    {
                        ps = badVal;
                    }
                    else
                    {
                        mem[cpu.sp] *= tos;
                    }
                    break;

                /*
                 * case PVM.div:           // integer division (quotient) ORIGINAL
                 * tos = mem[cpu.sp++];
                 * mem[cpu.sp] /= tos;
                 * break;
                 */
                case PVM.div:     // integer division (quotient) UPDATED
                    tos = mem[cpu.sp++];
                    if (tos == 0)
                    {
                        ps = divZero;
                    }
                    else
                    {
                        mem[cpu.sp] /= tos;
                    }
                    break;

                case PVM.rem:     // integer division (remainder)
                    tos = mem[cpu.sp++]; mem[cpu.sp] %= tos;
                    break;

                case PVM.not:     // logical negation
                    mem[cpu.sp] = mem[cpu.sp] == 0 ? 1 : 0;
                    break;

                case PVM.and:     // logical and
                    tos = mem[cpu.sp++]; mem[cpu.sp] &= tos;
                    break;

                case PVM.or:      // logical or
                    tos = mem[cpu.sp++]; mem[cpu.sp] |= tos;
                    break;

                case PVM.ceq:     // logical equality
                    tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] == tos ? 1 : 0;
                    break;

                case PVM.cne:     // logical inequality
                    tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] != tos ? 1 : 0;
                    break;

                case PVM.clt:     // logical less
                    tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] < tos ? 1 : 0;
                    break;

                case PVM.cle:     // logical less or equal
                    tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] <= tos ? 1 : 0;
                    break;

                case PVM.cgt:     // logical greater
                    tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] > tos ? 1 : 0;
                    break;

                case PVM.cge:     // logical greater or equal
                    tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] >= tos ? 1 : 0;
                    break;

                case PVM.brn:     // unconditional branch
                    cpu.pc = mem[cpu.pc++];
                    break;

                case PVM.bze:     // pop top of stack, branch if false
                    int target = mem[cpu.pc++];
                    if (mem[cpu.sp++] == 0)
                    {
                        cpu.pc = target;
                    }
                    break;

                /*
                 * case PVM.anew:          // heap array allocation ORIGINAL
                 * int size = mem[cpu.sp];
                 * mem[cpu.sp] = cpu.hp;
                 * cpu.hp += size;
                 * break;
                 */
                case PVM.anew:    // heap array allocation  UPDATED: as per textbook on page 51
                    int size = mem[cpu.sp];
                    if (size <= 0 || size + 1 > cpu.sp - cpu.hp)
                    {
                        ps = badAll;
                    }
                    else
                    {
                        mem[cpu.hp] = size;
                        mem[cpu.sp] = cpu.hp;
                        cpu.hp     += size + 1;
                    }
                    break;

                case PVM.halt:    // halt
                    ps = finished;
                    break;

                case PVM.stk:     // stack dump (debugging)
                    StackDump(results, pcNow);
                    break;

                case PVM.heap:     // heap dump (debugging)
                    HeapDump(results, pcNow);
                    break;

                case PVM.ldc_0:   // push constant 0
                case PVM.ldc_1:   // push constant 1
                case PVM.ldc_2:   // push constant 2
                case PVM.ldc_3:   // push constant 3
                case PVM.lda_0:   // push local address 0
                case PVM.lda_1:   // push local address 1
                case PVM.lda_2:   // push local address 2
                case PVM.lda_3:   // push local address 3
                case PVM.ldl:     // push local value
                case PVM.ldl_0:   // push value of local variable 0
                case PVM.ldl_1:   // push value of local variable 1
                case PVM.ldl_2:   // push value of local variable 2
                case PVM.ldl_3:   // push value of local variable 3
                case PVM.stl:     // store local value
                case PVM.stlc:    // store local value
                case PVM.stl_0:   // pop to local variable 0
                case PVM.stl_1:   // pop to local variable 1
                case PVM.stl_2:   // pop to local variable 2
                case PVM.stl_3:   // pop to local variable 3
                case PVM.stoc:    // character checked store
                case PVM.inpc:    // character input
                case PVM.prnc:    // character output
                case PVM.cap:     // toUpperCase    ADDED
                    mem[cpu.sp] = Char.ToUpper((char)mem[cpu.sp]);
                    break;

                case PVM.low:     // toLowerCase
                case PVM.islet:   // isLetter
                case PVM.inc:     // ++   ADDED
                    mem[mem[cpu.sp++]]++;
                    break;

                case PVM.dec:     // --   ADDED
                    mem[mem[cpu.sp++]]--;
                    break;

                default:          // unrecognized opcode
                    ps = badOp;
                    break;
                }
            } while (ps == running);
            TimeSpan ts = timer.Elapsed;

            // Format and display the TimeSpan value.
            string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                                               ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);

            Console.WriteLine("\n\n" + ops + " operations.  Run Time " + elapsedTime + "\n\n");
            if (ps != finished)
            {
                PostMortem(results, pcNow);
            }
            timer.Reset();
            timer.Stop();
        } // PVM.Emulator
コード例 #24
0
ファイル: PVM.cs プロジェクト: TomMakkink/Compilers
        } // PVM.InBounds

        public static void Emulator(int initPC, int codeLen, int initSP,
                                    InFile data, OutFile results, bool tracing,
                                    bool traceStack, bool traceHeap)
        {
            // Emulates action of the codeLen instructions stored in mem[0 .. codeLen-1], with
            // program counter initialized to initPC, stack pointer initialized to initSP.
            // data and results are used for I/O.  Tracing at the code level may be requested

            int pcNow;            // current program counter
            int loop;             // internal loops
            int tos, sos;         // values popped from stack
            int adr;              // effective address for memory accesses
            int target;           // destination for branches

            stackBase = initSP;
            heapBase  = codeLen;  // initialize boundaries
            cpu.hp    = heapBase; // initialize registers
            cpu.sp    = stackBase;
            cpu.gp    = stackBase;
            cpu.mp    = stackBase;
            cpu.fp    = stackBase;
            cpu.pc    = initPC;   // initialize program counter
            for (int i = heapBase; i < stackBase; i++)
            {
                mem[i] = 0;       // set entire memory to null or 0
            }
            ps = running;         // prepare to execute
            int ops = 0;

            timer.Start();
            do
            {
                ops++;
                pcNow = cpu.pc;   // retain for tracing/postmortem
                if (cpu.pc < 0 || cpu.pc >= codeLen)
                {
                    ps = badAdr;
                    break;
                }
                cpu.ir = Next();  // fetch
                if (tracing)
                {
                    Trace(results, pcNow, traceStack, traceHeap);
                }
                switch (cpu.ir)   // execute
                {
                case PVM.nop:     // no operation
                    break;

                case PVM.dsp:     // decrement stack pointer (allocate space for variables)
                    int localSpace = Next();
                    cpu.sp -= localSpace;
                    if (InBounds(cpu.sp)) // initialize all local variables to zero/null
                    {
                        for (loop = 0; loop < localSpace; loop++)
                        {
                            mem[cpu.sp + loop] = 0;
                        }
                    }
                    break;

                case PVM.ldc:     // push constant value
                    Push(Next());
                    break;

                case PVM.ldc_m1:  // push constant -1
                    Push(-1);
                    break;

                case PVM.ldc_0:   // push constant 0
                    Push(0);
                    break;

                case PVM.ldc_1:   // push constant 1
                    Push(1);
                    break;

                case PVM.ldc_2:   // push constant 2
                    Push(2);
                    break;

                case PVM.ldc_3:   // push constant 3
                    Push(3);
                    break;

                case PVM.ldc_4:   // push constant 4
                    Push(4);
                    break;

                case PVM.ldc_5:   // push constant 5
                    Push(5);
                    break;

                case PVM.dup:     // duplicate top of stack
                    tos = Pop();
                    Push(tos); Push(tos);
                    break;

                case PVM.rdup:    // Remove top of stack
                    tos = Pop();
                    break;

                case PVM.lda:     // push local address
                    adr = cpu.fp - 1 - Next();
                    if (InBounds(adr))
                    {
                        Push(adr);
                    }
                    break;

                case PVM.lda_0:   // push local address 0
                    adr = cpu.fp - 1;
                    if (InBounds(adr))
                    {
                        Push(adr);
                    }
                    break;

                case PVM.lda_1:   // push local address 1
                    adr = cpu.fp - 2;
                    if (InBounds(adr))
                    {
                        Push(adr);
                    }
                    break;

                case PVM.lda_2:   // push local address 2
                    adr = cpu.fp - 3;
                    if (InBounds(adr))
                    {
                        Push(adr);
                    }
                    break;

                case PVM.lda_3:   // push local address 3
                    adr = cpu.fp - 4;
                    if (InBounds(adr))
                    {
                        Push(adr);
                    }
                    break;

                case PVM.lda_4:   // push local address 4
                    adr = cpu.fp - 5;
                    if (InBounds(adr))
                    {
                        Push(adr);
                    }
                    break;

                case PVM.lda_5:   // push local address 5
                    adr = cpu.fp - 6;
                    if (InBounds(adr))
                    {
                        Push(adr);
                    }
                    break;

                case PVM.ldl:     // push local value
                    adr = cpu.fp - 1 - Next();
                    if (InBounds(adr))
                    {
                        Push(mem[adr]);
                    }
                    break;

                case PVM.ldl_0:   // push value of local variable 0
                    adr = cpu.fp - 1;
                    if (InBounds(adr))
                    {
                        Push(mem[adr]);
                    }
                    break;

                case PVM.ldl_1:   // push value of local variable 1
                    adr = cpu.fp - 2;
                    if (InBounds(adr))
                    {
                        Push(mem[adr]);
                    }
                    break;

                case PVM.ldl_2:   // push value of local variable 2
                    adr = cpu.fp - 3;
                    if (InBounds(adr))
                    {
                        Push(mem[adr]);
                    }
                    break;

                case PVM.ldl_3:   // push value of local variable 3
                    adr = cpu.fp - 4;
                    if (InBounds(adr))
                    {
                        Push(mem[adr]);
                    }
                    break;

                case PVM.ldl_4:   // push value of local variable 4
                    adr = cpu.fp - 5;
                    if (InBounds(adr))
                    {
                        Push(mem[adr]);
                    }
                    break;

                case PVM.ldl_5:   // push value of local variable 5
                    adr = cpu.fp - 6;
                    if (InBounds(adr))
                    {
                        Push(mem[adr]);
                    }
                    break;

                case PVM.stl:     // store local value
                    adr = cpu.fp - 1 - Next();
                    if (InBounds(adr))
                    {
                        mem[adr] = Pop();
                    }
                    break;

                case PVM.stlc:    // character checked pop to local variable
                    tos = Pop(); adr = cpu.fp - 1 - Next();
                    if (InBounds(adr))
                    {
                        if (tos >= 0 && tos <= maxChar)
                        {
                            mem[adr] = tos;
                        }
                        else
                        {
                            ps = badVal;
                        }
                    }
                    break;

                case PVM.stl_0:   // pop to local variable 0
                    adr = cpu.fp - 1;
                    if (InBounds(adr))
                    {
                        mem[adr] = Pop();
                    }
                    break;

                case PVM.stl_1:   // pop to local variable 1
                    adr = cpu.fp - 2;
                    if (InBounds(adr))
                    {
                        mem[adr] = Pop();
                    }
                    break;

                case PVM.stl_2:   // pop to local variable 2
                    adr = cpu.fp - 3;
                    if (InBounds(adr))
                    {
                        mem[adr] = Pop();
                    }
                    break;

                case PVM.stl_3:   // pop to local variable 3
                    adr = cpu.fp - 4;
                    if (InBounds(adr))
                    {
                        mem[adr] = Pop();
                    }
                    break;

                case PVM.stl_4:   // pop to local variable 4
                    adr = cpu.fp - 5;
                    if (InBounds(adr))
                    {
                        mem[adr] = Pop();
                    }
                    break;

                case PVM.stl_5:   // pop to local variable 5
                    adr = cpu.fp - 6;
                    if (InBounds(adr))
                    {
                        mem[adr] = Pop();
                    }
                    break;

                case PVM.ldv:     // dereference
                    adr = Pop();
                    if (InBounds(adr))
                    {
                        Push(mem[adr]);
                    }
                    break;

                case PVM.sto:     // store
                    tos = Pop(); adr = Pop();
                    if (InBounds(adr))
                    {
                        mem[adr] = tos;
                    }
                    break;

                case PVM.stoc:    // character checked store
                    tos = Pop(); adr = Pop();
                    if (InBounds(adr))
                    {
                        if (tos >= 0 && tos <= maxChar)
                        {
                            mem[adr] = tos;
                        }
                        else
                        {
                            ps = badVal;
                        }
                    }
                    break;

                case PVM.ldxa:    // heap array indexing
                    adr = Pop();
                    int heapPtr = Pop();
                    if (heapPtr == 0)
                    {
                        ps = nullRef;
                    }
                    else if (heapPtr < heapBase || heapPtr >= cpu.hp)
                    {
                        ps = badMem;
                    }
                    else if (adr < 0 || adr >= mem[heapPtr])
                    {
                        ps = badInd;
                    }
                    else
                    {
                        Push(heapPtr + adr + 1);
                    }
                    break;

                case PVM.inpi:    // integer input
                    adr = Pop();
                    if (InBounds(adr))
                    {
                        mem[adr] = data.ReadInt();
                        if (data.Error())
                        {
                            ps = badData;
                        }
                    }
                    break;

                case PVM.inpb:    // boolean input
                    adr = Pop();
                    if (InBounds(adr))
                    {
                        mem[adr] = data.ReadBool() ? 1 : 0;
                        if (data.Error())
                        {
                            ps = badData;
                        }
                    }
                    break;

                case PVM.inpc:    // character input
                    adr = Pop();
                    if (InBounds(adr))
                    {
                        mem[adr] = data.ReadChar();
                        if (data.Error())
                        {
                            ps = badData;
                        }
                    }
                    break;

                case PVM.inpl:    // skip to end of input line
                    data.ReadLine();
                    break;

                case PVM.i2c:     // check (char) cast is in range
                    if (mem[cpu.sp] < 0 || mem[cpu.sp] > maxChar)
                    {
                        ps = badVal;
                    }
                    break;

                case PVM.prni:    // integer output
                    if (tracing)
                    {
                        results.Write(padding);
                    }
                    results.Write(Pop(), 0);
                    if (tracing)
                    {
                        results.WriteLine();
                    }
                    break;

                case PVM.prnb:    // boolean output
                    if (tracing)
                    {
                        results.Write(padding);
                    }
                    if (Pop() != 0)
                    {
                        results.Write(" true  ");
                    }
                    else
                    {
                        results.Write(" false ");
                    }
                    if (tracing)
                    {
                        results.WriteLine();
                    }
                    break;

                case PVM.prnc:    // character output
                    if (tracing)
                    {
                        results.Write(padding);
                    }
                    results.Write((char)(Math.Abs(Pop()) % (maxChar + 1)), 1);
                    if (tracing)
                    {
                        results.WriteLine();
                    }
                    break;

                case PVM.prns:    // string output
                    if (tracing)
                    {
                        results.Write(padding);
                    }
                    loop = Next();
                    while (ps == running && mem[loop] != 0)
                    {
                        results.Write((char)mem[loop]); loop--;
                        if (loop < stackBase)
                        {
                            ps = badMem;
                        }
                    }
                    if (tracing)
                    {
                        results.WriteLine();
                    }
                    break;

                case PVM.fprns:    // string output
                    if (tracing)
                    {
                        results.Write(padding);
                    }
                    loop = Next();
                    StringBuilder str = new StringBuilder();
                    while (ps == running && mem[loop] != 0)
                    {
                        //results.Write((char) mem[loop]); loop--;
                        str.Append((char)mem[loop]); loop--;
                        if (loop < stackBase)
                        {
                            ps = badMem;
                        }
                    }
                    results.Write(str.ToString(), Pop());
                    if (tracing)
                    {
                        results.WriteLine();
                    }
                    break;

                case PVM.prnl:    // newline
                    results.WriteLine();
                    break;

                case PVM.fprint:
                    tos = Pop();
                    sos = Pop();
                    results.Write(sos, tos);
                    break;

                case PVM.neg:     // integer negation
                    Push(-Pop());
                    break;

                case PVM.add:     // integer addition
                    tos = Pop(); Push(Pop() + tos);
                    break;

                case PVM.sub:     // integer subtraction
                    tos = Pop(); Push(Pop() - tos);
                    break;

                case PVM.mul:     // integer multiplication
                    tos = Pop();
                    sos = Pop();
                    if (tos != 0 && Math.Abs(sos) > maxInt / Math.Abs(tos))
                    {
                        ps = badVal;
                    }
                    else
                    {
                        Push(sos * tos);
                    }
                    break;

                case PVM.div:     // integer division (quotient)
                    tos = Pop();
                    if (tos == 0)
                    {
                        ps = divZero;
                    }
                    else
                    {
                        Push(Pop() / tos);
                    }
                    break;

                case PVM.max:     // Finds max. First Pops elements off stack
                                  // to see how many elements.
                    int numElements = Pop();
                    if (numElements == 0)
                    {
                        ps = noData;
                    }
                    else
                    {
                        List <int> maxElements = new List <int> ();
                        for (int i = 0; i < numElements; i++)
                        {
                            maxElements.Add(Pop());
                        }
                        maxElements.Sort();
                        maxElements.Reverse();
                        Push(maxElements[0]);
                    }
                    break;

                case PVM.min:     // Finds min. First Pops elements off stack
                                  // to see how many elements
                    int numMin = Pop();
                    if (numMin == 0)
                    {
                        ps = noData;
                    }
                    else
                    {
                        List <int> minElements = new List <int> ();
                        for (int i = 0; i < numMin; i++)
                        {
                            minElements.Add(Pop());
                        }
                        minElements.Sort();
                        Push(minElements[0]);
                    }
                    break;

                case PVM.sqrt:     // Square root
                    tos = Pop();
                    Push(Convert.ToInt32(System.Math.Sqrt(tos)));
                    break;

                case PVM.rem:     // integer division (remainder)
                    tos = Pop();
                    if (tos == 0)
                    {
                        ps = divZero;
                    }
                    else
                    {
                        Push(Pop() % tos);
                    }
                    break;

                case PVM.not:     // logical negation
                    Push(Pop() == 0 ? 1 : 0);
                    break;

                case PVM.and:     // logical and
                    tos = Pop(); Push(Pop() & tos);
                    break;

                case PVM.or:      // logical or
                    tos = Pop(); Push(Pop() | tos);
                    break;

                case PVM.ceq:     // logical equality
                    tos = Pop(); Push(Pop() == tos ? 1 : 0);
                    break;

                case PVM.cne:     // logical inequality
                    tos = Pop(); Push(Pop() != tos ? 1 : 0);
                    break;

                case PVM.clt:     // logical less
                    tos = Pop(); Push(Pop() < tos ? 1 : 0);
                    break;

                case PVM.cle:     // logical less or equal
                    tos = Pop(); Push(Pop() <= tos ? 1 : 0);
                    break;

                case PVM.cgt:     // logical greater
                    tos = Pop(); Push(Pop() > tos ? 1 : 0);
                    break;

                case PVM.cge:     // logical greater or equal
                    tos = Pop(); Push(Pop() >= tos ? 1 : 0);
                    break;

                case PVM.brn:     // unconditional branch
                    cpu.pc = Next();
                    if (cpu.pc < 0 || cpu.pc >= codeLen)
                    {
                        ps = badAdr;
                    }
                    break;

                case PVM.bze:     // pop top of stack, branch if false
                    target = Next();
                    if (Pop() == 0)
                    {
                        cpu.pc = target;
                        if (cpu.pc < 0 || cpu.pc >= codeLen)
                        {
                            ps = badAdr;
                        }
                    }
                    break;

                case PVM.bfalse:  // conditional short circuit "and" branch
                    target = Next();
                    if (mem[cpu.sp] == 0)
                    {
                        cpu.pc = target;
                    }
                    else
                    {
                        cpu.sp++;
                    }
                    break;

                case PVM.btrue:   // conditional short circuit "or" branch
                    target = Next();
                    if (mem[cpu.sp] == 1)
                    {
                        cpu.pc = target;
                    }
                    else
                    {
                        cpu.sp++;
                    }
                    break;

                case PVM.anew:    // heap array allocation
                    int size = Pop();
                    if (size <= 0 || size + 1 > cpu.sp - cpu.hp - 2)
                    {
                        ps = badAll;
                    }
                    else
                    {
                        mem[cpu.hp] = size; // first element stores size for bounds checking
                        Push(cpu.hp);
                        cpu.hp += size + 1; // bump heap pointer
                                            // elements are already initialized to 0 / null (why?)
                    }
                    break;

                case PVM.halt:    // halt
                    ps = finished;
                    break;

                case PVM.inc:     // integer ++
                    adr = Pop();
                    if (InBounds(adr))
                    {
                        mem[adr]++;
                    }
                    break;

                case PVM.dec:     // integer --
                    adr = Pop();
                    if (InBounds(adr))
                    {
                        mem[adr]--;
                    }
                    break;

                case PVM.incc:    // ++ characters
                    adr = Pop();
                    if (InBounds(adr))
                    {
                        if (mem[adr] < maxChar)
                        {
                            mem[adr]++;
                        }
                        else
                        {
                            ps = badVal;
                        }
                    }
                    break;

                case PVM.decc:    // -- characters
                    adr = Pop();
                    if (InBounds(adr))
                    {
                        if (mem[adr] > 0)
                        {
                            mem[adr]--;
                        }
                        else
                        {
                            ps = badVal;
                        }
                    }
                    break;

                case cpy:

                    int addrC1       = Pop();
                    int addrC2       = Pop();
                    int addrLengthC1 = mem[mem[addrC1]];
                    int addrLengthC2 = mem[mem[addrC2]];
                    if (addrLengthC1 != addrLengthC2)
                    {
                        ps = badVal;
                    }
                    else
                    {
                        int i = 1;
                        while ((i <= addrLengthC1))
                        {
                            mem[mem[addrC2] + i] = mem[mem[addrC1] + i];
                            i++;
                        }
                    }
                    break;

                case eql:
                    int addr1       = Pop();
                    int addr2       = Pop();
                    int addrLength1 = mem[mem[addr1]];
                    int addrLength2 = mem[mem[addr2]];
                    if (addrLength1 != addrLength2)
                    {
                        Push(0); // push flase if lenghts arnt ==
                    }
                    else
                    {
                        bool isEqual = true;
                        int  i       = 1;
                        while (i < addrLength1 + 1)
                        {
                            if (mem[mem[addr1] + i] != mem[mem[addr2] + i])
                            {
                                isEqual = false;
                            }
                            i++;
                        }
                        if (isEqual)
                        {
                            Push(1);
                        }
                        else
                        {
                            Push(0);
                        }
                    }
                    break;

                case PVM.stack:   // stack dump (debugging)
                    StackDump(results, pcNow);
                    break;

                case PVM.heap:    // heap dump (debugging)
                    HeapDump(results, pcNow);
                    break;

                case PVM.fhdr:    // allocate frame header
                    if (InBounds(cpu.sp - headerSize))
                    {
                        mem[cpu.sp - headerSize] = cpu.mp;
                        cpu.mp  = cpu.sp;
                        cpu.sp -= headerSize;
                    }
                    break;

                case PVM.call:    // call function
                    if (mem[cpu.pc] < 0)
                    {
                        ps = badAdr;
                    }
                    else
                    {
                        mem[cpu.mp - 2] = cpu.fp;
                        mem[cpu.mp - 3] = cpu.pc + 1;
                        cpu.fp          = cpu.mp;
                        cpu.pc          = mem[cpu.pc];
                    }
                    break;

                case PVM.retv:    // return from void function
                    cpu.sp = cpu.fp;
                    cpu.mp = mem[cpu.fp - 4];
                    cpu.pc = mem[cpu.fp - 3];
                    cpu.fp = mem[cpu.fp - 2];
                    break;

                default:          // unrecognized opcode
                    ps = badOp;
                    break;
                } // switch(cpu.ir)
            } while (ps == running);
            if (ps != finished)
            {
                PostMortem(results, pcNow);
            }
            TimeSpan ts          = timer.Elapsed;
            string   elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                                                 ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);

            Console.WriteLine("\n" + ops + " operations.  Run Time " + elapsedTime);
            timer.Reset();
            timer.Stop();
        } // PVM.Emulator
コード例 #25
0
    } // PVM.InBounds

    public static void Emulator(int initPC, int codeLen, int initSP,
                                InFile data, OutFile results, bool tracing,
                                bool traceStack, bool traceHeap) {
    // Emulates action of the codeLen instructions stored in mem[0 .. codeLen-1], with
    // program counter initialized to initPC, stack pointer initialized to initSP.
    // data and results are used for I/O.  Tracing at the code level may be requested

      int pcNow;                  // current program counter
      int loop;                   // internal loops
      int tos, sos;               // values popped from stack
      int adr;                    // effective address for memory accesses
      int target;                 // destination for branches

      stackBase = initSP;
      heapBase = codeLen;         // initialize boundaries
      cpu.hp = heapBase;          // initialize registers
      cpu.sp = stackBase;
      cpu.gp = stackBase;
      cpu.mp = stackBase;
      cpu.fp = stackBase;
      cpu.pc = initPC;            // initialize program counter
      for (int i = heapBase; i < stackBase; i++)
        mem[i] = 0;               // set entire memory to null or 0

      ps = running;               // prepare to execute
      int ops = 0;
      timer.Start();
      do {
        ops++;
        pcNow = cpu.pc;           // retain for tracing/postmortem
        if (cpu.pc < 0 || cpu.pc >= codeLen) {
          ps = badAdr;
          break;
        }
        cpu.ir = Next();          // fetch
        if (tracing) Trace(results, pcNow, traceStack, traceHeap);
        switch (cpu.ir) {         // execute
          case PVM.nop:           // no operation
            break;
          case PVM.dsp:           // decrement stack pointer (allocate space for variables)
            int localSpace = Next();
            cpu.sp -= localSpace;
            if (InBounds(cpu.sp)) // initialize all local variables to zero/null
              for (loop = 0; loop < localSpace; loop++)
                mem[cpu.sp + loop] = 0;
            break;
          case PVM.ldc:           // push constant value
            Push(Next());
            break;
          case PVM.ldc_m1:        // push constant -1
            Push(-1);
            break;
          case PVM.ldc_0:         // push constant 0
            Push(0);
            break;
          case PVM.ldc_1:         // push constant 1
            Push(1);
            break;
          case PVM.ldc_2:         // push constant 2
            Push(2);
            break;
          case PVM.ldc_3:         // push constant 3
            Push(3);
            break;
          case PVM.ldc_4:         // push constant 4
            Push(4);
            break;
          case PVM.ldc_5:         // push constant 5
            Push(5);
            break;
          case PVM.dup:           // duplicate top of stack
            tos = Pop();
            Push(tos); Push(tos);
            break;
          case PVM.lda:           // push local address
            adr = cpu.fp - 1 - Next();
            if (InBounds(adr)) Push(adr);
            break;
          case PVM.lda_0:         // push local address 0
            adr = cpu.fp - 1;
            if (InBounds(adr)) Push(adr);
            break;
          case PVM.lda_1:         // push local address 1
            adr = cpu.fp - 2;
            if (InBounds(adr)) Push(adr);
            break;
          case PVM.lda_2:         // push local address 2
            adr = cpu.fp - 3;
            if (InBounds(adr)) Push(adr);
            break;
          case PVM.lda_3:         // push local address 3
            adr = cpu.fp - 4;
            if (InBounds(adr)) Push(adr);
            break;
          case PVM.lda_4:         // push local address 4
            adr = cpu.fp - 5;
            if (InBounds(adr)) Push(adr);
            break;
          case PVM.lda_5:         // push local address 5
            adr = cpu.fp - 6;
            if (InBounds(adr)) Push(adr);
            break;
          case PVM.ldl:           // push local value
            adr = cpu.fp - 1 - Next();
            if (InBounds(adr)) Push(mem[adr]);
            break;
          case PVM.ldl_0:         // push value of local variable 0
            adr = cpu.fp - 1;
            if (InBounds(adr)) Push(mem[adr]);
            break;
          case PVM.ldl_1:         // push value of local variable 1
            adr = cpu.fp - 2;
            if (InBounds(adr)) Push(mem[adr]);
            break;
          case PVM.ldl_2:         // push value of local variable 2
            adr = cpu.fp - 3;
            if (InBounds(adr)) Push(mem[adr]);
            break;
          case PVM.ldl_3:         // push value of local variable 3
            adr = cpu.fp - 4;
            if (InBounds(adr)) Push(mem[adr]);
            break;
          case PVM.ldl_4:         // push value of local variable 4
            adr = cpu.fp - 5;
            if (InBounds(adr)) Push(mem[adr]);
            break;
          case PVM.ldl_5:         // push value of local variable 5
            adr = cpu.fp - 6;
            if (InBounds(adr)) Push(mem[adr]);
            break;
          case PVM.stl:           // store local value
            adr = cpu.fp - 1 - Next();
            if (InBounds(adr)) mem[adr] = Pop();
            break;
          case PVM.stlc:          // character checked pop to local variable
            tos = Pop(); adr = cpu.fp - 1 - Next();
            if (InBounds(adr))
              if (tos >= 0 && tos <= maxChar) mem[adr] = tos;
              else ps = badVal;
            break;
          case PVM.stl_0:         // pop to local variable 0
            adr = cpu.fp - 1;
            if (InBounds(adr)) mem[adr] = Pop();
            break;
          case PVM.stl_1:         // pop to local variable 1
            adr = cpu.fp - 2;
            if (InBounds(adr)) mem[adr] = Pop();
            break;
          case PVM.stl_2:         // pop to local variable 2
            adr = cpu.fp - 3;
            if (InBounds(adr)) mem[adr] = Pop();
            break;
          case PVM.stl_3:         // pop to local variable 3
            adr = cpu.fp - 4;
            if (InBounds(adr)) mem[adr] = Pop();
            break;
          case PVM.stl_4:         // pop to local variable 4
            adr = cpu.fp - 5;
            if (InBounds(adr)) mem[adr] = Pop();
            break;
          case PVM.stl_5:         // pop to local variable 5
            adr = cpu.fp - 6;
            if (InBounds(adr)) mem[adr] = Pop();
            break;
          case PVM.ldv:           // dereference
            adr = Pop();
            if (InBounds(adr)) Push(mem[adr]);
            break;
          case PVM.sto:           // store
            tos = Pop(); adr = Pop();
            if (InBounds(adr)) mem[adr] = tos;
            break;
          case PVM.stoc:          // character checked store
            tos = Pop(); adr = Pop();
            if (InBounds(adr))
              if (tos >= 0 && tos <= maxChar) mem[adr] = tos;
              else ps = badVal;
            break;
          case PVM.ldxa:          // heap array indexing
            adr = Pop();
            int heapPtr = Pop();
            if (heapPtr == 0) ps = nullRef;
            else if (heapPtr < heapBase || heapPtr >= cpu.hp) ps = badMem;
            else if (adr < 0 || adr >= mem[heapPtr]) ps = badInd;
            else Push(heapPtr + adr + 1); 
            break;
          case PVM.inpi:          // integer input
            adr = Pop();
            if (InBounds(adr)) {
              mem[adr] = data.ReadInt();
              if (data.Error()) ps = badData;
            }
            break;
          case PVM.inpb:          // boolean input
            adr = Pop();
            if (InBounds(adr)) {
              mem[adr] = data.ReadBool() ? 1 : 0;
              if (data.Error()) ps = badData;
            }
            break;
          case PVM.inpc:          // character input
            adr = Pop();
            if (InBounds(adr)) {
              mem[adr] = data.ReadChar();
              if (data.Error()) ps = badData;
            }
            break;
          case PVM.inpl:          // skip to end of input line
            data.ReadLine();
            break;
          case PVM.i2c:           // check (char) cast is in range
            if (mem[cpu.sp] < 0 || mem[cpu.sp] > maxChar) ps = badVal;
            break;
          case PVM.prni:          // integer output
            if (tracing) results.Write(padding);
            results.Write(Pop(), 0);
            if (tracing) results.WriteLine();
            break;
          case PVM.prnb:          // boolean output
            if (tracing) results.Write(padding);
            if (Pop() != 0) results.Write(" true  "); else results.Write(" false ");
            if (tracing) results.WriteLine();
            break;
          case PVM.prnc:          // character output
            if (tracing) results.Write(padding);
            results.Write((char) (Math.Abs(Pop()) % (maxChar + 1)), 1);
            if (tracing) results.WriteLine();
            break;
          case PVM.prns:          // string output
            if (tracing) results.Write(padding);
            loop = Next();
            while (ps == running && mem[loop] != 0) {
              results.Write((char) mem[loop]); loop--;
              if (loop < stackBase) ps = badMem;
            }
            if (tracing) results.WriteLine();
            break;
          case PVM.prnl:          // newline
            results.WriteLine();
            break;
          case PVM.neg:           // integer negation
            Push(-Pop());
            break;
          case PVM.add:           // integer addition
            tos = Pop(); Push(Pop() + tos);
            break;
          case PVM.sub:           // integer subtraction
            tos = Pop(); Push(Pop() - tos);
            break;
          case PVM.mul:           // integer multiplication
            tos = Pop();
            sos = Pop();
            if (tos != 0 && Math.Abs(sos) > maxInt / Math.Abs(tos)) ps = badVal;
            else Push(sos * tos);
            break;
          case PVM.div:           // integer division (quotient)
            tos = Pop();
            if (tos == 0) ps = divZero;
            else Push(Pop() / tos);
            break;
          case PVM.rem:           // integer division (remainder)
            tos = Pop();
            if (tos == 0) ps = divZero;
            else Push(Pop() % tos);
            break;
          case PVM.not:           // logical negation
            Push(Pop() == 0 ? 1 : 0);
            break;
          case PVM.and:           // logical and
            tos = Pop(); Push(Pop() & tos);
            break;
          case PVM.or:            // logical or
            tos = Pop(); Push(Pop() | tos);
            break;
          case PVM.ceq:           // logical equality
            tos = Pop(); Push(Pop() == tos ? 1 : 0);
            break;
          case PVM.cne:           // logical inequality
            tos = Pop(); Push(Pop() != tos ? 1 : 0);
            break;
          case PVM.clt:           // logical less
            tos = Pop(); Push(Pop() <  tos ? 1 : 0);
            break;
          case PVM.cle:           // logical less or equal
            tos = Pop(); Push(Pop() <= tos ? 1 : 0);
            break;
          case PVM.cgt:           // logical greater
            tos = Pop(); Push(Pop() >  tos ? 1 : 0);
            break;
          case PVM.cge:           // logical greater or equal
            tos = Pop(); Push(Pop() >= tos ? 1 : 0);
            break;
          case PVM.brn:           // unconditional branch
            cpu.pc = Next();
            if (cpu.pc < 0 || cpu.pc >= codeLen) ps = badAdr;
            break;
          case PVM.bze:           // pop top of stack, branch if false
            target = Next();
            if (Pop() == 0) {
              cpu.pc = target;
              if (cpu.pc < 0 || cpu.pc >= codeLen) ps = badAdr;
            }
            break;
          case PVM.bfalse:        // conditional short circuit "and" branch
            target = Next();
            if (mem[cpu.sp] == 0) cpu.pc = target; else cpu.sp++;
            break;
          case PVM.btrue:         // conditional short circuit "or" branch
            target = Next();
            if (mem[cpu.sp] == 1) cpu.pc = target; else cpu.sp++;
            break;
          case PVM.anew:          // heap array allocation
            int size = Pop();
            if (size <= 0 || size + 1 > cpu.sp - cpu.hp - 2)
              ps = badAll;
            else {
              mem[cpu.hp] = size; // first element stores size for bounds checking
              Push(cpu.hp);
              cpu.hp += size + 1; // bump heap pointer
                                  // elements are already initialized to 0 / null (why?)
            }
            break;
          case PVM.halt:          // halt
            ps = finished;
            break;
          case PVM.inc:           // integer ++
            adr = Pop();
            if (InBounds(adr)) mem[adr]++;
            break;
          case PVM.dec:           // integer --
            adr = Pop();
            if (InBounds(adr)) mem[adr]--;
            break;
          case PVM.incc:          // ++ characters
            adr = Pop();
            if (InBounds(adr))
              if (mem[adr] < maxChar) mem[adr]++;
              else ps = badVal;
            break;
          case PVM.decc:          // -- characters
            adr = Pop();
            if (InBounds(adr))
              if (mem[adr] > 0) mem[adr]--;
              else ps = badVal;
            break;
          case PVM.stack:         // stack dump (debugging)
            StackDump(results, pcNow);
            break;
          case PVM.heap:          // heap dump (debugging)
            HeapDump(results, pcNow);
            break;
          case PVM.fhdr:          // allocate frame header
            if (InBounds(cpu.sp - headerSize)) {
              mem[cpu.sp - headerSize] = cpu.mp;
              cpu.mp = cpu.sp;
              cpu.sp -= headerSize;
            }
            break;
          case PVM.call:          // call function
            if (mem[cpu.pc] < 0) ps = badAdr;
            else {
              mem[cpu.mp - 2] = cpu.fp;
              mem[cpu.mp - 3] = cpu.pc + 1;
              cpu.fp = cpu.mp;
              cpu.pc = mem[cpu.pc];
            }
            break;
          case PVM.retv:          // return from void function
            cpu.sp = cpu.fp;
            cpu.mp = mem[cpu.fp - 4];
            cpu.pc = mem[cpu.fp - 3];
            cpu.fp = mem[cpu.fp - 2];
            break;
		  case PVM.max:
			tos = Pop();
			sos = Pop();
			if (tos > sos) Push(tos);				
			else Push(sos);
		    break;
		  case PVM.min:
			tos = Pop();
			sos = Pop();
			if (tos < sos) Push(tos);				
			else Push(sos);
		    break;
		  case PVM.sqr:
			tos = Pop();
			Push((int)Math.Sqrt(tos));
		    break;
		  case PVM.aceq:
		    tos =Pop(); //address of array 1
			sos = Pop(); //address of array 1
			int len_1 = mem[tos];
			int len_2 = mem[sos];
			if(len_1!=len_2){ 
				Push(0); // if lengths aren't equal then arrays can't be equal
			}
			else{
				int i=0;
				while(i<len_1 && mem[tos+1+i] == mem[sos+1+i]){
					i++;
				}
				if(i==len_1) 
					Push(1);
				else
					Push(0);	  		
			}
			break;
			case PVM.acpy:
			    tos =Pop(); //address to be copied
			    sos = Pop(); //address of array to be assigned 
				if(mem[tos]==mem[sos]){ //if the lengths are not the same leave it
				  int i=0;
				  while(i<mem[tos]){
					  mem[sos+1+i] = mem[tos+1+i];
				  }
				
				}
				/*
				else{
					IO.WriteLine("Arrays must be the same size to be copied!");
				    ps=badVal;
				}
				*/
			break;
			case PVM.wprni:          // integer output with wdith
				if (tracing) results.Write(padding);
				tos=Pop();
				results.Write(Pop(),tos);
				if (tracing) results.WriteLine();
            break;
          case PVM.wprnb:          // boolean output with width
            if (tracing) results.Write(padding);
			tos = Pop();
            if (Pop() != 0) results.Write("true",tos); else results.Write("false",tos);
            if (tracing) results.WriteLine();
            break;
          case PVM.wprnc:          // character output with width
            if (tracing) results.Write(padding);
			tos = Pop();
            results.Write((char) (Math.Abs(Pop()) % (maxChar + 1)), tos);
            if (tracing) results.WriteLine();
			break;
          default:                // unrecognized opcode
            ps = badOp;
            break;
        } // switch(cpu.ir)
      } while (ps == running);
      if (ps != finished) PostMortem(results, pcNow);
      TimeSpan ts = timer.Elapsed;
      string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                                         ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
      Console.WriteLine("\n" + ops + " operations.  Run Time " + elapsedTime);
      timer.Reset();
      timer.Stop();
    } // PVM.Emulator
コード例 #26
0
        } // PVM.InBounds

        public static void Emulator(int initPC, int codeLen, int initSP,
                                    InFile data, OutFile results, bool tracing,
                                    bool traceStack, bool traceHeap)
        {
            // Emulates action of the codeLen instructions stored in mem[0 .. codeLen-1], with
            // program counter initialized to initPC, stack pointer initialized to initSP.
            // data and results are used for I/O.  Tracing at the code level may be requested

            int pcNow;            // current program counter
            int loop;             // internal loops
            int tos, sos;         // value popped from stack
            int adr;              // effective address for memory accesses

            stackBase = initSP;
            heapBase  = codeLen;  // initialize boundaries
            cpu.hp    = heapBase; // initialize registers
            cpu.sp    = stackBase;
            cpu.gp    = stackBase;
            cpu.mp    = stackBase;
            cpu.fp    = stackBase;
            cpu.pc    = initPC;   // initialize program counter
            ps        = running;  // prepare to execute
            int ops = 0;

            timer.Start();
            do
            {
                ops++;
                pcNow = cpu.pc;   // retain for tracing/postmortem
                if (cpu.pc < 0 || cpu.pc >= codeLen)
                {
                    ps = badAdr;
                    break;
                }
                cpu.ir = Next();  // fetch
                if (tracing)
                {
                    Trace(results, pcNow, traceStack, traceHeap);
                }
                switch (cpu.ir)   // execute
                {
                case PVM.nop:     // no operation
                    break;

                case PVM.dsp:     // decrement stack pointer (allocate space for variables)
                    int localSpace = Next();
                    cpu.sp -= localSpace;
                    if (InBounds(cpu.sp)) // initialize
                    {
                        for (loop = 0; loop < localSpace; loop++)
                        {
                            mem[cpu.sp + loop] = 0;
                        }
                    }
                    break;

                case PVM.ldc:     // push constant value
                    Push(Next());
                    break;

                case PVM.lda:     // push local address
                    adr = cpu.fp - 1 - Next();
                    if (InBounds(adr))
                    {
                        Push(adr);
                    }
                    break;

                case PVM.ldv:     // dereference
                    Push(mem[Pop()]);
                    break;

                case PVM.sto:     // store
                    tos = Pop(); adr = Pop();
                    if (InBounds(adr))
                    {
                        mem[adr] = tos;
                    }
                    break;

                case PVM.ldxa:    // heap array indexing
                    adr = Pop();
                    int heapPtr = Pop();
                    if (heapPtr == 0)
                    {
                        ps = nullRef;
                    }
                    else if (heapPtr < heapBase || heapPtr >= cpu.hp)
                    {
                        ps = badMem;
                    }
                    else if (adr < 0 || adr >= mem[heapPtr])
                    {
                        ps = badInd;
                    }
                    else
                    {
                        Push(heapPtr + adr + 1);
                    }
                    break;

                case PVM.inpi:    // integer input
                    adr = Pop();
                    if (InBounds(adr))
                    {
                        mem[adr] = data.ReadInt();
                        if (data.Error())
                        {
                            ps = badData;
                        }
                    }
                    break;

                case PVM.prni:    // integer output
                    if (tracing)
                    {
                        results.Write(padding);
                    }
                    results.Write(Pop(), 0);
                    if (tracing)
                    {
                        results.WriteLine();
                    }
                    break;

                case PVM.inpb:    // boolean input
                    adr = Pop();
                    if (InBounds(adr))
                    {
                        mem[adr] = data.ReadBool() ? 1 : 0;
                        if (data.Error())
                        {
                            ps = badData;
                        }
                    }
                    break;

                case PVM.prnb:    // boolean output
                    if (tracing)
                    {
                        results.Write(padding);
                    }
                    if (Pop() != 0)
                    {
                        results.Write(" true  ");
                    }
                    else
                    {
                        results.Write(" false ");
                    }
                    if (tracing)
                    {
                        results.WriteLine();
                    }
                    break;

                case PVM.prns:    // string output
                    if (tracing)
                    {
                        results.Write(padding);
                    }
                    loop = Next();
                    while (ps == running && mem[loop] != 0)
                    {
                        results.Write((char)mem[loop]); loop--;
                        if (loop < stackBase)
                        {
                            ps = badMem;
                        }
                    }
                    if (tracing)
                    {
                        results.WriteLine();
                    }
                    break;

                case PVM.prnl:    // newline
                    results.WriteLine();
                    break;

                case PVM.neg:     // integer negation
                    Push(-Pop());
                    break;

                case PVM.add:     // integer addition
                    tos = Pop(); Push(Pop() + tos);
                    break;

                case PVM.sub:     // integer subtraction
                    tos = Pop(); Push(Pop() - tos);
                    break;

                case PVM.mul:     // integer multiplication
                    //tos = Pop(); Push(Pop() * tos);
                    tos = Pop();
                    int prod = Pop();
                    if (tos > 0 && prod > 2147483647 / tos)
                    {
                        Push(tos * prod);
                    }
                    else
                    {
                        ps = badVal;
                    }
                    break;

                case PVM.div:     // integer division (quotient)
                    //tos = Pop(); Push(Pop() / tos);
                    tos = Pop();
                    if (tos != 0)
                    {
                        Push(Pop() / tos);
                    }
                    else
                    {
                        ps = divZero;
                    }
                    break;

                case PVM.rem:     // integer division (remainder)
                    tos = Pop(); Push(Pop() % tos);
                    break;

                case PVM.not:     // logical negation
                    Push(Pop() == 0 ? 1 : 0);
                    break;

                case PVM.and:     // logical and
                    tos = Pop(); Push(Pop() & tos);
                    break;

                case PVM.or:      // logical or
                    tos = Pop(); Push(Pop() | tos);
                    break;

                case PVM.ceq:     // logical equality
                    tos = Pop(); Push(Pop() == tos ? 1 : 0);
                    break;

                case PVM.cne:     // logical inequality
                    tos = Pop(); Push(Pop() != tos ? 1 : 0);
                    break;

                case PVM.clt:     // logical less
                    tos = Pop(); Push(Pop() < tos ? 1 : 0);
                    break;

                case PVM.cle:     // logical less or equal
                    tos = Pop(); Push(Pop() <= tos ? 1 : 0);
                    break;

                case PVM.cgt:     // logical greater
                    tos = Pop(); Push(Pop() > tos ? 1 : 0);
                    break;

                case PVM.cge:     // logical greater or equal
                    tos = Pop(); Push(Pop() >= tos ? 1 : 0);
                    break;

                case PVM.brn:     // unconditional branch
                    cpu.pc = Next();
                    if (cpu.pc < 0 || cpu.pc >= codeLen)
                    {
                        ps = badAdr;
                    }
                    break;

                case PVM.bze:     // pop top of stack, branch if false
                    int target = Next();
                    if (Pop() == 0)
                    {
                        cpu.pc = target;
                        if (cpu.pc < 0 || cpu.pc >= codeLen)
                        {
                            ps = badAdr;
                        }
                    }
                    break;

                case PVM.anew:    // heap array allocation
                    int size = Pop();
                    if (size <= 0 || size + 1 > cpu.sp - cpu.hp - 2)
                    {
                        ps = badAll;
                    }
                    else
                    {
                        mem[cpu.hp] = size;
                        Push(cpu.hp);
                        cpu.hp += size + 1;
                    }
                    break;

                case PVM.halt:    // halt
                    ps = finished;
                    break;

                case PVM.stk:     // stack dump (debugging)
                    StackDump(results, pcNow);
                    break;

                case PVM.heap:     // heap dump (debugging)
                    HeapDump(results, pcNow);
                    break;

                case PVM.ldc_0:   // push constant 0
                case PVM.ldc_1:   // push constant 1
                case PVM.ldc_2:   // push constant 2
                case PVM.ldc_3:   // push constant 3
                case PVM.lda_0:   // push local address 0
                case PVM.lda_1:   // push local address 1
                case PVM.lda_2:   // push local address 2
                case PVM.lda_3:   // push local address 3
                case PVM.ldl:     // push local value
                case PVM.ldl_0:   // push value of local variable 0
                case PVM.ldl_1:   // push value of local variable 1
                case PVM.ldl_2:   // push value of local variable 2
                case PVM.ldl_3:   // push value of local variable 3
                case PVM.stl:     // store local value
                case PVM.stlc:    // store local value
                case PVM.stl_0:   // pop to local variable 0
                case PVM.stl_1:   // pop to local variable 1
                case PVM.stl_2:   // pop to local variable 2
                case PVM.stl_3:   // pop to local variable 3
                case PVM.stoc:    // character checked store
                case PVM.inpc:    // character input
                case PVM.prnc:    // character output
                case PVM.cap:     // toUpperCase
                case PVM.low:     // toLowerCase
                case PVM.islet:   // isLetter
                case PVM.inc:     // ++
                case PVM.dec:     // --
                default:          // unrecognized opcode
                    ps = badOp;
                    break;
                }
            } while (ps == running);
            TimeSpan ts = timer.Elapsed;

            // Format and display the TimeSpan value.
            string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                                               ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);

            Console.WriteLine("\n\n" + ops + " operations.  Run Time " + elapsedTime + "\n\n");
            if (ps != finished)
            {
                PostMortem(results, pcNow);
            }
            timer.Reset();
            timer.Stop();
        } // PVM.Emulator
コード例 #27
0
ファイル: PVM.cs プロジェクト: Lexical-Luke/Compilers
        } // PVM.PostMortem

        // The interpreters and utility methods

        public static void Emulator(int initPC, int codeLen, int initSP,
                                    InFile data, OutFile results, bool tracing)
        {
            // Emulates action of the codeLen instructions stored in mem[0 .. codeLen-1], with
            // program counter initialized to initPC, stack pointer initialized to initSP.
            // data and results are used for I/O.  Tracing at the code level may be requested

            int pcNow;            // current program counter
            int loop;             // internal loops
            int tos, sos;         // value popped from stack

            stackBase = initSP;
            heapBase  = codeLen;  // initialize boundaries
            cpu.hp    = heapBase; // initialize registers
            cpu.sp    = stackBase;
            cpu.gp    = stackBase;
            cpu.mp    = stackBase;
            cpu.fp    = stackBase;
            cpu.pc    = initPC;   // initialize program counter
            ps        = running;  // prepare to execute
            int ops = 0;

            timer.Start();
            do
            {
                ops++;
                pcNow  = cpu.pc;        // retain for tracing/postmortem
                cpu.ir = mem[cpu.pc++]; // fetch
//        if (tracing) Trace(results, pcNow);
                switch (cpu.ir)         // execute
                {
                case PVM.nop:           // no operation
                    break;

                case PVM.dsp:     // decrement stack pointer (allocate space for variables)
                    cpu.sp -= mem[cpu.pc++];
                    break;

                case PVM.ldc:     // push constant value
                    mem[--cpu.sp] = mem[cpu.pc++];
                    break;

                case PVM.lda:     // push local address
                    mem[--cpu.sp] = cpu.fp - 1 - mem[cpu.pc++];
                    break;

                case PVM.ldv:     // dereference
                    mem[cpu.sp] = mem[mem[cpu.sp]];
                    break;

                case PVM.sto:     // store
                    tos = mem[cpu.sp++]; mem[mem[cpu.sp++]] = tos;
                    break;

                case PVM.ldxa:    // heap array indexing
                    int adr     = mem[cpu.sp++];
                    int heapPtr = mem[cpu.sp];
                    if (heapPtr == 0)
                    {
                        ps = nullRef;
                    }
                    else if (heapPtr < heapBase || heapPtr >= cpu.hp)
                    {
                        ps = badMem;
                    }
                    else if (adr < 0 || adr >= mem[heapPtr])
                    {
                        ps = badInd;
                    }
                    else
                    {
                        mem[cpu.sp] = heapPtr + adr + 1;
                    }
                    break;

                case PVM.inpi:    // integer input
                    mem[mem[cpu.sp++]] = data.ReadInt();
                    break;

                case PVM.prni:    // integer output
//            if (tracing) results.Write(padding);
                    results.Write(mem[cpu.sp++], 0);
//            if (tracing) results.WriteLine();
                    break;

                case PVM.inpb:    // boolean input
                    mem[mem[cpu.sp++]] = data.ReadBool() ? 1 : 0;
                    break;

                case PVM.prnb:    // boolean output
//            if (tracing) results.Write(padding);
                    if (mem[cpu.sp++] != 0)
                    {
                        results.Write(" true  ");
                    }
                    else
                    {
                        results.Write(" false ");
                    }
//            if (tracing) results.WriteLine();
                    break;

                case PVM.prns:    // string output
//            if (tracing) results.Write(padding);
                    loop = mem[cpu.pc++];
                    while (mem[loop] != 0)
                    {
                        results.Write((char)mem[loop]); loop--;
                    }
//            if (tracing) results.WriteLine();
                    break;

                case PVM.prnl:    // newline
                    results.WriteLine();
                    break;

                case PVM.neg:     // integer negation
                    mem[cpu.sp] = -mem[cpu.sp];
                    break;

                case PVM.add:     // integer addition
                    tos = mem[cpu.sp++]; mem[cpu.sp] += tos;
                    break;

                case PVM.sub:     // integer subtraction
                    tos = mem[cpu.sp++]; mem[cpu.sp] -= tos;
                    break;

                case PVM.mul:     // integer multiplication
                    tos = mem[cpu.sp++];
                    if (tos != 0 && Math.Abs(mem[cpu.sp]) > maxInt / Math.Abs(tos))
                    {
                        ps = badVal;
                    }
                    else
                    {
                        mem[cpu.sp] *= tos;
                    }
                    break;

                case PVM.div:     // integer division (quotient)
                    tos = mem[cpu.sp++];
                    if (tos != 0)
                    {
                        mem[cpu.sp] /= tos;
                    }
                    else
                    {
                        ps = divZero;
                    }
                    break;

                case PVM.rem:     // integer division (remainder)
                    tos = mem[cpu.sp++];
                    if (tos != 0)
                    {
                        mem[cpu.sp] %= tos;
                    }
                    else
                    {
                        ps = divZero;
                    }
                    break;

                case PVM.not:     // logical negation
                    mem[cpu.sp] = mem[cpu.sp] == 0 ? 1 : 0;
                    break;

                case PVM.and:     // logical and
                    tos = mem[cpu.sp++]; mem[cpu.sp] &= tos;
                    break;

                case PVM.or:      // logical or
                    tos = mem[cpu.sp++]; mem[cpu.sp] |= tos;
                    break;

                case PVM.ceq:     // logical equality
                    tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] == tos ? 1 : 0;
                    break;

                case PVM.cne:     // logical inequality
                    tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] != tos ? 1 : 0;
                    break;

                case PVM.clt:     // logical less
                    tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] < tos ? 1 : 0;
                    break;

                case PVM.cle:     // logical less or equal
                    tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] <= tos ? 1 : 0;
                    break;

                case PVM.cgt:     // logical greater
                    tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] > tos ? 1 : 0;
                    break;

                case PVM.cge:     // logical greater or equal
                    tos = mem[cpu.sp++]; mem[cpu.sp] = mem[cpu.sp] >= tos ? 1 : 0;
                    break;

                case PVM.brn:     // unconditional branch
                    cpu.pc = mem[cpu.pc++];
                    break;

                case PVM.bze:     // pop top of stack, branch if false
                    int target = mem[cpu.pc++];
                    if (mem[cpu.sp++] == 0)
                    {
                        cpu.pc = target;
                    }
                    break;

                case PVM.anew:    // heap array allocation
                    int size = mem[cpu.sp];
                    if (size <= 0 || size + 1 > cpu.sp - cpu.hp - 2)
                    {
                        ps = badAll;
                    }
                    else
                    {
                        mem[cpu.hp] = size;
                        mem[cpu.sp] = cpu.hp;
                        cpu.hp     += size + 1;
                    }
                    break;

                case PVM.halt:    // halt
                    ps = finished;
                    break;

                case PVM.stk:     // stack dump (debugging)
                    StackDump(results, pcNow);
                    break;

                case PVM.heap:     // heap dump (debugging)
                    HeapDump(results, pcNow);
                    break;

                case PVM.ldc_0:   // push constant 0
                    mem[--cpu.sp] = 0;
                    break;

                case PVM.ldc_1:   // push constant 1
                    mem[--cpu.sp] = 1;
                    break;

                case PVM.ldc_2:   // push constant 2
                    mem[--cpu.sp] = 2;
                    break;

                case PVM.ldc_3:   // push constant 3
                    mem[--cpu.sp] = 3;
                    break;

                case PVM.lda_0:   // push local address 0
                    mem[--cpu.sp] = cpu.fp - 1;
                    break;

                case PVM.lda_1:   // push local address 1
                    mem[--cpu.sp] = cpu.fp - 2;
                    break;

                case PVM.lda_2:   // push local address 2
                    mem[--cpu.sp] = cpu.fp - 3;
                    break;

                case PVM.lda_3:   // push local address 3
                    mem[--cpu.sp] = cpu.fp - 4;
                    break;

                case PVM.ldl:     // push local value
                    mem[--cpu.sp] = mem[cpu.fp - 1 - mem[cpu.pc++]];
                    break;

                case PVM.ldl_0:   // push value of local variable 0
                    mem[--cpu.sp] = mem[cpu.fp - 1];
                    break;

                case PVM.ldl_1:   // push value of local variable 1
                    mem[--cpu.sp] = mem[cpu.fp - 2];
                    break;

                case PVM.ldl_2:   // push value of local variable 2
                    mem[--cpu.sp] = mem[cpu.fp - 3];
                    break;

                case PVM.ldl_3:   // push value of local variable 3
                    mem[--cpu.sp] = mem[cpu.fp - 4];
                    break;

                case PVM.stl:     // store local value
                    mem[cpu.fp - 1 - mem[cpu.pc++]] = mem[cpu.sp++];
                    break;

                case PVM.stlc:    // store local character value
                    mem[cpu.fp - 1 - mem[cpu.pc++]] = mem[cpu.sp++];
                    break;

                case PVM.stl_0:   // pop to local variable 0
                    mem[cpu.fp - 1] = mem[cpu.sp++];
                    break;

                case PVM.stl_1:   // pop to local variable 1
                    mem[cpu.fp - 2] = mem[cpu.sp++];
                    break;

                case PVM.stl_2:   // pop to local variable 2
                    mem[cpu.fp - 3] = mem[cpu.sp++];
                    break;

                case PVM.stl_3:   // pop to local variable 3
                    mem[cpu.fp - 4] = mem[cpu.sp++];
                    break;

                case PVM.i2c:     // check convert character to integer - unchecked
                    break;

                case PVM.stoc:    // character checked store
                    tos = mem[cpu.sp++]; mem[mem[cpu.sp++]] = tos;
                    break;

                case PVM.inpc:    // character input
                    mem[mem[cpu.sp++]] = data.ReadChar();
                    break;

                case PVM.prnc:    // character output
//            if (tracing) results.Write(padding);
                    results.Write((char)(Math.Abs(mem[cpu.sp++]) % (maxChar + 1)), 1);
//            if (tracing) results.WriteLine();
                    break;

                case PVM.low:     // toLowerCase
                    mem[cpu.sp] = Char.ToLower((char)mem[cpu.sp]);
                    break;

                case PVM.islet:   // isLetter
                    mem[cpu.sp] = Char.IsLetter((char)mem[cpu.sp]) ? 1 : 0;
                    break;

                case PVM.inc:     // ++
                    mem[mem[cpu.sp++]]++;
                    break;

                case PVM.dec:     // --
                    mem[mem[cpu.sp++]]--;
                    break;

                default:          // unrecognized opcode
                    ps = badOp;
                    break;
                }
            } while (ps == running);
            TimeSpan ts          = timer.Elapsed;
            string   elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                                                 ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);

            Console.WriteLine("\n\n" + ops + " operations.  Run Time " + elapsedTime + "\n\n");
            if (ps != finished)
            {
                PostMortem(results, pcNow);
            }
            timer.Reset();
            timer.Stop();
        } // PVM.Emulator
コード例 #28
0
        public static bool Assemble(string sourceName)
        {
            // Assembles source code from an input file sourceName and loads codeLen
            // words of code directly into memory PVM.mem[0 .. codeLen-1],
            // storing strings in the string pool at the top of memory in
            // PVM.mem[stkBase .. memSize-1].
            //
            // Returns true if assembly succeeded
            //
            // Instruction format :
            //    Instruction  = [ Label ] Opcode [ AddressField ] [ Comment ]
            //    Label        = [ "{" ] Integer [ "}" ]
            //    Opcode       = Mnemonic
            //    AddressField = Integer | "String"
            //    Comment      = String
            //
            // A string AddressField may only be used with a PRNS opcode
            // Instructions are supplied one to a line; terminated at end of input file

            string mnemonic; // mnemonic for matching
            char   quote;    // string delimiter

            src = new InFile(sourceName);
            if (src.OpenError())
            {
                Console.WriteLine("Could not open input file\n");
                System.Environment.Exit(1);
            }
            Console.WriteLine("Assembling code ... \n");
            codeLen = 0;
            stkBase = PVM.memSize - 1;
            okay    = true;
            do
            {
                SkipLabel();                         // ignore labels at start of line
                if (!src.EOF())                      // we must have a line
                {
                    mnemonic = ReadMnemonic();       // unpack mnemonic
                    if (mnemonic == null)
                    {
                        continue;                    // ignore directives
                    }
                    int op = PVM.OpCode(mnemonic);   // look it up
                    PVM.mem[codeLen] = op;           // store in memory
                    switch (op)
                    {
                    case PVM.prns:                   // requires a string address field
                        do
                        {
                            quote = src.ReadChar();  // search for opening quote character
                        }while (quote != '"' && quote != '\'' && quote != '\n');
                        codeLen          = (codeLen + 1) % PVM.memSize;
                        PVM.mem[codeLen] = stkBase - 1; // pointer to start of string
                        if (quote == '\n')
                        {
                            Error("Missing string address", codeLen);
                        }
                        else                         // stack string in literal pool
                        {
                            ch = src.ReadChar();
                            while (ch != quote && ch != '\n')
                            {
                                if (ch == '\\')
                                {
                                    ch = src.ReadChar();
                                    if (ch == '\n')  // closing quote missing
                                    {
                                        Error("Malformed string", codeLen);
                                    }
                                    switch (ch)
                                    {
                                    case 't': ch = '\t'; break;

                                    case 'n': ch = '\n'; break;

                                    case '\"': ch = '\"'; break;

                                    case '\'': ch = '\''; break;

                                    default: break;
                                    }
                                }
                                stkBase--;
                                PVM.mem[stkBase] = ch;
                                ch = src.ReadChar();
                            }
                            if (ch == '\n')          // closing quote missing
                            {
                                Error("Malformed string", codeLen);
                            }
                        }
                        stkBase--;
                        PVM.mem[stkBase] = 0;        // terminate string with nul
                        break;

                    case PVM.brn:                    // all require numeric address field
                    case PVM.bze:
                    case PVM.dsp:
                    case PVM.lda:
                    case PVM.ldc:
                        codeLen = (codeLen + 1) % PVM.memSize;
                        if (ch == '\n')              // no field could be found
                        {
                            Error("Missing address", codeLen);
                        }
                        else                         // unpack it and store
                        {
                            PVM.mem[codeLen] = src.ReadInt();
                            if (src.Error())
                            {
                                Error("Bad address", codeLen);
                            }
                        }
                        break;

                    case PVM.nul:                    // unrecognized mnemonic
                        Console.Write(mnemonic);
                        Error(" - Invalid opcode", codeLen);
                        break;

                    default:                         // no address needed
                        break;
                    }
                    if (!src.EOL())
                    {
                        src.ReadLn();                // skip comments
                    }
                    codeLen = (codeLen + 1) % PVM.memSize;
                }
            } while (!src.EOF());
            for (int i = codeLen; i < stkBase; i++)  // fill with invalid OpCodes
            {
                PVM.mem[i] = PVM.nul;
            }
            return(okay);
        }
コード例 #29
0
        static void Main(string[] args)

        {
            int[,] bob = new int[9, 9];


            if (args.Length != 1)
            {
                Console.WriteLine("missing args");
                System.Environment.Exit(1);
            }
            //                             attempt to open data file
            InFile data = new InFile(args[0]);

            if (data.OpenError())
            {
                Console.WriteLine("cannot open " + args[0]);
                System.Environment.Exit(1);
            }

            for (int row = 0; row < 9; row++)
            {
                for (int col = 0; col < 9; col++)
                {
                    if (row < 9 && col < 9)
                    {
                        bob[row, col] = data.ReadInt();
                    }
                }
            }

            void printBoard(int[,] board)
            {
                Console.Write(String.Format("{0,-2}{1,-2}{2,-2}{3,-2}{4,-2}{5,-2}{6,-2}{7,-2}{8,-2}{9,-2}", "", 0, 1, 2, 3, 4, 5, 6, 7, 8));
                for (int row = 0; row < 9; row++)
                {
                    Console.WriteLine();
                    for (int col = 0; col < 9; col++)
                    {
                        if (col == 0)
                        {
                            Console.Write(String.Format("{0,-2}{1,-2}", row, board[row, col]));
                        }
                        else
                        {
                            Console.Write(String.Format("{0,-2}", board[row, col]));
                        }
                    }
                }
                Console.WriteLine();
            }

            void update(int[,] board)
            {
                Console.WriteLine("\n\nYour move - row [0..8] col [0..8] val [1-9] (ENTER to quit)");
                string move = Console.ReadLine();
                //Console.Write(move);
                int count = 0, row = 0, col = 0, val = 0;

                try
                {
                    for (int i = 0; i < move.Length; i++)
                    {
                        if (count == 0)
                        {
                            row = Convert.ToInt32(Convert.ToString(move[i]));
                        }

                        if (count == 2)
                        {
                            col = Convert.ToInt32(Convert.ToString(move[i]));
                        }

                        if (count == 4)
                        {
                            val = Convert.ToInt32(Convert.ToString(move[i]));
                        }

                        count++;
                    }
                    if (val == 0)
                    {
                        System.Environment.Exit(0);
                    }

                    if (checkMove(board, row, col, val) == true)
                    {
                        board[row, col] = val;
                        printBoard(board);
                        printAvailable();
                    }
                    else
                    {
                        Console.WriteLine("can't make the move");
                    }

                    update(bob);
                }catch (Exception o)
                { Console.WriteLine("Invalid input (format is {row col val})"); update(bob); }
            }

            string posAvailable(int[,] board, int row, int col) // print numbers available
            {
                int    i         = 1;
                string available = "";

                while (i < 10)
                {
                    if (board[row, col] > 0)
                    {
                        available = "..";
                    }
                    else
                    if (checkMove(board, row, col, i))
                    {
                        available += "" + i;
                    }
                    i++;
                }
                return(available);
            }

            void printAvailable()
            {
                Console.WriteLine();
                Console.Write(String.Format("{0,-6} {1,-6} {2,-6} {3,-6} {4,-6} {5,-6} {6,-6} {7,-6} {8,-6} {9,-6}\n", "", 0, 1, 2, 3, 4, 5, 6, 7, 8));
                for (int row = 0; row < 9; row++)
                {
                    Console.WriteLine();
                    for (int col = 0; col < 9; col++)
                    {
                        if (col == 0)
                        {
                            Console.Write(String.Format("{0,-6}", row));
                            Console.Write(String.Format("{0,-7}", posAvailable(bob, row, col)));
                        }
                        else
                        {
                            Console.Write(String.Format("{0,-7}", posAvailable(bob, row, col)));
                        }
                    }
                }
            }

            bool checkMove(int[,] board, int row, int col, int value) //if value doesnt exist in the row,col or box then true the move is valid
            {
                bool result = true;

                if (CheckRow(board, row, col, value) == true)
                {
                    return(false);
                }
                else if (CheckCol(board, row, col, value) == true)
                {
                    return(false);
                }
                else if (CheckBox(board, row, col, value) == true)
                {
                    return(false);
                }

                return(result);
            }

            bool CheckRow(int[,] board, int row, int col, int value) //if value exist in the row returns true
            {
                bool result = false;

                for (int i = 0; i < 9; i++)
                {
                    if (board[i, col] == value)
                    {
                        return(true);
                    }
                }

                return(result);
            }

            bool CheckCol(int[,] board, int row, int col, int value) //if value exist in the col returns true
            {
                bool result = false;

                for (int i = 0; i < 9; i++)
                {
                    if (board[row, i] == value)
                    {
                        return(true);
                    }
                }

                return(result);
            }

            bool CheckBox(int[,] board, int row, int col, int value)//if value exist in the box returns true
            {
                bool result   = false;
                int  startrow = 0;
                int  startcol = 0;
                int  c        = 0;

                if (row >= 0 && row <= 2)
                {
                    startrow = 0;
                }
                if (row >= 3 && row <= 5)
                {
                    startrow = 3;
                }
                if (row >= 6 && row <= 8)
                {
                    startrow = 6;
                }
                if (col >= 0 && row <= 2)
                {
                    startcol = 0;
                }
                if (col >= 3 && row <= 5)
                {
                    startcol = 3;
                }
                if (col >= 6 && row <= 8)
                {
                    startcol = 6;
                }
                for (int i = startrow; i < startrow + 3; i++)
                {
                    for (int j = startcol; j < startcol + 3; j++)
                    {
                        if (board[i, j] == value)
                        {
                            return(true);
                        }
                    }
                }

                return(result);
            }

            printBoard(bob);
            printAvailable();
            update(bob);
        } //Main
コード例 #30
0
ファイル: PVM.cs プロジェクト: RobinV07/Compilers-Prac5
        } // PVM.InBounds

        public static void Emulator(int initPC, int codeLen, int initSP,
                                    InFile data, OutFile results, bool tracing,
                                    bool traceStack, bool traceHeap)
        {
            // Emulates action of the codeLen instructions stored in mem[0 .. codeLen-1], with
            // program counter initialized to initPC, stack pointer initialized to initSP.
            // data and results are used for I/O.  Tracing at the code level may be requested

            int pcNow;            // current program counter
            int loop;             // internal loops
            int tos, sos;         // values popped from stack
            int adr;              // effective address for memory accesses
            int target;           // destination for
            int store  = 0;       // saves the next location of
            int store2 = 0;       // compares

            stackBase = initSP;
            heapBase  = codeLen;  // initialize boundaries
            cpu.hp    = heapBase; // initialize registers
            cpu.sp    = stackBase;
            cpu.gp    = stackBase;
            cpu.mp    = stackBase;
            cpu.fp    = stackBase;
            cpu.pc    = initPC;   // initialize program counter
            for (int i = heapBase; i < stackBase; i++)
            {
                mem[i] = 0;       // set entire memory to null or 0
            }
            ps = running;         // prepare to execute
            int ops = 0;

            timer.Start();
            do
            {
                ops++;
                pcNow = cpu.pc;   // retain for tracing/postmortem
                if (cpu.pc < 0 || cpu.pc >= codeLen)
                {
                    ps = badAdr;
                    break;
                }
                cpu.ir = Next();  // fetch
                if (tracing)
                {
                    Trace(results, pcNow, traceStack, traceHeap);
                }
                switch (cpu.ir)   // execute
                {
                case PVM.nop:     // no operation
                    break;

                case PVM.dsp:     // decrement stack pointer (allocate space for variables)
                    int localSpace = Next();
                    cpu.sp -= localSpace;
                    if (InBounds(cpu.sp)) // initialize all local variables to zero/null
                    {
                        for (loop = 0; loop < localSpace; loop++)
                        {
                            mem[cpu.sp + loop] = 0;
                        }
                    }
                    break;

                case PVM.ldc:     // push constant value
                    Push(Next());
                    break;

                case PVM.ldc_m1:  // push constant -1
                    Push(-1);
                    break;

                case PVM.ldc_0:   // push constant 0
                    Push(0);
                    break;

                case PVM.ldc_1:   // push constant 1
                    Push(1);
                    break;

                case PVM.ldc_2:   // push constant 2
                    Push(2);
                    break;

                case PVM.ldc_3:   // push constant 3
                    Push(3);
                    break;

                case PVM.ldc_4:   // push constant 4
                    Push(4);
                    break;

                case PVM.ldc_5:   // push constant 5
                    Push(5);
                    break;

                case PVM.lda:     // push local address
                    adr = cpu.fp - 1 - Next();
                    if (InBounds(adr))
                    {
                        Push(adr);
                    }
                    break;

                case PVM.lda_0:   // push local address 0
                    adr = cpu.fp - 1;
                    if (InBounds(adr))
                    {
                        Push(adr);
                    }
                    break;

                case PVM.lda_1:   // push local address 1
                    adr = cpu.fp - 2;
                    if (InBounds(adr))
                    {
                        Push(adr);
                    }
                    break;

                case PVM.lda_2:   // push local address 2
                    adr = cpu.fp - 3;
                    if (InBounds(adr))
                    {
                        Push(adr);
                    }
                    break;

                case PVM.lda_3:   // push local address 3
                    adr = cpu.fp - 4;
                    if (InBounds(adr))
                    {
                        Push(adr);
                    }
                    break;

                case PVM.lda_4:   // push local address 4
                    adr = cpu.fp - 5;
                    if (InBounds(adr))
                    {
                        Push(adr);
                    }
                    break;

                case PVM.lda_5:   // push local address 5
                    adr = cpu.fp - 6;
                    if (InBounds(adr))
                    {
                        Push(adr);
                    }
                    break;

                case PVM.ldga:  // push global address
                    adr = cpu.gp - 1 - Next();
                    if (InBounds(adr))
                    {
                        Push(adr);
                    }
                    break;

                case PVM.ldg_0:   // push local address 0
                    adr = cpu.gp - 1;
                    if (InBounds(adr))
                    {
                        Push(adr);
                    }
                    break;

                case PVM.ldg_1:   // push local address 1
                    adr = cpu.gp - 2;
                    if (InBounds(adr))
                    {
                        Push(adr);
                    }
                    break;

                case PVM.ldg_2:   // push local address 2
                    adr = cpu.gp - 3;
                    if (InBounds(adr))
                    {
                        Push(adr);
                    }
                    break;

                case PVM.ldg_3:   // push local address 3
                    adr = cpu.gp - 4;
                    if (InBounds(adr))
                    {
                        Push(adr);
                    }
                    break;

                case PVM.ldg_4:   // push local address 4
                    adr = cpu.gp - 5;
                    if (InBounds(adr))
                    {
                        Push(adr);
                    }
                    break;

                case PVM.ldg_5:   // push local address 5
                    adr = cpu.gp - 6;
                    if (InBounds(adr))
                    {
                        Push(adr);
                    }
                    break;

                case PVM.ldl:     // push local value
                    adr = cpu.fp - 1 - Next();
                    if (InBounds(adr))
                    {
                        Push(mem[adr]);
                    }
                    break;

                case PVM.ldl_0:   // push value of local variable 0
                    adr = cpu.fp - 1;
                    if (InBounds(adr))
                    {
                        Push(mem[adr]);
                    }
                    break;

                case PVM.ldl_1:   // push value of local variable 1
                    adr = cpu.fp - 2;
                    if (InBounds(adr))
                    {
                        Push(mem[adr]);
                    }
                    break;

                case PVM.ldl_2:   // push value of local variable 2
                    adr = cpu.fp - 3;
                    if (InBounds(adr))
                    {
                        Push(mem[adr]);
                    }
                    break;

                case PVM.ldl_3:   // push value of local variable 3
                    adr = cpu.fp - 4;
                    if (InBounds(adr))
                    {
                        Push(mem[adr]);
                    }
                    break;

                case PVM.ldl_4:   // push value of local variable 4
                    adr = cpu.fp - 5;
                    if (InBounds(adr))
                    {
                        Push(mem[adr]);
                    }
                    break;

                case PVM.ldl_5:   // push value of local variable 5
                    adr = cpu.fp - 6;
                    if (InBounds(adr))
                    {
                        Push(mem[adr]);
                    }
                    break;

                case PVM.stl:     // store local value
                    adr = cpu.fp - 1 - Next();
                    if (InBounds(adr))
                    {
                        mem[adr] = Pop();
                    }
                    break;

                case PVM.stlc:    // character checked pop to local variable
                    tos = Pop(); adr = cpu.fp - 1 - Next();
                    if (InBounds(adr))
                    {
                        if (tos >= 0 && tos <= maxChar)
                        {
                            mem[adr] = tos;
                        }
                        else
                        {
                            ps = badVal;
                        }
                    }
                    break;

                case PVM.stl_0:   // pop to local variable 0
                    adr = cpu.fp - 1;
                    if (InBounds(adr))
                    {
                        mem[adr] = Pop();
                    }
                    break;

                case PVM.stl_1:   // pop to local variable 1
                    adr = cpu.fp - 2;
                    if (InBounds(adr))
                    {
                        mem[adr] = Pop();
                    }
                    break;

                case PVM.stl_2:   // pop to local variable 2
                    adr = cpu.fp - 3;
                    if (InBounds(adr))
                    {
                        mem[adr] = Pop();
                    }
                    break;

                case PVM.stl_3:   // pop to local variable 3
                    adr = cpu.fp - 4;
                    if (InBounds(adr))
                    {
                        mem[adr] = Pop();
                    }
                    break;

                case PVM.stl_4:   // pop to local variable 4
                    adr = cpu.fp - 5;
                    if (InBounds(adr))
                    {
                        mem[adr] = Pop();
                    }
                    break;

                case PVM.stl_5:   // pop to local variable 5
                    adr = cpu.fp - 6;
                    if (InBounds(adr))
                    {
                        mem[adr] = Pop();
                    }
                    break;

                case PVM.ldv:     // dereference
                    adr = Pop();
                    if (InBounds(adr))
                    {
                        Push(mem[adr]);
                    }
                    break;

                case PVM.sto:     // store
                    tos = Pop(); adr = Pop();
                    if (InBounds(adr))
                    {
                        mem[adr] = tos;
                    }
                    break;

                case PVM.stoc:    // character checked store
                    tos = Pop(); adr = Pop();
                    if (InBounds(adr))
                    {
                        if (tos >= 0 && tos <= maxChar)
                        {
                            mem[adr] = tos;
                        }
                        else
                        {
                            ps = badVal;
                        }
                    }
                    break;

                case PVM.ldxa:    // heap array indexing
                    adr = Pop();
                    int heapPtr = Pop();
                    if (heapPtr == 0)
                    {
                        ps = nullRef;
                    }
                    else if (heapPtr < heapBase || heapPtr >= cpu.hp)
                    {
                        ps = badMem;
                    }
                    else if (adr < 0 || adr >= mem[heapPtr])
                    {
                        ps = badInd;
                    }
                    else
                    {
                        Push(heapPtr + adr + 1);
                    }
                    break;

                case PVM.inpi:    // integer input
                    adr = Pop();
                    if (InBounds(adr))
                    {
                        mem[adr] = data.ReadInt();
                        if (data.Error())
                        {
                            ps = badData;
                        }
                    }
                    break;

                case PVM.inpb:    // boolean input
                    adr = Pop();
                    if (InBounds(adr))
                    {
                        mem[adr] = data.ReadBool() ? 1 : 0;
                        if (data.Error())
                        {
                            ps = badData;
                        }
                    }
                    break;

                case PVM.inpc:    // character input
                    adr = Pop();
                    if (InBounds(adr))
                    {
                        mem[adr] = data.ReadChar();
                        if (data.Error())
                        {
                            ps = badData;
                        }
                    }
                    break;

                case PVM.inpl:    // skip to end of input line
                    data.ReadLine();
                    break;

                case PVM.i2c:     // check convert character to integer
                    if (mem[cpu.sp] < 0 || mem[cpu.sp] > maxChar)
                    {
                        ps = badVal;
                    }
                    else
                    {
                        Push((int)Pop());
                    }
                    break;

                case PVM.c2i:     // check convert integer to
                    adr = Pop();
                    if ((adr >= 65 && adr <= 90) || (adr >= 97 && adr <= 122))
                    {
                        Push((char)adr);
                    }
                    else
                    {
                        ps = badCast;
                    }
                    break;

                case PVM.prni:    // integer output
                    if (tracing)
                    {
                        results.Write(padding);
                    }
                    results.Write(Pop(), 0);
                    if (tracing)
                    {
                        results.WriteLine();
                    }
                    break;

                case PVM.prnb:    // boolean output
                    if (tracing)
                    {
                        results.Write(padding);
                    }
                    if (Pop() != 0)
                    {
                        results.Write(" true  ");
                    }
                    else
                    {
                        results.Write(" false ");
                    }
                    if (tracing)
                    {
                        results.WriteLine();
                    }
                    break;

                case PVM.prnc:    // character output
                    if (tracing)
                    {
                        results.Write(padding);
                    }
                    results.Write((char)(Math.Abs(Pop()) % (maxChar + 1)), 1);
                    if (tracing)
                    {
                        results.WriteLine();
                    }
                    break;

                case PVM.prns:    // string output
                    if (tracing)
                    {
                        results.Write(padding);
                    }
                    loop = Next();
                    while (ps == running && mem[loop] != 0)
                    {
                        results.Write((char)mem[loop]); loop--;
                        if (loop < stackBase)
                        {
                            ps = badMem;
                        }
                    }
                    if (tracing)
                    {
                        results.WriteLine();
                    }
                    break;

                case PVM.prnl:    // newline
                    results.WriteLine();
                    break;

                case PVM.neg:     // integer negation
                    Push(-Pop());
                    break;

                case PVM.add:     // integer addition
                    tos = Pop(); Push(Pop() + tos);
                    break;

                case PVM.sub:     // integer subtraction
                    tos = Pop(); Push(Pop() - tos);
                    break;

                case PVM.mul:     // integer multiplication
                    tos = Pop();
                    sos = Pop();
                    if (tos != 0 && Math.Abs(sos) > maxInt / Math.Abs(tos))
                    {
                        ps = badVal;
                    }
                    else
                    {
                        Push(sos * tos);
                    }
                    break;

                case PVM.div:     // integer division (quotient)
                    tos = Pop();
                    if (tos == 0)
                    {
                        ps = divZero;
                    }
                    else
                    {
                        Push(Pop() / tos);
                    }
                    break;

                case PVM.rem:     // integer division (remainder)
                    tos = Pop();
                    if (tos == 0)
                    {
                        ps = divZero;
                    }
                    else
                    {
                        Push(Pop() % tos);
                    }
                    break;

                case PVM.not:     // logical negation
                    Push(Pop() == 0 ? 1 : 0);
                    break;

                case PVM.and:     // logical and
                    tos = Pop(); Push(Pop() & tos);
                    break;

                case PVM.or:      // logical or
                    tos = Pop(); Push(Pop() | tos);
                    break;

                case PVM.ceq:     // logical equality
                    tos = Pop(); Push(Pop() == tos ? 1 : 0);
                    break;

                case PVM.cne:     // logical inequality
                    tos = Pop(); Push(Pop() != tos ? 1 : 0);
                    break;

                case PVM.clt:     // logical less
                    tos = Pop(); Push(Pop() < tos ? 1 : 0);
                    break;

                case PVM.cle:     // logical less or equal
                    tos = Pop(); Push(Pop() <= tos ? 1 : 0);
                    break;

                case PVM.cgt:     // logical greater
                    tos = Pop(); Push(Pop() > tos ? 1 : 0);
                    break;

                case PVM.cge:     // logical greater or equal
                    tos = Pop(); Push(Pop() >= tos ? 1 : 0);
                    break;

                case PVM.brn:     // unconditional branch
                    store  = cpu.pc + 1;
                    store2 = Next();
                    cpu.pc = store2;
                    if (cpu.pc < 0 || cpu.pc >= codeLen)
                    {
                        ps = badAdr;
                    }
                    break;

                case PVM.bze:     // pop top of stack, branch if false
                    target = Next();
                    if (Pop() == 0)
                    {
                        cpu.pc = target;
                        if (cpu.pc < 0 || cpu.pc >= codeLen)
                        {
                            ps = badAdr;
                        }
                    }
                    break;

                case PVM.pjp:       // jumps to the location of given parameter
                    if (store == store2)
                    {
                        cpu.pc++;
                    }
                    else
                    {
                        cpu.pc = store;
                    }
                    if (cpu.pc < 0 || cpu.pc >= codeLen)
                    {
                        ps = badAdr;
                    }
                    break;

                case PVM.bfalse:  // conditional short circuit "and" branch
                    target = Next();
                    if (mem[cpu.sp] == 0)
                    {
                        cpu.pc = target;
                    }
                    else
                    {
                        cpu.sp++;
                    }
                    break;

                case PVM.btrue:   // conditional short circuit "or" branch
                    target = Next();
                    if (mem[cpu.sp] == 1)
                    {
                        cpu.pc = target;
                    }
                    else
                    {
                        cpu.sp++;
                    }
                    break;

                case PVM.anew:    // heap array allocation
                    int size = Pop();
                    if (size <= 0 || size + 1 > cpu.sp - cpu.hp - 2)
                    {
                        ps = badAll;
                    }
                    else
                    {
                        mem[cpu.hp] = size; // first element stores size for bounds checking
                        Push(cpu.hp);
                        cpu.hp += size + 1; // bump heap pointer
                                            // elements are already initialized to 0 / null (why?)
                    }
                    break;

                case PVM.halt:    // halt
                    ps = finished;
                    break;

                case PVM.inc:     // integer ++
                    adr = Pop();
                    if (InBounds(adr))
                    {
                        mem[adr]++;
                    }
                    break;

                case PVM.dec:     // integer --
                    adr = Pop();
                    if (InBounds(adr))
                    {
                        mem[adr]--;
                    }
                    break;

                case PVM.incc:    // ++ characters
                    adr = Pop();
                    if (InBounds(adr))
                    {
                        if (mem[adr] < maxChar)
                        {
                            mem[adr]++;
                        }
                        else
                        {
                            ps = badVal;
                        }
                    }
                    break;

                case PVM.decc:    // -- characters
                    adr = Pop();
                    if (mem[adr] > 0)
                    {
                        mem[adr]--;
                    }
                    else
                    {
                        ps = badVal;
                    }
                    break;

                case PVM.stack:   // stack dump (debugging)
                    StackDump(results, pcNow);
                    break;

                case PVM.heap:    // heap dump (debugging)
                    HeapDump(results, pcNow);
                    break;

                case PVM.fhdr:    // allocate frame header
                    if (InBounds(cpu.sp - headerSize))
                    {
                        mem[cpu.sp - headerSize] = cpu.mp;
                        cpu.mp  = cpu.sp;
                        cpu.sp -= headerSize;
                    }
                    break;

                case PVM.call:    // call function
                    if (mem[cpu.pc] < 0)
                    {
                        ps = badAdr;
                    }
                    else
                    {
                        mem[cpu.mp - 2] = cpu.fp;
                        mem[cpu.mp - 3] = cpu.pc + 1;
                        cpu.fp          = cpu.mp;
                        cpu.pc          = mem[cpu.pc];
                    }
                    break;

                case PVM.retv:    // return from void function
                    cpu.sp = cpu.fp;
                    cpu.mp = mem[cpu.fp - 4];
                    cpu.pc = mem[cpu.fp - 3];
                    cpu.fp = mem[cpu.fp - 2];
                    break;

                case PVM.ret:     // return from non-void function
                    cpu.sp = cpu.fp - 1;
                    cpu.mp = mem[cpu.fp - 4];
                    cpu.pc = mem[cpu.fp - 3];
                    cpu.fp = mem[cpu.fp - 2];
                    break;

                case PVM.trap:    // trap falling off end of function
                    ps = badFun;
                    break;

                case PVM.low:     // toLowerCase
                    Push(Char.ToLower((char)Pop()));
                    break;

                case PVM.cap:     // toUpperCase
                    Push(Char.ToUpper((char)Pop()));
                    break;

                case PVM.islet:   // isLetter
                    tos = Pop();
                    Push(Char.IsLetter((char)tos) ? 1 : 0);
                    break;

                case PVM.pop:     // pop and discard tos
                    tos = Pop();
                    break;

                case PVM.dup:     // duplicate tos
                    tos = Pop();
                    Push(tos); Push(tos);
                    break;

                default:          // unrecognized opcode
                    ps = badOp;
                    break;
                }
            } while (ps == running);
            TimeSpan ts = timer.Elapsed;
            // Format and display the TimeSpan value.
            string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                                               ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);

            Console.WriteLine("\n\n" + ops + " operations.  Run Time " + elapsedTime + "\n\n");
            if (ps != finished)
            {
                PostMortem(results, pcNow);
            }
            timer.Reset();
            timer.Stop();
        } // PVM.Emulator