/// <summary>
        /// Builds and prints the hard coded Reserve Table and Quad Table to run the summation algorithm.
        /// </summary>
        /// <returns>The Quad Table</returns>
        static QuadTable BuildQuadsForSummation()
        {
            ReserveTable reserveTable = new ReserveTable();

            reserveTable.PrintReserveTable();

            QuadTable quadTable = new QuadTable(reserveTable);

            quadTable.AddQuad(5, 4, 0, 0);
            quadTable.AddQuad(5, 5, 0, 1);
            quadTable.AddQuad(5, 5, 0, 2);
            quadTable.AddQuad(3, 0, 2, 6);
            quadTable.AddQuad(13, 6, 0, 8);
            quadTable.AddQuad(4, 1, 2, 1);
            quadTable.AddQuad(4, 2, 5, 2);
            quadTable.AddQuad(14, 0, 0, 3);
            quadTable.AddQuad(5, 1, 0, 3);
            quadTable.AddQuad(16, 3, 0, 0);
            quadTable.AddQuad(0, 0, 0, 0);
            quadTable.PrintQuadTable();

            return(quadTable);
        }
예제 #2
0
        /// <summary>
        /// Runs the program using the data from the given Quad Table and Symbol Table.
        /// Trace mode will print each quad code that the interpretter executes.
        /// </summary>
        /// <param name="quadTable">Quad Table containing all the necessary Quad Codes</param>
        /// <param name="symbolTable">Symbol Table containing all the necessary Symbols</param>
        /// <param name="TraceOn">Toggles Trace Mode on and off</param>
        public void InterpretQuads(QuadTable quadTable, SymbolTable symbolTable, bool TraceOn = false)
        {
            QuadTable      = quadTable;
            ProgramCounter = 0;
            while (ProgramCounter < QuadTable.NextQuad())
            {
                CurrentQuad = QuadTable.GetQuad(ProgramCounter);
                if (QuadTable.ReserveTable.isValidOpCode(CurrentQuad.OpCode))
                {
                    try
                    {
                        switch (CurrentQuad.OpCode)
                        {
                        // STOP
                        // Terminate program
                        case STOP:
                            if (TraceOn)
                            {
                                PrintTrace(CurrentQuad.OpCode);
                            }
                            ProgramCounter = QuadTable.NextQuad();
                            break;

                        // DIV
                        // Compute op1 / op2, place result into op3
                        case DIV:
                            if (TraceOn)
                            {
                                PrintTrace(CurrentQuad.OpCode, CurrentQuad.Op1, CurrentQuad.Op2, CurrentQuad.Op3);
                            }
                            symbolTable.UpdateSymbol(CurrentQuad.Op3, SymbolKind.Variable,
                                                     (symbolTable.GetSymbol(CurrentQuad.Op1).GetValue() / symbolTable.GetSymbol(CurrentQuad.Op2).GetValue()));
                            ProgramCounter++;
                            break;

                        // MUL
                        // Compute op1 * op2, place result into op3
                        case MUL:
                            if (TraceOn)
                            {
                                PrintTrace(CurrentQuad.OpCode, CurrentQuad.Op1, CurrentQuad.Op2, CurrentQuad.Op3);
                            }
                            symbolTable.UpdateSymbol(CurrentQuad.Op3, SymbolKind.Variable,
                                                     (symbolTable.GetSymbol(CurrentQuad.Op1).GetValue() * symbolTable.GetSymbol(CurrentQuad.Op2).GetValue()));
                            ProgramCounter++;
                            break;

                        // SUB
                        // Compute op1 - op2, place result into op3
                        case SUB:
                            if (TraceOn)
                            {
                                PrintTrace(CurrentQuad.OpCode, CurrentQuad.Op1, CurrentQuad.Op2, CurrentQuad.Op3);
                            }
                            symbolTable.UpdateSymbol(CurrentQuad.Op3, SymbolKind.Variable,
                                                     (symbolTable.GetSymbol(CurrentQuad.Op1).GetValue() - symbolTable.GetSymbol(CurrentQuad.Op2).GetValue()));
                            ProgramCounter++;
                            break;

                        // ADD
                        // Compute op1 + op2, place result into op3
                        case ADD:
                            if (TraceOn)
                            {
                                PrintTrace(CurrentQuad.OpCode, CurrentQuad.Op1, CurrentQuad.Op2, CurrentQuad.Op3);
                            }
                            symbolTable.UpdateSymbol(CurrentQuad.Op3, SymbolKind.Variable,
                                                     (symbolTable.GetSymbol(CurrentQuad.Op1).GetValue() + symbolTable.GetSymbol(CurrentQuad.Op2).GetValue()));
                            ProgramCounter++;
                            break;

                        // MOV
                        // Assign the value in op1 into op3 (op2 is ignored here)
                        case MOV:
                            if (TraceOn)
                            {
                                PrintTrace(CurrentQuad.OpCode, CurrentQuad.Op1, CurrentQuad.Op3);
                            }
                            symbolTable.UpdateSymbol(CurrentQuad.Op3, SymbolKind.Variable, symbolTable.GetSymbol(CurrentQuad.Op1).GetValue());
                            ProgramCounter++;
                            break;

                        // STI
                        // Store indexed - Assign the value in op1 into op2 + offset op3
                        case STI:
                            if (TraceOn)
                            {
                                PrintTrace(CurrentQuad.OpCode, CurrentQuad.Op1, CurrentQuad.Op2, CurrentQuad.Op3);
                            }
                            symbolTable.UpdateSymbol((CurrentQuad.Op2 + CurrentQuad.Op3), SymbolKind.Variable, symbolTable.GetSymbol(CurrentQuad.Op1).GetValue());
                            ProgramCounter++;
                            break;

                        // LDI
                        // Load indexed- Assign the value in op1 + offset op2, into op3
                        case LDI:
                            if (TraceOn)
                            {
                                PrintTrace(CurrentQuad.OpCode, CurrentQuad.Op1, CurrentQuad.Op2, CurrentQuad.Op3);
                            }
                            symbolTable.UpdateSymbol(CurrentQuad.Op3, SymbolKind.Variable, symbolTable.GetSymbol(CurrentQuad.Op1 + CurrentQuad.Op2).GetValue());
                            ProgramCounter++;
                            break;

                        // BNZ
                        // Branch Not Zero; if op1 value <> 0, set program counter to op3
                        case BNZ:
                            if (TraceOn)
                            {
                                PrintTrace(CurrentQuad.OpCode, CurrentQuad.Op3);
                            }
                            if (symbolTable.GetSymbol(CurrentQuad.Op1).GetValue() != 0)
                            {
                                ProgramCounter = CurrentQuad.Op3;
                            }
                            else
                            {
                                ProgramCounter++;
                            }
                            break;

                        // BNP
                        // Branch Not Positive; if op1 value <= 0, set program counter to op3
                        case BNP:
                            if (TraceOn)
                            {
                                PrintTrace(CurrentQuad.OpCode, CurrentQuad.Op3);
                            }
                            if (symbolTable.GetSymbol(CurrentQuad.Op1).GetValue() <= 0)
                            {
                                ProgramCounter = CurrentQuad.Op3;
                            }
                            else
                            {
                                ProgramCounter++;
                            }
                            break;

                        // BNN
                        // Branch Not Negative; if op1 value >= 0, set program counter to op3
                        case BNN:
                            if (TraceOn)
                            {
                                PrintTrace(CurrentQuad.OpCode, CurrentQuad.Op3);
                            }
                            if (symbolTable.GetSymbol(CurrentQuad.Op1).GetValue() >= 0)
                            {
                                ProgramCounter = CurrentQuad.Op3;
                            }
                            else
                            {
                                ProgramCounter++;
                            }
                            break;

                        // BZ
                        // Branch Zero; if op1 value = 0, set program counter to op3
                        case BZ:
                            if (TraceOn)
                            {
                                PrintTrace(CurrentQuad.OpCode, CurrentQuad.Op3);
                            }
                            if (symbolTable.GetSymbol(CurrentQuad.Op1).GetValue() == 0)
                            {
                                ProgramCounter = CurrentQuad.Op3;
                            }
                            else
                            {
                                ProgramCounter++;
                            }
                            break;

                        // BP
                        // Branch Positive; if op1 value > 0, set program counter to op3
                        case BP:
                            if (TraceOn)
                            {
                                PrintTrace(CurrentQuad.OpCode, CurrentQuad.Op3);
                            }
                            if (symbolTable.GetSymbol(CurrentQuad.Op1).GetValue() > 0)
                            {
                                ProgramCounter = CurrentQuad.Op3;
                            }
                            else
                            {
                                ProgramCounter++;
                            }
                            break;

                        // BN
                        // Branch Negative; if op1 value < 0, set program counter to op3
                        case BN:
                            if (TraceOn)
                            {
                                PrintTrace(CurrentQuad.OpCode, CurrentQuad.Op3);
                            }
                            if (symbolTable.GetSymbol(CurrentQuad.Op1).GetValue() < 0)
                            {
                                ProgramCounter = CurrentQuad.Op3;
                            }
                            else
                            {
                                ProgramCounter++;
                            }
                            break;

                        // BR
                        // Branch (unconditional); set program counter to op3
                        case BR:
                            if (TraceOn)
                            {
                                PrintTrace(CurrentQuad.OpCode, CurrentQuad.Op3);
                            }
                            ProgramCounter = CurrentQuad.Op3;
                            break;

                        // BINDR
                        // Branch (unconditional); set program counter to op3 value contents (indirect)
                        case BINDR:
                            if (TraceOn)
                            {
                                PrintTrace(CurrentQuad.OpCode, symbolTable.GetSymbol(CurrentQuad.Op3).GetValue());
                            }
                            ProgramCounter = symbolTable.GetSymbol(CurrentQuad.Op3).GetValue();
                            break;

                        // PRINT
                        // Write symbol table name and value of op 1
                        case PRINT:
                            if (TraceOn)
                            {
                                PrintTrace(CurrentQuad.OpCode, CurrentQuad.Op1);
                            }
                            Console.WriteLine($"{ symbolTable.GetSymbol(CurrentQuad.Op1).Name} = {symbolTable.GetSymbol(CurrentQuad.Op1).GetValue()}");
                            ProgramCounter++;
                            break;

                        default:
                            Console.WriteLine($"Invalid Opcode {CurrentQuad.OpCode}");
                            break;
                        }
                    }
                    // Catches any expetion, prints the appropriate error message, and stops running the current program.
                    catch (Exception e)
                    {
                        Console.WriteLine("FATAL ERROR: " + e.Message + "\n");
                        ProgramCounter = QuadTable.NextQuad();
                    }
                }
            }
        }