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]); } }
//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); }
// +++++++++++++++++++++ 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
} // 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
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
} // 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
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++) { } }
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); }
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); } }
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); }
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); }
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); }
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); }
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(); } }
// 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); }
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); }
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); }
/// <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); }
// 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 }); }
} // 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
/// /// <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); }
} // 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
} // 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
} // 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
} // 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
} // 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
} // 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
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); }
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
} // 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